Amazon AppFlow を使って二つのSalesforce組織を同期できるか試してみた

2021.11.05

Upsertするための準備

AppFlowを使って同期処理を行うにあたって、新規登録/更新/削除に対応するためにUpsertが可能である必要があります。 そのため、同期対象の各オブジェクトに外部IDとして利用可能なユニークキーを作成します。

取引先

取引先では、取引先名(Name)とWebサイト(Website)を文字列結合した値を保持させる項目をユニークキーとして用意してみました。 数式は外部IDにできないので、項目(SyncKey__c)を作って、そこにApexを使って値をセットします。

ApexコードはBatchで実装します。

global class BatchSetAccountKey implements Database.Batchable<sObject> {

    global Database.QueryLocator start(Database.BatchableContext BC) {
        String query = 'SELECT Id, Name, Website FROM Account';
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<Account> scope) {
         for(Account acc : scope) {
             if (String.isEmpty(acc.Website)) {
                 acc.SyncKey__c = acc.Name + '';
             } else {
                 acc.SyncKey__c = acc.Name + acc.Website;                 
             }
         }
         update scope;
    }

    global void finish(Database.BatchableContext BC) {
    }
}

このApexを作成したら、開発者コンソールの Open Execute Anonymous Window を開き、次のコードを記述して実行します。

Id batchJobId = Database.executeBatch(new BatchSetAccountKey(), 200);

同期する二つのSalesforce組織のそれぞれで実行します。

取引先責任者

取引先責任者は「メール(Email)」をキーとして使えるのでキーの追加は行いませんでした。

単一オブジェクトの確認

取引先を使って検証します。 フローは次のように定義しました。

フローを設定

データフィールドをマッピング

フロー: SyncSingleObj

新規登録の確認

同期元の組織で新規取引先を作成します。

新規登録取引先(同期元)

取引先を作成したら、フローを実行します。

同期先の組織で新規取引先が作成されていることを確認できました。

新規登録取引先(同期先)

更新の確認

同期元の組織で作成した取引先を更新します。 ここでは、電話番号を変更しました。

更新取引先(同期元)

フローを再度実行します。

更新取引先(同期先)

電話番号が同期により変更されました。

削除の確認

同期元の組織で作成した取引先を削除し、フローを再度実行します。
しかし、同期先の取引先は削除されずに残っていました。

削除取引先(同期先)

フローの設定を変更して、「オンデマンドで実行」を「スケジュール通りにフローを実行」に変更し、また「削除されたレコードのインポート」にチェックを入れて試してみるも、削除したレコードの情報を同期先に送ることはできるものの、それをトリガーに削除することはしないようでした。

削除の同期に対応するには、AppFlowにて Salesforceイベント をキャッチし、Amazon EventBridgeに繋いでLambdaで処理するといったことが必要なようです。こちらは後日また改めて検証してみようと思います。

リレーションを持つ複数オブジェクトの確認

リレーション関係にある複数オブジェクトの新規作成と更新に関して確認します。
取引先と取引先責任者を使って検証します。
フローは一つにつき一つのオブジェクトに対してしか定義できないので、次のように取引先責任者用に追加定義しました。

フローを設定(取引先責任者)

データフィールドをマッピング(取引先責任者)

フロー: SyncContact

取引先の参照に関しては

リレーションの設定

のように AccountId => AccountId.SyncKey__c と設定しています。

しかし、これは同期元レコードIdを同期先のSyncKey__cに入れようとしているので参照関係が正しくセットされません。
現状、AppFlowのUIでは外部キーを利用した AccountId.SyncKey__c => AccountId.SyncKey__c のような設定ができないようで、実際にこのフローを実行するとエラーになりました。

AccountId => AccountId という紐付けにした場合、組織が異なると(人間の目には)同じレコードでもレコードIdが異なりますので、これもフローはエラーになりました。

どうやら削除の場合と同じく、リレーションを持つ複数オブジェクトを同期するには、AppFlowにて Salesforceイベント をキャッチし、Amazon EventBridgeに繋いでLambdaで処理するといったことをする必要があるようです。