ZapierでSalesforce連携するときのコツ

Zapier使ってますか？私は数年前に使っていたのですがしばらくご無沙汰でした。
今回、Herokuに置いてあるPostgreSQLとSalesforceを同期したいと思ってなにか無いかなと考えていたときに思い出したのがZapierです。
HerokuだったらHerokuConnectでいいんじゃないの？と思うかもしれませんが、今回同期したいテーブルはカラム全てが必要な訳ではないので、現状のHerokuConnectだと要件が合いません。HerokuConnectを使う場合は、Salesforce側でオブジェクトを設定→HerokuConnectを使ってマッピングするとオブジェクトの項目がPostgreSQL側に同期するという仕組みになっているので、全項目が同期されます。
全項目の同期は不要なので、同期用のスクリプトでも書くのが良いのかなとも思ったのですが、そういう時にコード書いても保守性がよくない＆車輪の再発明感が否めないのでZapierをチョイス。
注意：Salesforce及びPostgreSQLはプレミアムプラグインなので有償利用でないと使えません。

## PostgreSQL→Salesforceへの同期
最終的に実現したいフローの要件は以下の通り

- PostgreSQLで新規レコードが入った場合にSalesforceに新レコードが追加される
- PostgreSQLでレコードが更新された場合にSalesforce側のレコードが更新される

いわゆるupsertの挙動です。
よく使いますよね。

## PostgreSQLコネクタの設定
ここではつまづきませんでしたが一応書いておきます。
Trigger EventはNew or Updated Rowです。

![Cursor_と_Name_your_zap___Zapier.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22294/aaa5d0fb-3d8d-749d-a179-1a32177f268f.png)

主キーはPostgreSQLテーブルのidを使ってます。最終更新日の変更をトリガにしたいのでupdated_at(最終更新日時が入るカラム)を指定。
![Cursor_と_Name_your_zap___Zapier.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22294/22ce05fe-44c2-8a2f-8ed1-5a38d114c194.png)

テストはコケることはないと思いますが、テストを行って問題なければ、Salesforceコネクタの設定に移ります。

## Salesforceコネクタの設定
Upsertという設定はないのでどうするかというと、Findを使います。
Find Recordのオプションには、もしレコードが見つからなかった場合にレコードをつくるというオプションがあるのでそれを使うことでinsertが実現できます。

![Cursor_と_Name_your_zap___Zapier.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22294/87b9113f-3df2-7c77-bd41-80985a26ee14.png)

次にFindの設定を行います。
Salesforce側のオブジェクトを指定します。
Field to Search byはキーとなる項目を指定します。
今回は、PostgreSQL側のid項目を利用する為、article_idという項目を指定しました。
スクショの関係でチェックを入れていませんが、Create Salesforce Record if it doesn’t exist yet?のチェック欄にチェックを入れてください。これを行っておくことで、レコードIDが存在しなかった場合に新規レコードが作成されます。
Should this step be considered a "success" when nothng is found?についてはYesにしてください。後述のフィルタで設定を利用します。

![skitch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22294/3baf00fc-01f4-6836-1970-9259cc42db1c.png)


### Salesforce側のレコードをFindするためのキー指定についての注意点
Zapier側の仕様で、数値項目によるFindは出来ません。
そのため、Salesforce側のarticle_id__c はテキスト項目で設定。テキスト長は最大18文字という制限があるので18に設定しています。
外部キーとして利用するにチェックを入れて保存してあります。


ここまで行ったらContinueボタンを押して、カラムと項目のマッピングをします。

![Cursor_と_Name_your_zap___Zapier.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22294/6ffdc964-d496-bb18-fc13-7f8667277c1f.png)

ここまででテストをすると新規作成がされることが分かるでしょう。

## フィルターステップを追加する
先程Should this step be considered a "success" when nothng is found?をYesにしておいたことで、ステップ2のSalesforceのFindが終わったあとに継続してステップを追加して処理を続けられます。
実現したいのはupsert。先程insertについては設定できたので次にupdateの設定をします。
フィルタでは、レコードが存在した場合というフィルタをかけています。

![Cursor_と_Name_your_zap___Zapier.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22294/ad5aef06-dbb1-f86e-35c3-3960cb28f087.png)

## Salesforceのupdateをする

続いて、updateを設定していきます。

![Cursor_と_Name_your_zap___Zapier.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22294/2a1c6ac9-1276-a432-d9f2-9a807d7543ae.png)

Record to Update の項目には、先程のFindで取得したSalesforceのレコードIDを指定します。

![Cursor_と_Find_or_create_record_in_Salesforce_when_new_or_updated_row_in_PostgreSQL___Zapier.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22294/c0e1db84-4828-ef05-daa3-321e368a46c0.png)

あとはカラムのマッチングを設定すればOKです。

以上

## まとめ
Salesforce連携にはFind時にテキスト項目しか指定できないというトラップがありました。もしPostgreSQL側でUUIDのようなものを持っていれば、それを使えば解決なのですが、数値のid項目を使いたいという場合には注意が必要です。

Zapier便利なので、ちょっとした連携にはサクサク使って生産性をあげていきたいですね。