Email-to-CaseでRef IdからThread tokenに乗り換えてみた

# 背景
2021 Winter以前から利用している企業では、Email-to-Caseのやりとりを取り込むのに、ref Idを利用しています。このref Idが曲者で乱数のように見えるものが、SubjectやBodyTextに自動で挿入されます。それは一種のマーカーのように機能してIncoming emailをref Idに該当するCaseに自動で紐付けます。

このref Idはときおり他企業からメールにも出てくるので、「あ、Salesforce使っているな」と推測したことのある方も多いのではないでしょうか。

乱数のように見えますがそうではなく以下のような規則があり、その規則に沿ってOrganizationId とCaseIdを組み合わせて、どの企業のどのケースから発せられたEmailMessageなのか、Incoming emailを関連付けていたようです。

![CleanShot 2024-02-10 at 21.19.57@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15524/4c57c361-0f64-ad2a-1663-3ae370a94b59.png)

これを数式化すると、以下のような組織IdをCase Idを魔法のレシピで混ぜ合わせたなかなかカオス規則で生成されているようです。
```
"ref:_" & //
LEFT($Organization.Id,5) &// 組織番号の左5桁
SUBSTITUTE(RIGHT($Organization.Id,10), "0", "" )& //組織番号の後方10桁で0を""に置換
"._" & LEFT(Id,5) & // CaseIDの左5桁
SUBSTITUTE(Left(RIGHT(Id,10), 5), "0", "") & //CaseID後方10桁のうち左5桁で0は""に置換
RIGHT(Id,5) & ":ref" //CaseIDの後方5桁
```

さらに、直近Winter ’24で桁数が変更になったり、結合の文字列が「_」だったのが「!」に変わったり、自作していた人たち（私も含む）はなかなかな展開です。

参照
[メール-to-ケースの新しいスレッド動作によるセキュリティの強化](https://help.salesforce.com/s/articleView?id=000393881&type=1)
[The Ref ID Format for Email-to-Case is Changing](https://help.salesforce.com/s/articleView?id=release-notes.rn_service_email_refid_format.htm&release=244&type=5)
[Email-to-Case Threading
](https://help.salesforce.com/s/articleView?id=sf.support_email_to_case_threading.htm&type=5)

# Thread tokenの登場
このref idからthread tokenへの変遷は、2023/12/19に発表されたノートによると、ref Idからheader-threading、そしてlightning threadingへと紆余曲折があって移行されたようです。ユーザー間にも混乱が見受けられていました。

[Disable Ref ID and Switch to Lightning Threading
](https://help.salesforce.com/s/articleView?id=000389648&type=1)

Thread tokenにすると以下のようなthread::がEmail-to-Caseに差し込まれるようになります。設定は、Email-to-Case設定にある以下でsubjectやbodyに挿入を選びます。

![CleanShot 2024-02-10 at 21.56.19@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15524/1d278720-c520-4714-d8f3-e81553aa8286.png)

ただこのメニューはこれまた設定にある`Release Updates`で`Disable Ref ID and Tansition to New Email Threading Behaviour`を承認しなくては有効になりません。ただし、Test Runもサポートされているので、Switchしてから様子を見てまた元に戻すということの可能です。

![CleanShot 2024-02-10 at 21.58.23@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15524/d78c12ac-8e2a-6d75-f814-b9391fe623d2.png)

設定をオンにすると、Email-to-Caseで標準の返信などを利用すると以下のようなフォーマットのThread tokenが挿入されます。
```
thread::pp5XPGfmNf2hRZdRCWnrohc::　（例）
```
## 具体的な変更点
![CleanShot 2024-02-10 at 22.03.59@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15524/05c1fd3e-f3ed-775c-896a-4f9b0cadaaec.png)
新しいEmail-to-Caseのスレッディング動作では、受信メールはref Idを使用して照合されません。代わりに、メールの件名または本文にある新しいセキュアトークンを使用して照合されます。一致するものが見つからない場合、メールヘッダーに含まれるメタデータも確認します。（ということで、仮にThread tokenが表題や本文に記載がなくても、Mail headerのMetadataに含まれている情報を参照して照合するとのことです）

## 移行による改善点
![CleanShot 2024-02-10 at 22.04.23@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15524/c70e6b81-5d45-3559-f67e-a8b64e318a48.png)

Ref ID threadingに似ていますが、token-basedのthreadingでは、メールの本文または件名にフォーマットされた文字列を挿入しますが、これは現在Salesforceのセキュリティ基準を満たすように生成されます。Lightning threadingが有効になると、新しい送信メールにはRef Idが含まれなくなります。（代わりにthread:xxxxx :threadが挿入、要設定）

## 組織への影響
![CleanShot 2024-02-10 at 22.05.02@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15524/7f9d2439-e2af-2e5b-fc02-8c338d0497ec.png)

Lightning threadingを有効にするまでEmail-to-Caseは互換性があります。新機能の自動有効化がオフの場合、Ref Id設定に基づいてスレッディングトークンの設定をします。メールテンプレートのMerge FieldはCase.Thread_IdからCase.Thread_Tokenにあります。（が、Merge Fieldのみの参照です）

カスタムコードはCases.getCaseIdFromEmailThreadIdからCases.getCaseIdFromEmailHeadersやEmailMessages.getRecordIdFromEmailに置き換えます。（こちらは後述のApex内でthread token取得に利用します）

移行中ケースのメールにはRef IdとThread tokenの両方とも含まれることがあります。

# ApexによるThread tokenの取得
Flow内でのInvocable methodにしろ、Message methodを利用した送信にしろ、Email-to-Caseとして送信する場合はThread tokenを挿入しないといけないので、Apex内でThread tokenを取得します。

取得はとても簡単で、以下にCase Idを投げ込むだけです。

```
String formattedToken = EmailMessages.getFormattedThreadingToken(caseId);
```

こちらで生成されたものをSubjectやBodyに挿入するか、
[getFormattedThreadingToken(recordId)
](https://developer.salesforce.com/docs/atlas.en-us.248.0.apexref.meta/apexref/apex_System_EmailMessages_getFormattedThreadingToken.htm)

こちらで生成して、mail.setReferencesにつけて作成もできます。
[generateThreadingMessageId(caseId)
](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_classes_email_outbound_single.htm)

```
@AuraEnabled
    public static string returnTokens(String recordId){
    return EmailMessages.getFormattedThreadingToken(recordId);
}
```

## まとめ
作成してみると、Caseにつき1 Thread tokenで、これは何度取得しても、どの方法でやっても同一です。一意を保つSecure tokenという形でref Idを置き換えることができ、動作も想定通りなので今のところ問題はありません。
また、2021 Winter移行にSalesforceを導入した組織の場合はデフォルトですでにThread token形式になっているとのことで、そちらも併せてご確認ください。
遅くてもSpring '25 にはLightning threadingが強化されるのでそこら辺までにはRef Idを卒業しておく必要があります。

## 参照
こちらにFlow actionで利用するInvocable methodと通常LWCで利用するmethodを挙げておきます。

https://github.com/liuxiachanghong/threadtoken