メインコンテンツへスキップ
見出し画像
Photo byakisuke0925

【第447回】 Marketing Cloud Next : オンデマンドフロー x Apex パーソナライズ

    Nobuyuki Watanabe

    Marketing Cloud Next Growth & Advanced Edition の Winter ’26 新機能リリースでは、新たに 「オンデマンドフロー」 というフロータイプが追加されました。これにより、REST API 経由で連絡先を即時にトリガーし、プロモーション/トランザクションメッセージを配信できる ようになったことを、以前の記事でご紹介しました。

    Winter ’26 時点でも データグラフを活用したパーソナライゼーション は可能でしたが、API から任意の追加情報を直接渡すことはできない という制約がありました。

    しかし、Spring ’26 新機能リリース ではこの制約が解消され、REST API から追加のデータを渡し、動的にパーソナライズされたメッセージを生成することが可能 になりました。

    今回の記事では、「オンデマンドフロー」にパーソナライズされた値を渡してみたいと思います。

    例えば、以下のような注文完了メールがあったとします。

    {{LastName}} {{FirstName}} 様
    このたびはご注文いただき、誠にありがとうございます。
    以下の内容でご注文を承りました。
    ----------------------------------
    ■ ご注文番号
    {{OrderNumber}}
    ■ ご注文日時
    {{OrderDate}}
    ■ ご注文商品
    商品名:{{ItemName}}
    数量 :{{ItemQuantity}}
    価格 :{{ItemPrice}} 円
    ■ お支払い方法
    {{PaymentMethod}}
    ■ 合計金額
    {{TotalAmount}} 円
    ----------------------------------
    商品は発送準備が整い次第、改めてご連絡いたします。
    ご不明な点がございましたら、
    本メールへの返信、またはサポート窓口までお問い合わせください。
    今後ともどうぞよろしくお願いいたします。

    そして、この実装には Apex の技術を活用 しますので、以下のような Apex クラスを利用します。

    • Apex クラス例:OrderConfirmationContactService

    public without sharing class OrderConfirmationContactService {
    
        @AuraEnabled public String LastName { get; set; }
        @AuraEnabled public String FirstName { get; set; }
        @AuraEnabled public String OrderNumber { get; set; }
    
        @AuraEnabled public String ItemName { get; set; }
        @AuraEnabled public String ItemQuantity { get; set; }
        @AuraEnabled public String PaymentMethod { get; set; }
    
        @AuraEnabled public String OrderDateYmdJp { get; set; }
        @AuraEnabled public String OrderDateYmdSlash { get; set; }
        @AuraEnabled public String ItemPriceFormatted { get; set; }
        @AuraEnabled public String TotalAmountFormatted { get; set; }
    
        private String orderDateRaw;
        private String itemPriceRaw;
        private String totalAmountRaw;
    
        @AuraEnabled
        public String OrderDate {
            get { return orderDateRaw; }
            set {
                orderDateRaw = value;
    
                OrderDateYmdJp = null;
                OrderDateYmdSlash = null;
    
                if (String.isBlank(orderDateRaw)) return;
    
                Date d = Date.valueOf(orderDateRaw.substring(0,10));
                DateTime dt = DateTime.newInstance(d, Time.newInstance(0,0,0,0));
                OrderDateYmdJp = dt.format('yyyy年MM月dd日');
                OrderDateYmdSlash = dt.format('yyyy/MM/dd');
            }
        }
    
        @AuraEnabled
        public String ItemPrice {
            get { return itemPriceRaw; }
            set {
                itemPriceRaw = value;
    
                ItemPriceFormatted = null;
    
                if (String.isBlank(itemPriceRaw)) return;
    
                ItemPriceFormatted = Decimal.valueOf(itemPriceRaw.replace(',', '')).format();
            }
        }
    
        @AuraEnabled
        public String TotalAmount {
            get { return totalAmountRaw; }
            set {
                totalAmountRaw = value;
    
                TotalAmountFormatted = null;
    
                if (String.isBlank(totalAmountRaw)) return;
    
                TotalAmountFormatted = Decimal.valueOf(totalAmountRaw.replace(',', '')).format();
            }
        }
    }

    Tips:日付や数字は、メール上で加工するのではなく、事前に Apex 内で加工する必要があります。

    • Apex テストクラス例:OrderConfirmationContactServiceTest

    @IsTest
    private class OrderConfirmationContactServiceTest {
    
        @IsTest
        static void testFormatting() {
            OrderConfirmationContactService s = new OrderConfirmationContactService();
    
            s.OrderDate = '2026-02-05';
            s.ItemPrice = '2000';
            s.TotalAmount = '22000';
    
            System.assertEquals('2026年02月05日', s.OrderDateYmdJp);
            System.assertEquals('2026/02/05', s.OrderDateYmdSlash);
            System.assertEquals('2,000', s.ItemPriceFormatted);
            System.assertEquals('22,000', s.TotalAmountFormatted);
        }
    }

    この記事は Marketing Cloud Engagement ユーザーの方も数多く見ていると思いますので、Apex クラスの設定についても説明しておきます。

    Apex クラスを本番へデプロイするには、以下の手順が必要です。

    ✅ Sandbox で作成、エラーが出ないかの手動テスト
    ✅ Apex クラス と テストクラス を一緒に変更セットへ
    ✅ 本番で Validate → Deploy

    Sandbox
    ↓
    変更セット作成(Apex + Test)
    ↓
    Production Validate
    ↓
    Deploy

    Marketing Cloud Next の Sandbox の作成と、変更セットの送信については以下の記事で取り上げていますので必要に応じて確認してください。

    以下に詳細な手順を記載しておきます。


    Apex クラスの設定手順

    STEP 1:Sandbox(開発・下準備)

    それではまず、Sandbox を開き、設定から「Apex クラス」を選択し、新規をクリックします。

    画像

    ここでは、必ず本番の Apex クラスから登録してください。

    画像

    ※ テストを先に登録しようとすると、本番用の Apex クラスがありませんとエラーが出ます。

    続いて、テストも登録します。

    画像

    STEP 2:Sandbox → 本番へ送信

    続いて、設定>「アウトバウンド変更セット」で「新規」の変更セットを作成したら、作成した Apex クラス + テスト Apex クラスを追加します。

    画像

    これを本番組織へ アップロードします。

    画像

    STEP 3:本番で「検証(Validate)」

    続いて、本番環境にログインを行い、設定 > インバウンド変更セットに移動し、対象の変更セットを開き、検証(Validate) をクリックします。

    画像

    ローカルテストを実行します。

    画像

    STEP 4:本番でデプロイ(Deploy)

    Validate が 成功したらデプロイをクリックします。

    画像

    再度ローカルテストを実行します。

    画像

    デプロイが完了しました。

    画像

    少々長い説明になりましたが、これでまず本番環境に Apex クラスが登録できました。

    画像

    メールコンテンツの作成

    上に記載済みのメールのテンプレートを「パラグラフ」に貼り付けます。

    画像

    今回、差し込み項目のデータソースとして、Spring '26 以降新しく登場した「Apex クラスデータプロバイダー」を利用しますので、データソースの追加を行います。

    画像
    画像

    先ほど作成した Apex クラスを選択します。

    画像

    続いて、メール内のプレースホルダーの箇所を「Apex クラスデータプロバイダー」の項目に差し替えていきます。

    画像

    Apex クラスにて設定した項目が表示されます。

    画像

    すべての差し込み項目を設定できたら、メールを保存して、公開します。

    ※ 公開の前に「トランザクションメール」に変更してください。

    画像

    オンデマンドフローの作成

    新規のフローからオンデマンドフローを作成します。

    画像

    フローが開いたら、まずは「変数」のリソースを追加します。追加したものはそのままにしておいて問題ないです。

    • 設定した API 名は、後に REST API のボディ内で使用します

    • データ種別は「Apex-Defined」を選択します

    • Apex クラスは上で作成したものを選択します

    • 「入力で利用可能」にチェックを入れます

    画像

    次に、メールを設定したら、保存してフローを有効化します。

    画像

    ※ フローの API 名は、REST API のエンドポイントで使用します。

    フローを設定したら、プロパティを開き、アクションボタンから「アクセス編集」を選択します。

    画像

    今回の REST API の実行ユーザーとなっているプロファイルに対して、フローへのアクセス権を付与してください。

    画像

    REST API の実行

    それでは、最後に REST API を実行します。
    この方法については、以下の記事を参考にしてください。

    ① アクセストークンを取得したら、
    ② 以下の REST API を実行します。

    ※ OrderInfo の部分が、フローで作成した「変数の API 名」になります。

    --- メソッド 
    POST 
    
    --- エンドポイント
    https://[私のドメイン名].my.salesforce.com/services/data/v65.0/actions/custom/flow/[Flow API 名]
    
    --- ヘッダー 
    Content-Type:application/json 
    Authorization:Bearer [アクセストークン] 
    
    --- ボディ
    {
      "inputs": [
        {
          "EmailAddress": "xxxxxxxxxxxxxxxxxxx@gmail.com",
          "IndividualId": "003A800000ODmp1IAD",
          "OrderInfo": {
            "LastName": "Takahashi",
            "FirstName": "Miyu",
            "OrderNumber": "ORD-0001",
            "OrderDate": "2026-02-05",
            "ItemName": "Sample Item",
            "ItemQuantity": "1",
            "ItemPrice": "2000",
            "PaymentMethod": "Credit Card",
            "TotalAmount": "2200"
          }
        }
      ]
    }

    これでフローが起動されます。

    画像

    送信されたメールを確認すると、無事、パーソナライズされていました。成功です。

    画像

    いかがでしたでしょうか。

    これまでもデータグラフを利用したパーソナライズは可能でしたが、
    API 実行時にリアルタイムの値を直接渡すことができない という制約があり、「注文完了」「決済完了」「予約確定」などの 瞬間的なトランザクション通知 を柔軟にカスタマイズするのは難しい場面もありました。

    しかし Spring ’26 からは、

    • ✅ REST API で任意の値を直接渡せる

    • ✅ Apex で事前に日付・金額・フォーマット加工ができる

    • ✅ オンデマンドフローで即時送信できる

    これらを組み合わせることで、

    「必要なデータを、その瞬間に、そのままパーソナライズして届ける」

    という、より実践的でリアルタイムなコミュニケーションが実現可能になりました。特に、

    ・注文完了メール
    ・決済通知
    ・配送連絡
    ・予約確認
    ・ワンタイム情報通知

    といった トランザクション系メッセージとの相性は抜群 です。

    Marketing Cloud Next と Salesforce Platform(Apex)を組み合わせることで、単なるメール配信ツールではなく、業務ロジックと密接に連携した“アプリケーション基盤”として活用できる世界 が広がってきました。

    ぜひ皆さんの環境でも、オンデマンドフロー × Apex パーソナライズを試してみてください。

    今回は以上です。


    次の記事はこちら

    前回の記事はこちら

    私の note のトップページはこちら

     
     
     
    Salesforce Marketing Cloud、Agentforce、Data Cloud、Salesforce 認定資格に関する実践的な情報を発信しています。これらの記事が、皆さまの学習や日々の業務に少しでもお役に立てば幸いです。