Heroku で Apex コールアウトとワークフローを使用する
学習の目的
この単元を完了すると、次のことができるようになります。
- Apex コールアウトとアウトバウンドメッセージを Heroku に送信する。 
 
- Apex コールアウトとアウトバウンドメッセージのユースケースを検討する。 
 
Heroku アプリケーションへのコールアウト
実行するプロセスのスケールまたは種別のために Salesforce の行動を外部システムで処理しなければならない場合があります。たとえば、今後の使用のためにサイズ変更が必要な画像を Salesforce のユーザーがアップロードします。Heroku は Salesforce から行動を受け取って、何らかのプロセスを実行し、応答することができます。また、REST API や Heroku Connect を使用してプロセスの出力を Salesforce に戻して保存することもできます。

[代替テキスト: アウトバウンドメッセージからトリガーされたか送信された Salesforce とデータイベントを含むボックスを示す図。ボックスからの矢印と Heroku でホストされるすべてのアプリケーションを含む別のボックスへの参照]
Salesforce のイベントに基づいて Heroku アプリケーションをコールする主な方法は数種類あります。Apex HTTP コールアウト、アウトバウンドメッセージ、フローの HTTP アクションを使用する方法などです。Apex HTTP コールアウトは Heroku アプリケーションへの REST コールをプログラムで実行します。アウトバウンドメッセージは、SOAP コールを宣言的に実行するアクションです。どちらの方法でも、Heroku アプリケーションは、行動の詳細のペイロードと共に要求を受け取ってアクションを実行します。
フローの HTTP アクションや外部サービスについての詳細は、「Swagger / OpenAPI + Salesforce = LIKE (Swagger / OpenAPI + Salesforce = いいね!)」や「Simplified API Integrations with External Services (外部サービスとの API インテグレーションの簡素化)」ブログ投稿を参照してください。
Apex トリガーを使用したコールアウト
Salesforce オブジェクトの Apex トリガーを定義して次のイベントを処理できます。
- 挿入 
 
- 更新 
 
- 削除 
 
- マージ 
 
- 更新/挿入 
 
- 復元 
 
トリガーは、Apex コールアウトを使用して Heroku アプリケーションのエンドポイントへの REST JSON コールを実行できます。たとえば、Heroku アプリケーションをコールする Apex トリガーを次に示します。
 trigger NewContactWebhookTrigger on Contact (after insert) {
  String url = 'https://foo.herokuapp.com/new_contact';
  String content = Webhook.jsonContent(Trigger.new, Trigger.old);
  Webhook.callout(url, content);
}参照される Webhook Apex クラスは次のとおりです。
 public class Webhook {
  public static String jsonContent(List<Object> triggerNew, List<Object> triggerOld) {
    String newObjects = '[]';
    if (triggerNew != null) {
      newObjects = JSON.serialize(triggerNew);
    }
    String oldObjects = '[]';
    if (triggerOld != null) {
      oldObjects = JSON.serialize(triggerOld);
    }
    String userId = JSON.serialize(UserInfo.getUserId());
    String content = '{"new": ' + newObjects + ', "old": ' + oldObjects + ', "userId": ' + userId + '}';
    return content;
  }
  @future(callout=true) public static void callout(String url, String content) {
    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint(url);
    req.setMethod('POST');
    req.setHeader('Content-Type', 'application/json');
    req.setBody(content);
    h.send(req);
  }
}jsonContent メソッドはトリガーデータを取得して JSON に逐次化します。コールアウトメソッドは JSON ペイロードを使用して Heroku への HTTP ポストを実行します。
アウトバウンドメッセージの場合と同様に、オープンソースの Web または REST 技術を使用して Heroku アプリケーションを構築できます。JavaScript、Node.js、および Express では、エンドポイントを次のように定義できます。
 app.post("/new_contact", function(req, res) {
  // do something with req.body
  res.status(201).end();
});要求ハンドラー内の req.body は、Apex トリガーから送信された、並列化された JSON データです。
Apex トリガーを使用する場合、何らかの形式の事前共有キーを使用して要求を認証できるため、悪意のある可能性がある要求を回避できます。また、ペイロードにセッション ID を含めて、Heroku アプリケーションで Salesforce への REST API 要求を実行し、データを取得または更新することもできます。
アウトバウンドメッセージを使用したコールアウト
アウトバウンドメッセージアクションを使用する場合は、外部システムへのコールアウトと、コールアウトを送信するレコードトリガーフローを宣言的に定義します。
フローの実行時に Heroku アプリケーションをコールするには、まずアウトバウンドメッセージアクションを作成します。Heroku アプリケーションエンドポイントをエンドポイント URL に指定します。

[代替テキスト: アウトバウンドメッセージの設定] ダイアログのスクリーンショット。「Heroku への新規取引先責任者」という名前のメッセージが表示されています。]
Send Session ID を選択した場合、Heroku アプリケーションはそのトークンを使用して REST API コールをユーザーに代わって実行できます。セッション ID を送信しない場合、要求が有効であることを確認できません。また、Heroku アプリケーションの API エンドポイントへの悪意のあるコールから保護できません。
Heroku 側では、オープンソースの Web または REST 技術を使用してイベントハンドラーを実装できます。ただし、メッセージは SOAP 形式のため、XML を解析できる必要があります。たとえば、JavaScript、Node.js、Express、および express-xml-bodyparser ライブラリを使用する場合、アウトバウンドメッセージを処理し、SOAP メッセージを解析するエンドポイントは次のようになります。
app.post("/new_contact", function(req, res) { var notification = req.body["soapenv:envelope"]["soapenv:body"][0]["notifications"][0]; var sessionId = notification["sessionid"][0]; var data = {}; if (notification["notification"] !== undefined) { var sobject = notification["notification"][0]["sobject"][0]; Object.keys(sobject).forEach(function(key) { if (key.indexOf("sf:") == 0) { var newKey = key.substr(3); data[newKey] = sobject[key][0]; } }); // do something #awesome with the data and sessionId } res.status(201).end(); });この例では、取引先責任者を作成するたびに Heroku アプリケーションは取引先責任者の詳細を受け取るため、そのデータを使用して必要な処理を実行できます。
アウトバウンドメッセージアクションを作成したら、コールするフローを作成します。このフローは、次のいずれかが発生したときに任意の Salesforce オブジェクト (取引先責任者、取引先など) によってトリガーされます。
- レコードが作成されたとき 
 
- レコードが更新されたとき 
 
- レコードが作成または更新されたとき 
 
- レコードが削除されたとき 
 
レコードが更新されたときにフローをトリガーする場合は、レコードが更新され、かつ条件の要件を満たしている場合は必ずフローをトリガーするか、レコードが更新されて条件の要件を満たしたときにのみトリガーするかを指定できます。
フローの開始要素を設定した後に、アクション要素を作成します。[アクション] 項目に、作成したアウトバウンドメッセージアクションを入力します。次に、要素に表示ラベルを付け、[完了] をクリックしてフローを保存します。フローでこの要素が実行されると、アウトバウンドメッセージアクションで定義されたコールアウトが送信されます。

リソース
- SOAP API 開発ガイド: アウトバウンドメッセージの設定
- Salesforce ヘルプ: アウトバウンドメッセージアクション
- Salesforce ヘルプ: フロー要素: 待機
- Apex 開発者ガイド: HTTP コールアウトの呼び出し
- Trailhead: Heroku の Node.js の概要
- JAMES WARD: Heroku での Node.js のクイックスタート
