AWSのAPI GatewayとLambdaで自前Webhook作成
AWSのAPI GatewayとLambdaを用いて自前Webhookを作成し、
Marketoから呼び出す手順の概要を共有します。
こんな感じのことができるんだ、と雰囲気だけでも共有できればと思います。
なお、作成するWebhookの仕様自体は特にMarketo特有のものはありません。
Webhookを自前で作ることにより、トリガーベースの様々な処理や
複雑なフィールドデータの加工・変換が実現できます。
またAPI GatewayとLambdaを使うことでサーバレスで安価に実現可能です。
ただし、詳細理解しないで実装するとセキュリティ面等の問題が発生する可能性があるため、
詳しいエンジニアの方に依頼することをオススメします。
#しかし、Webhookは使わない方法があるのであれば、できるだけ使わないで
もっとシンプルに実現したほうがよいことが多いと思います。
以下では例として誕生日フィールド(Date of Birth)を元に年齢フィールドに
データを格納するWebhookを実現しています。
あくまで概要ですので、詳細必要であればお声掛けください。
■Marketo側のWebhook設定
- URL: API Gatewayで作成したAPIのURLを設定
- ペイロード テンプレート: Lambdaに送るJSONを設定。ここではbirth_dateキーに誕生日フィールド(Date of Birth)の値をセットして送信。
- 応答マッピング: Lambdaから返還される値のJSONキーを「応答属性」に指定、その値を格納するフィールド(下記例ではecPointとなっているが、通常はAgeとか)を「Marketoフィールド」に設定。

■フローからWebhook呼び出し
上記のウェブフックで呼び出す。

■Amazon API Gateway
説明割愛します。
最低限、Marketoからのアクセスに絞るIP制限はかけたほうがよいかと。
Webhookのアクセス元IPアドレスはMarketoサポートに問い合わせれば教えてもらえます。
■AWS Lambdaソース(node.js)
お試しコードなので適当です。
(本番で実現する際はエラー処理やパスワード判定などをきちんと入れたほうがベターです。)
ポイントとしては以下2点。
- handlerのevent変数にペイロードテンプレートのJSON値が連想配列に変換されて格納されている
- 応答マッピングの設定に合わせたJSON値をリターンする
時刻を扱う場合、タイムゾーンの設定も忘れずにおこなってください。
index.js
function createErrorResponse(status, message){
return {
"status": status,
"message": message
};
};
//誕生日Dateオブジェクトから年齢算出
function calcAge(birthDate){ //ref.) https://goo.gl/4XqHoN
// 文字列に分解
const y2 = birthDate.getFullYear().toString().padStart(4, '0');
const m2 = (birthDate.getMonth() + 1).toString().padStart(2, '0');
const d2 = birthDate.getDate().toString().padStart(2, '0');
// 今日の日付
const today = new Date();
const y1 = today.getFullYear().toString().padStart(4, '0');
const m1 = (today.getMonth() + 1).toString().padStart(2, '0');
const d1 = today.getDate().toString().padStart(2, '0');
// 引き算
const age = Math.floor((Number(y1 + m1 + d1) - Number(y2 + m2 + d2)) / 10000);
return age;
}
//最初に呼び出されるのはここ
exports.handler = function(event, context, callback) {
//Marketo Webhook設定の「ペイロード テンプレート」で指定したJSONデータが
// event引数に連想配列で格納されています。
//[lead.Date of Birth]を取得
var strBirthDate = event['birth_date'];
console.log('#ARGMENTS');
console.log('- birth_date:' + strBirthDate);
//エラー処理(てきとう)
// ここ参照 → ref.) https://qiita.com/naoki_koreeda/items/5351f8ab803db655b0b4
if(strBirthDate === null || strBirthDate === undefined){
const response = createErrorResponse(400, 'Bad Request.');
callback(JSON.stringify(response));
return;
}
//年齢取得
var birtDate = new Date(strBirthDate);
var age = calcAge(birtDate);
//コールバックしておしまい
var res = age;
console.log('#RESULT');
console.log(res);
callback( null, {"result": res} ); //キーの"result" はMarketoのWebhook設定の「応答マッピング」で指定した応答属性
//コールバックの例はこちら参照 → https://goo.gl/2ydQnv
return;
};