Salesforceで項目履歴をDIYする!
今年も技術系アドベントカレンダーの季節がやってまいりました。皆さま元気にお過ごしでしょうか?
今年はコロナ禍のため Dreamforce もリアルイベントではなく、バーチャル開催となりました。バーチャル開催となることでこれまで参加できなかった人も参加できるようになりました。どんなイベントになるか楽しみです。
さて、今年も技術系アドベントカレンダーがクリスマスまで25日間続きます。今日から毎日投稿されるアドベントカレンダーの記事を読んで楽しみましょう!
はじめに
エンタープライズでは項目の監査履歴を求められることがあります。Salesforce Shieldで提供される項目監査履歴を利用するのが定跡ですが、有償機能にしないと制限があり、かつ有償機能を利用しても60項目までしか履歴を追跡できません。
そこで、今回は項目履歴をDIYしてみましょう。
項目監査履歴
まず、標準的に利用できる項目監査履歴についてです。
Salesforce Shield で提供される機能となり、設定した項目監査履歴保持ポリシーにしたがって項目履歴をアーカイブしていきます。Salesforce Shield は有償機能ですが、無償でも一部の機能を利用できます。
有償の場合
・1 オブジェクトにつき60個までの項目追跡
・アーカイブされた時点から最長 10 年保持
無償の場合
・1 オブジェクトにつき20個までの項目追跡
・アーカイブされた時間から 18 ヶ月
より詳細はSalesforceセキュリティガイドなどを参考にしてください。
項目履歴をDIYする
さて、ここからは項目監査履歴を利用してもいろいろと制約があるため、せっかくなのでDIYしていきます。
今回利用する機能は、変更データキャプチャとBig Objectになります。普段聞き慣れない機能なので、簡単に紹介していきます。
変更データキャプチャ
変更データキャプチャはSalesforce データを外部データと効率よく統合できるようにするための機能です。詳しくはTrailheadのモジュールを学習してもらうと理解できると思います。
今回は、例外的な使い方になりそうですが、カスタムオブジェクトの作成・更新・削除・復元のイベントでログを記録するために利用します。通常のApexトリガーでもよいのですが、変更された項目が取得しやすいので使ってみました。
Big Object
Big ObjectはSalesforce Platform 上で大量のデータを保存して管理するための機能です。用途としては、顧客の360度ビュー、監査と追跡、履歴アーカイブなど、まさに今回の用途に利用することが想定されています。
設計
設計としては下図のようになります。
項目履歴を記録した対象のカスタムオブジェクトに変更データキャプチャの設定、およびChangeEventに対するApexトリガーを設定します。このApexトリガー内で履歴データを作成し、BigObjectに書き込みます。
変更データキャプチャを利用すると強制的に非同期実行となるため、同期処理に負担をかけず処理できるところがよいところです。今回のケースでは、Big Objectへの書き込みも非同期処理となってしまい、やりすぎな感じがします。
実装
続いて、実装になります。ChangeEventHeaderに更新操作で変更された項目のリストであるchangedfieldsがあり、変更点のログの組み立てが簡単にできるようになっています。
trigger ChangeCustomObjectChangeTrigger on ChangeCustomObject__ChangeEvent (after insert) {
List<FieldHistory__b> historyList = new List<FieldHistory__b>();
for (ChangeCustomObject__ChangeEvent event : Trigger.New) {
EventBus.ChangeEventHeader header = event.ChangeEventHeader;
FieldHistory__b history = new FieldHistory__b();
switch on header.changetype {
when 'INSERT' {
// 追加時に記録するログを組み立てる
}
when 'UPDATE' {
// 更新時に記録するログを組み立てる
}
when 'DELETE' {
// 削除時に記録するログを組み立てる
}
WHEN 'UNDELETE' {
// 復元時に記録するログを組み立てる
}
}
historyList.add(history);
}
if(historyList.size() > 0) {
Database.insertImmediate(historyList);
}
}
カスタムオブジェクトの項目値の変更をJSON形式に変換して履歴として保存しておくことで項目履歴が記録できるようになります。時間の関係でJSON形式の文字列を組み立てるコードは割愛させてもらっています(作業時間が取れれば追記します)。
おわりに
変更データキャプチャとBigObjectを利用した項目履歴のDIYについてご紹介しました。
正直なところ、変更データキャプチャはオーバーエンジニアリング気味です。本来、変更データキャプチャはサービス間のイベントをストリーミングでやりとりします。SalesforceではこれをApexトリガーで扱え、複雑な実装なしで利用できる点は非常に優れていると感じました。
プラットフォームイベントと合わせて、難易度の高かったサービス間連携が比較的簡単に実装できそうです。今回は技術に触ってみるといったところまででしたが、利用方法を研究していきたいと思います。
関連リンク
この記事は Salesforce Platform Advent Calendar 2020 - Qiita 第1日目の投稿です。
この記事はSalesforce 開発者向けブログ投稿キャンペーンへのエントリー記事です。
Enjoy Advent Calendar!