
【第196回】 待機中の連絡先を API で待機解除させる Marketing Cloud アプリ
以前に「REST API を使って API イベントまで待機アクティビティを試す」という記事を書きました。
Journey Builder には「API イベントまで待機」という種類の待機アクティビティがあって、このアクティビティ上で待機させている人を、REST API を使って合図を出してあげることで、その待機を解除し、次のステップに進ませることができます。
このアクティビティ上で待機可能な期間は以下の通りです。
■ 1 ~ 10 日
■ 1 ~ 10 週
■ 1 ~ 10 ヶ月
最小が 1 日間で、最大が 10 ヶ月間です。この設定された期間までに合図が出なかった場合は、イベントなしの分岐(下側の分岐)に流れていきます。

この待機アクティビティの仕組みを受けて、私が "実験的" に試してみたかったのが、連絡先キーを入力するだけで、この REST API を簡単に起動できないか?ということでした。
Marketing Cloud は、送信リストを使った大量送信・一括送信のメール配信ツールという印象ですが、担当者が連絡先キーを入力するだけで送信ができるのであれば、より個別のタイミングでメール送信が可能になります。
そんな "実験的" な Marketing Cloud アプリを作ってみましたので共有します。誰でも簡単に作れますので試してみて下さい。

今回の記事で「実験的」であることを強調しているのは、必ずしも「実用的」ではない可能性があるためです。何らかの解決策を示すものではなく、こんなこともできるかもという可能性のみを示しています。悪しからず。
それでは以下で説明してみます。
今回紹介する Markeitng Cloud アプリは Cloudpages を使って作成します。Cloudpages をパブリッシュすることで、アプリが一般公開されてしまうため、このアプリへのアクセス可能なユーザーを限定してください。
仮に Cloudpages の URL が外部に漏れても、その URL にアクセスした際に Marketing Cloud のログインページに遷移させることができます。
このユーザーを限定させる認証の仕組みに関しては、この記事では特に触れませんが、Salesforce MVP であるマテウシュ・ドンブロフスキさんが、ブログ記事や動画で丁寧に、かつ完璧な内容で説明してくれています。本当に素晴らしい内容で、私も実装時は、この仕組みを使わせて頂いています。
以下を参考にして実装してみて下さい。私の紹介しているコードに対して、多少アレンジが必要なので、コードが分かる方と一緒にお願いします。
また、今回の記事では REST API を使用します。
私の過去の記事「Marketing Cloud REST API 超入門 Part.1」で紹介した、以下の 3 つが必要になりますので、事前に用意して下さい。
① クライアント ID
② クライアントシークレット
③ 認証ベース URL
以下のスコープが API セットアップで選択されている必要があります。
■ AUTOMATION - Journeys - Read
■ CONTACTS - List and Subscribers - Read
それでは、今回はアプリの作成手順に入る前に、Email Studio でデータエクステンションを作成したり、Journey Builder で「API イベントまで待機」アクティビティを設定したりする必要があります。以下の記事を確認することでも、手順を追えるのですが、改めて記載します。
🚀 データエクステンションの作成
1. それでは、まずは REST API の受け皿になるデータエクステンションから作成しましょう。「標準」データエクステンションで作成し、名前は「WaitUntilEvent」としました。「送信可能」で設定してください。

2. 項目は「Id」という項目だけで OK です。「プライマリーキー」は設定せずに、重複を受け入れるように設定して下さい。

🚀 Journey Builder の設定
次に、Journey Builder の設定を行いましょう。
1. 細かい Journey Builder の設定は端折りますが、エントリーソースやメールアクティビティなどを配置後、「API イベントまで待機」のアクティビティを配置して、アクティビティをクリックします。

2.「新規作成」のボタンをクリックします。

3. 今回の API イベント名を分かりやすい名前で決めて、表示されている「イベント定義キー」をメモしてください。こちらは、後ほど Cloudpages を設定する際に使用します。「APIEvent-」の部分から必要です。

4. 続いて、データエクステンションの選択画面より、先ほど作成した送信可能データエクステンションを選択します。

5. データエクステンション選択後、最大待機期間を設定します。先ほども記載しましたが、この「API イベントまで待機」で待機できる最大待機期間は、次の中から選択できます。この期間までに REST API により合図が無い場合は、分岐の下のパスに進むことになるわけですね。
■ 1 ~ 10 日
■ 1 ~ 10 週
■ 1 ~ 10 ヶ月

6. 今回は、最大期間の 10 ヶ月で設定しました。つまり、10 ヶ月以内に何らかの処理を行う必要があるということになります。待機期間の設定後、このアクティビティを完了してください。

7. メールアクティビティなど、すべての設定が完了していることを確認して、ジャーニーをアクティブ化してください。

8. アクティブ化されたら、下記の通り、API イベントまで待機のアクティビティに、連絡先が流れて待機し始めたことを確認します。

9. これで、連絡先が 10 ヶ月間の待機状態になりましたので、メールの発射台に乗ったような状態になっています。
もしかすると、鋭い方は「今回作成したデータエクステンションには「Id」 しか項目がないけど、ジャーニー設定の「デフォルトのメールアドレス」はどうすればいいの?」と疑問に感じたかもしれません。しかし、今回作成したデータエクステンションは、あくまで待機解除のためのものであり、デフォルトのメールアドレスについては、エントリーソースのメールアドレスでも、すべての購読者のメールアドレスでも問題はありません。
ただし、10 ヶ月という長期間を考慮するならば、すべての購読者のメールアドレスを使う方がベターと言えるでしょう。
🚀 Cloudpages の設定
続いて、Cloudpages の設定を行います。
1. 新規で Cloudpages のランディングページを立ち上げたら、以下のコードを HTML ブロックにコピペして下さい。HTML ブロック以外のコンテンツブロックは設定不要です。
<h3>連絡先キーを入力して待機アクティビティをトリガー</h3>
%%[
SET @submittedContactKey = RequestParameter('contactKey')
IF NOT EMPTY(@submittedContactKey) THEN
SET @lookupValue = Lookup("WaitUntilEvent", "Id", "Id", @submittedContactKey) // データエクステンション名、連絡先キー項目名
IF NOT EMPTY(@lookupValue) THEN
SET @apiTriggerMessage = "既に処理済みです"
ELSE
SET @apiTriggerMessage = "処理が完了しました"
ENDIF
ELSE
SET @apiTriggerMessage = "" /* 初期状態で空に設定 */
ENDIF
]%%
<script runat="server">
Platform.Load("Core", "1");
var submittedContactKey = Variable.GetValue("@submittedContactKey");
var authPayload = {
"grant_type": "client_credentials",
"client_id": "************************", // クライアントID
"client_secret": "************************" // クライアントシークレット
};
var authUrl = "https://************************.auth.marketingcloudapis.com/v2/token"; // 認証ベース URL
var authResult = HTTP.Post(authUrl, 'application/json', Stringify(authPayload));
if (authResult.StatusCode == 200) {
var authResponse = Platform.Function.ParseJSON(authResult.Response[0]);
var accessToken = authResponse.access_token;
var restUrl = authResponse.rest_instance_url;
} else {
throw new Error("アクセストークンの取得エラーが発生しました。");
}
var apiTriggerMessage = Variable.GetValue("@apiTriggerMessage");
// ContactKeyがデータエクステンションに存在しない場合のみ、API呼び出しを実行
if (submittedContactKey && apiTriggerMessage == "処理が完了しました") {
var validateContactKeyUrl = restUrl + '/interaction/v1/events';
var validateContactKeyPayload = {
"ContactKey": submittedContactKey,
"EventDefinitionKey": "APIEvent-************************", // イベント定義キー
"Data": { "id": submittedContactKey } // 連絡先キー項目名
};
var validateContactKeyHeaders = ["Authorization"];
var validateContactKeyHeaderValues = ["Bearer " + accessToken];
var validateContactKeyResult = HTTP.Post(validateContactKeyUrl, 'application/json', Stringify(validateContactKeyPayload), validateContactKeyHeaders, validateContactKeyHeaderValues);
}
</script>
<br>
<form method="post">
<label for="contactKey">連絡先キー:</label>
<input type="text" id="contactKey" name="contactKey" value="%%=v(@submittedContactKey)=%%">
<br><br>
<input type="submit">
</form>
<br>
<p>%%=v(@apiTriggerMessage)=%%</p>
<br>
■ このコードの中で、修正の検討が必要なものは以下の 6 つです。
・用意したデータエクステンション名(名前を変えていたら)
・用意したデータエクステンション内の Id 項目名(名前を変えていたら)
・クライアントID
・クライアントシークレット
・認証ベース URL
・イベント定義キー(APIEvent-**************)
2. HTML ブロックの設定が完了したら、保存してパブリッシュして下さい。

3. パブリッシュが完了したら Cloudpages の URL をコピーしてメモしておきます。後に、インストール済みパッケージの設定で使用します。

4. Cloudpages の設定としては、以上となります。これで、既にアプリとしては動く状態ですので、Cloudpages URL をクリックしてみましょう。

5. 現在、待機している連絡先キーを入力して「送信」ボタンを押します。

6.「処理が完了しました」と入力されれば、成功です。

7. ジャーニーを確認すると、1 名の連絡先がメールアクティビティに進んでいることが確認できます。

8. データエクステンションの中身も確認しておきます。以下の通り、連絡先が 1 件格納されていることが確認できました。

9. すでに、処理済みの場合は、「既に処理済みです」と表示され、処理は重複して行われません。これは処理時に AMPscript の Lookup で同じ値が既にデータエクステンション内にいるかを確認しているためです。

🚀 インストール済みパッケージの設定
最後に、インストール済みパッケージの設定です。これを行うことで、Query Studio のように、AppExchange タブへ表示できるようになります。
1. Marketing Cloud セットアップの「インストール済みパッケージ」を選択して、「新規」のボタンをクリックします。

2. 新規パッケージの定義名を決めます。こちらは表示される名前ではありません。その後「保存」してください。

3. 「コンポーネントの追加」をクリックします。

4. コンポーネントタイプの選択画面で「Marketing Cloud App」を選択して、「次へ」をクリックします。

5. 最後に「表示名」を決定してください。そして「ログイン・エンドポイント」と「ログアウト・エンドポイント」に先ほどコピーした Cloudpages URL を入力します。どちらも同じ URL で問題ないです。その後「保存」をします。
※ 保存が完了したら、一度ログアウトして、再度ログインしてください。

6. ログイン後、AppExchange の表示を確認し、表示名をクリックします。

7 今回、私が名付けた表示名 Wait Until Event がロゴとなり、連絡先をトリガーする画面が表示されました。

これで作業は完了です。
先ほども指摘しましたが、今回作成した Cloudpages は一般公開されてしまいますので、誰でも閲覧可能な状況に置かれてしまいます。一時的にテストで作ってみる場合を除き、本番で使用する際は、特定ユーザーのみがアクセスできるように、認証の仕組みを必ず入れて下さい。
今回は以上です。