winter'22で追加されたレコードトリガーフローの機能を使って項目変更履歴を実装してみた

Salesforce Advent Calendar 2021の16日目の記事です。
Salesforceは毎年機能のアップデートが早くてキャッチアップが大変ですね。
リリースノートには目を通しているものの、都度、実際に動作確認までしている人は多くないのではないでしょうか。

特にフローの機能追加スピードは凄まじく、ほとんどApexなどでコードを書かなくてもほとんどの機能を実装することができるようになってきました。

本記事ではwinter'22で追加されたフローの簡単な機能紹介とそれをつかった実装を記載しています。
まだフローを触ったことがないけどそろそろ触ってみようと考えている、という人向けにフローを作るときのベストプラクティスがまとまった記事を載せておきます。
[10 Salesforce Flow Best Practices](https://www.salesforceben.com/salesforce-flow-best-practices/)

# winter'22で追加されたフローの機能
詳細は[リリースノート](https://help.salesforce.com/s/articleView?id=release-notes.rn_automate_flow.htm&type=5&release=234)を確認いただければと思いますが、個人的に私がいいなと思った部分を列挙します。

- レコードトリガフローで、サブフローが使えるようになった
- レコードトリガーフローで非同期パスが使えるようになった
- スケジュール済みパスおよび非同期で実行されるパスをデバッグできるようになった。
- レコードトリガーフローで送信メッセージを送信できるようになった
- フローが失敗した際にレコード変更をロールバックできるようになった

ローコードとはいえ、もうほとんどフローでできないことがなくなってきています。
複雑な処理を作り込まないと行けない場合はApexを使ったほうがいいと思いますが、部分的に処理をApexで記載し、フローから参照する、という方法も検討しておく必要があると思います。

# 非同期実行とサブフローで項目変更履歴機能を作ってみる

ようやく本題に入ります。本記事では、レコードトリガーフローのサブフローを非同期パスを利用して、項目変更履歴をコーディングなしで作っていきます。
項目変更履歴とはいつだれがどの項目を更新したかを記録する監査的な役割の機能になります。標準やアドオンライセンスでもこちらの機能はありますが、要件によっては標準だと機能が足りなかったり、アドオンライセンスの予算がなく、渋々カスタマイズで対応することもあると思います。

いままではカスタマイズ対応する場合、データ量などを考慮してBigObjectに項目変更履歴のレコードを保存しようとすると非同期処理で実装する必要があったので、必然的にApexで処理を実装する必要がありました。

しかし、今回のアップデートでレコードトリガーフローで非同期処理を実装することができるようになったのでレコードトリガーフローからBigObjectにもレコードを保存する処理を作成できるようになりました。

これでレコード量、保存期間、追跡可能項目数を気にすることなく項目変更履歴の機能をフローで実装することができます。

## 処理概要
今回作成する処理の概要をまとめると以下の図になります。今回は取引先に処理を実装し、検証を行います。
取引先の変更情報から直接BigObjectにレコードを作成せず、一度カスタムオブジェクトにレコードを作成してから転送しているのは、すべてを非同期処理にすると変更前の項目値を取得できず、すべてを同期処理にするとBigObjectにレコードを登録できなくなるので、非同期処理と動機処理でトリガーフローを分ける必要があったからになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/66e43625-7df9-ec80-6736-336d586908db.png)

この構成は項目変更履歴の実装に限らず、変更前のレコード値の処理と外部サービスとの連携が必要な機能の場合には利用できる構成になります。

具体的な処理内容を解説していきます。

### 項目変更履歴を一時保存するカスタムオブジェクトを作成
以下のようにカスタムオブジェクトを作成します。Name項目をRecordIdという設定で作成しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/7a732e88-ed57-ece1-b4d5-e735963bdecf.png)


### 項目変更履歴を保存するBigObjectを作成
以下のようにBigObjectを作成します。
ポイントとしては関連リストとして表示するためにレコードを紐付けるための「RecordId」と、「更新日時」、「項目名」の3項目でペアとなるIndexを作成することです。
また、Indexの合計文字数は100文字ということを考慮して、「項目名」は60文字を最大文字数として設定しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/5c0af675-7ae5-652c-8497-203f6935c31a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/fb20623a-e562-6b8e-357e-fbd16c9ce9f1.png)
※BigObjectは一度作成すると定義を変更できないので、どうしても定義を修正する必要がある場合は一度削除してから再作成する必要があります。

### 項目変更履歴を一時保存するサブフロー作成
以下のように自動起動フローでサブフローを作成します。
以下の図では取引先の取引先名が変更された場合に項目変更履歴を作成するように処理を記載していますが、
「取引先名の変更有無」、「変更履歴作成_取引先」、「変更履歴追加_取引先」を各項目分用意すれば複数の項目で準備することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/8e522d32-b7da-6ec5-b1ae-1835438d59d0.png)

サブフローとして呼び出される際の入力値としてoldAccountとnewAccountを用意します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/7bff27d7-2e4f-7171-7078-0f8d50b74ffb.png)

入力値のoldAccountとnewAccountの取引先名を比較して一致するかどうかを判定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/0c93b4e8-128b-ed57-c3d1-e747e12b6c07.png)

一致しなかった場合は用意した「項目変更履歴を一時保存するカスタムオブジェクト」のレコード変数に各種値をセットする処理を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/5332d268-31b6-756a-c9b8-c6226006c4d5.png)

その後、複数の項目値変更が発生していても一括で変更履歴を作成するために、「項目変更履歴を一時保存するカスタムオブジェクト」のリストに先程のレコード変数を追加する処理を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/f7a4b93a-833a-0bf3-91c0-2c3b1ebb826d.png)

追跡項目が変更されていない場合はフローが終了できるように決定要素を作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/8c50369c-3f5f-dea9-adc7-29083ce41491.png)

「項目変更履歴を一時保存するカスタムオブジェクト」に項目変更履歴内容を作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/07b5ec05-cd32-481c-2c31-49763b33a777.png)


### 項目変更履歴をBigObjectに保存するサブフロー作成
以下のように自動起動フローでサブフローを作成します。全体の流れとしては、まず「項目変更履歴を一時保存しているカスタムオブジェクト」からレコードを取得し、レコードが存在していればBigObject用のレコード変数に変換して登録を行います。
そしてその後、「項目変更履歴を一時保存しているカスタムオブジェクト」上のレコードは不要になるので削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/5a6c569f-f7ab-e843-15fd-6ff32a05ae9c.png)


### レコードトリガーフローでサブフローと非同期パスの設定
上記で作成したサブフローを呼び出すレコードトリガーフローを作成します。
次のように即時実行で「項目変更履歴を一時保存するサブフロー」を呼び出し、非同期に実行で「項目変更履歴をBigObjectに保存するサブフロー」を呼び出すように設定します。このようにそれぞれサブフローで処理を整理しておくことでメンテナンス性が高くなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/80a02a03-60ed-14dc-3dfa-b352a006ca10.png)

こちらのフローの開始条件設定は以下のようになります。
「トリガレコードの元のトランザクションが正常にコミットされた後に外部システムにアクセスするには、非同期に実行パスを含めます。」にチェックを入れることで非同期実行が可能になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/e3bc4ff4-54a5-c44f-bad3-82f21478a1e7.png)

即時実行で設定する「項目変更履歴を一時保存するサブフロー」では入力値に以下のように設定し、変更前のレコード情報と変更後のレコード情報をサブフローに渡すようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/19b2269f-1159-69d7-9b24-c82baa81e8c9.png)


### BigObjectを関連リストで表示するパッケージをAppExchangeからインストール
[こちら](https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3u00000OMz1jEAD)からインストールすることができます。

### BigObjectを関連リストで表示するパッケージをページレイアウトに追加
レコード詳細ページのレイアウトにタブを追加し、そこにカスタムコンポーネント「Big Object Related List」を選択してドラッグアンドドロップで配置します。
各パラメータの設定は以下の通りです。

| パラメータ | 値 |
|:-----------|:------------:|
| Big Object API Name | ColumnsChangeHistory__b |
| Lookup field API Name | RecordId__c |
| Fields to display for each record | ColumnName__c,OldValue__c,NewValue__c, UpdatedDateTime__c, User__c |
| Number of records options | 100,200,300,400,500 |
| Display mode(large screens) | Table |
| Display mode(medium screens) | Table |
| Display mode(small screens) | Tiles |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/89054f50-ce10-50ff-ee63-d37d8bec5081.png)


## 動作確認
それでは実際に動作するか確認してみます。
ちょうど「株式会社セールスフォース・ドットコム」社が「株式会社セールスフォース・ジャパン」に社名変更するとのことなので、変更してみます。編集画面で普通に編集します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/ce04926d-3cc0-c927-357f-87b1912d5338.png)
その後、項目変更履歴のタブで確認するとBigObjectのレコードとして項目変更履歴が作成されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503339/d661434b-6f7a-1d1d-02b1-d387e956e27e.png)


# まとめ
Apexも書ける人であれば、わざわざフローで実装、とはなかなかならないかもしれませんが、エンジニアでない人でもあらゆる処理の実装が可能なのでフローの需要は高いんじゃないでしょうか。機能もどんどん拡張されていくので、今後はApexよりフローを優先して設計を行っていったほうがいいのかもしれないと考えています。

現状ではSalesforceベンダーに開発を依頼しているユーザ企業も多いと思いますが、フローでSalesforce開発が内製化できる企業が増えていくといいなと考えてます。