メインコンテンツへスキップ
Create Message APIcustom_dataフィールドを使用して、バックエンドから動的データを送信し、Liquid構文を使ってテンプレート内でレンダリングします。 custom_data:
  • メッセージ固有のデータです
  • 保存されません
  • APIリクエスト中のみ存在します
  • template_idと一緒に使用する必要があります
テンプレートで値を参照するには:
Liquid
{{ message.custom_data.key_name }}
custom_dataは一時的なデータです。ユーザープロファイルには保存されず、将来のメッセージで再利用することはできません。永続的なデータが必要な場合は、メッセージパーソナライゼーションを参照してください。

custom_dataを使用するタイミング

custom_dataは以下の場合に使用します:
  • データがメッセージごとに変わる場合(注文合計、カートアイテム、残高)
  • 配列が必要な場合(商品リスト、明細項目、おすすめ商品)
  • データを永続化すべきでない場合(ワンタイムコード、一時的なURL)
  • バックエンドからトリガーされるメッセージを送信する場合
  • 1回のAPIリクエストで一括パーソナライゼーションを行いたい場合

custom_dataパーソナライゼーションの仕組み

メッセージにcustom_dataを追加するには、いくつかの手順が必要です:
1

テンプレートを作成する

ダッシュボードまたはCreate Template APIを使用して、Push、メール、またはSMSのテンプレートを作成します。
2

Liquidプレースホルダーを追加する

必須のプレフィックスを使用して参照を挿入します:
Liquid
Hi {{ message.custom_data.first_name }},
Order {{ message.custom_data.order_id }} is confirmed.
3

APIリクエストでcustom_dataを送信する

以下を含めてCreate Message APIを呼び出します:
  • template_id - テンプレートのID
  • custom_data - データオブジェクト
  • オーディエンスターゲティング(include_player_idsinclude_aliases、またはセグメント)
OneSignalは送信時にデータを使用してテンプレートをレンダリングします。Liquid構文が無効であるか、キーが存在しない場合、それらのフィールドは空文字列としてレンダリングされますが、メッセージは送信されます。

データパターン

custom_dataで使用できる一般的なデータパターンの例です。

フラットJSONの例

名前、ID、URL、またはその他の単一値データなど、基本的なパーソナライゼーションにはシンプルなキーバリューペアを使用します。 ユースケース: 各フィールドに単一の値を含むトランザクションメッセージ(請求書、領収書、確認)。 テンプレート:
Liquid
Invoice {{ message.custom_data.invoice_id }} for {{ message.custom_data.product_name }} is ready.
APIリクエスト:
JSON
{
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "include_email_tokens": ["user@example.com"],
  "custom_data": {
    "invoice_id": "463246732",
    "product_name": "Widget"
  }
}
顧客に表示される内容:
Text
Invoice 463246732 for Widget is ready.

配列データの例

カート内の商品、注文の明細項目、おすすめ商品など、複数のアイテムを扱うためにオブジェクトの配列を渡します。配列は直接アクセス(インデックス指定)と反復処理(ループ)の両方を可能にします。 ユースケース: 商品リスト、ランキング、注文サマリー、またはその他の複数アイテムデータの表示。 インデックス指定テンプレート(最初のアイテムにアクセス):
Liquid
Your {{message.custom_data.cart_items[0].item_name}} is waiting for you!
Image: {{message.custom_data.cart_items[0].img_url}}
配列のインデックスは0から始まります(1ではありません)。最初のアイテムは[0]、2番目は[1]です。存在しないインデックスにアクセスすると空が返されます(エラーはスローされません)。
ループテンプレート(すべてのアイテムにアクセス):
Liquid
{% for item in message.custom_data.cart_items %}
- {{ item.item_name }}{{ item.img_url }}
{% endfor %}
APIリクエスト:
{
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "include_email_tokens": ["user@example.com"],
  "custom_data": {
    "cart_items": [
      {
        "item_name": "sweater",
        "img_url": "https://.../sweater.png"
      },
      {
        "item_name": "socks",
        "img_url": "https://.../socks.png"
      }
    ]
  }
}
顧客に表示される内容:
Text
Your sweater is waiting for you!
Image: https://.../sweater.png

- sweater — https://.../sweater.png
- socks — https://.../socks.png
便利な配列プロパティ:
  • {{message.custom_data.cart_items.size}} — 配列内のアイテム数(この例では2を返します)
  • {{message.custom_data.cart_items.first.item_name}} — 最初のアイテムの名前([0]と同等)
  • {{message.custom_data.cart_items.last.item_name}} — 最後のアイテムの名前

一括パーソナライゼーションの例

1回のAPIリクエストを複数のユーザーに送信し、各受信者がexternal_idに基づいたパーソナライズされたコンテンツを表示できるようにします。 仕組み:
  1. custom_dataキーがexternal_id値がユーザー固有のデータであるオブジェクトとして構造化します
  2. テンプレートでsubscription.external_idを使用して現在の受信者のデータを検索します
  3. OneSignalは受信者ごとに、その受信者固有のデータでテンプレートを1回レンダリングします
テンプレート:
{% assign user = message.custom_data.users[subscription.external_id] %}
Hi {{ user.first_name }}, you have {{ user.points }} points. Your level is {{ user.level }}.
処理の内容:
  • subscription.external_idには現在の受信者のexternal_idが含まれています(例:「user123」)
  • message.custom_data.users[subscription.external_id]はcustom_dataオブジェクトからそのユーザーのデータを検索します
  • userはそのユーザーのデータのショートハンド変数になります
  • 各受信者は自分のパーソナライズされたコンテンツのみを見ることができます
APIリクエスト:
{
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "include_aliases": {
    "external_id": ["user123", "user456"]
  },
  "custom_data": {
    "users": {
      "user123": { "first_name": "John", "points": "150", "level": "Gold" },
      "user456": { "first_name": "Sarah", "points": "200", "level": "Platinum" }
    }
  }
}
各ユーザーに表示される内容:
  • John(user123):「Hi John, you have 150 points. Your level is Gold.」
  • Sarah(user456):「Hi Sarah, you have 200 points. Your level is Platinum.」
一括パーソナライゼーションの要件:
  • すべての受信者がOneSignalでexternal_idを設定している必要があります
  • include_aliases内の各external_idに対応するキーがcustom_data.usersに必要です
  • 受信者のexternal_idがcustom_dataに存在しない場合、そのメッセージのフィールドは空になります

例:custom_dataを使用したカゴ落ちメッセージ

custom_dataを使用して、メールとプッシュの両方でカゴ落ちメッセージを構築する方法です。 このアプローチを使用するタイミング:
  • サーバーがカゴ落ちを検出した場合(例:最後のアクティビティから1時間後)
  • リアルタイムのカートデータがデータベースにある場合
  • 画像、名前、価格付きの複数の商品を表示したい場合
  • 各ユーザーのアイテムと数量が異なる可能性がある場合
  • バックエンドからメッセージをオーケストレーションしたい場合

custom_dataペイロードの例

この例のCreate Message APIリクエストです。
JSON
{
  "custom_data": {
    "cart_url": "https://yourdomain.com/cart",
    "cart": [
      {
        "product_name": "24 Pack of Acorns",
        "product_image": "https://i.imgur.com/ssPCfbC.png",
        "product_price": "$12.99",
        "product_quantity": "1"
      },
      {
        "product_name": "Fancy Sweater",
        "product_image": "https://i.imgur.com/8QWTfV4.png",
        "product_price": "$9.99",
        "product_quantity": "1"
      }
    ]
  },
  "app_id": "YOUR_APP_ID",
  "template_id": "YOUR_TEMPLATE_ID",
  "include_aliases": {
    "external_id": ["YOUR_EXTERNAL_ID"]
  }
}
フィールドの説明:
フィールド用途
cart_urlstring顧客固有のカートリンク(ボタン/起動URLに使用)
cartarray商品リスト — カウント、ループ、詳細表示に対応
product_imagestring商品画像(配列内のアイテムごと)
product_namestring商品名(アイテムごと)
product_quantitystring数量(アイテムごと)
product_pricestringフォーマット済み価格(アイテムごと)
フィールド名は自由に設定できます。テンプレートのLiquid構文が一致していることを確認してください。
2KB以下に抑えてください: カートが大きい場合は、最初の3〜5アイテムに制限するか、必須フィールドのみを送信して、サイズ制限を超えないようにしてください。

メールテンプレート

この例では、以下を表示するメールテンプレートの構築方法を説明します:
  • カートアイテム数
  • forループを使用した各商品の画像、名前、数量、価格
  • 顧客固有のカートURLにリンクするボタン
1

メールテンプレートを作成する

Messages > Templates > New Email Templateに移動し、ドラッグ&ドロップエディターを開きます。
2

レイアウト構造を追加する

5つの行を作成します:
  • 行1、2、4:Paragraphブロックを含む1列
  • 行3:HTML | Paragraph | Paragraph | Paragraphの4列
  • 行5:Buttonブロックを含む1列
3

アイテム数を表示する

行1に以下を追加します:
Liquid
We're holding onto {{message.custom_data.cart.size}} items in your cart, but don't wait too long, other squirrels are getting ahead!
文法を改善するために、「1 item」と「2 items」を条件分岐で使い分けることもできますが、カゴ落ちメールでは通常、複数形で問題ありません。
Liquid
{% assign cart = message.custom_data.cart %}
{% assign item_count = cart.size | plus: 0 %}
{% if item_count == 1 %}
We're holding onto {{item_count}} item in your cart, but don't wait too long, other squirrels are getting ahead!
{% endif %}
{% if item_count > 1 %}
We're holding onto {{item_count}} items in your cart, but don't wait too long, other squirrels are getting ahead!
{% endif %}
4

ループを開始する

forループを使用して、カート内の各アイテムに対して商品表示行を繰り返します。行2(ループ開始)のテキストブロックに以下を追加します:
Text
{% for product in message.custom_data.cart %}
この処理の内容:
  • cart配列内の各オブジェクトを反復するループを開始します
  • 現在のアイテムを表すproductという一時変数を作成します
  • {% for %}{% endfor %}の間のすべてがカートアイテムごとに1回繰り返されます
  • productは任意の名前(例:itemcartItem)に変更できますが、一貫性を保ってください
forループの配置:{% for %}構文は独自のテキストブロック行に配置してください。他のコンテンツを含む複数列の行の中に入れないでください。一部のメールクライアントでレンダリングが崩れる可能性があります。
5

商品詳細を表示する

この4列の行は、画像、名前、数量、価格を表示します。ループ内にあるため、カートアイテムごとに繰り返されます。行3(商品詳細)を設定します:列1 - HTMLブロック(商品画像):
HTML
<img src="{{product.product_image}}" alt="Product image" style="max-width:100%;" />
列2〜4 - テキストブロック(商品名、数量、価格):
  • 列2:{{product.product_name}}
  • 列3:{{product.product_quantity}}
  • 列4:{{product.product_price}}
ループの動作:
  • 最初の反復では、product = カート配列の最初のオブジェクト
  • {{product.product_image}}は最初のアイテムの画像URLを取得します
  • 2回目の反復では、product = 2番目のオブジェクト
  • この行はすべてのカートアイテムに対して自動的に繰り返されます
フィールド名の一致: product_imageのようなキーは、イベントペイロードと完全に一致する必要があります(大文字小文字を区別)。不一致の場合、空文字列としてレンダリングされます。
6

ループを終了する

ループを閉じて、繰り返しの終了位置を示します。行4(ループ終了)に以下を追加します:
Liquid
{% endfor %}
すべての{% for %}には対応する{% endfor %}が必要です。これがない場合、メールのレンダリングが崩れます。
7

カートリンクボタンを追加する

行5のButtonブロックで、アクションURLを以下に設定します:
Text
{{message.custom_data.cart_url}}
8

テンプレートをテストする

  • 例のcustom_dataペイロードを使用してAPIリクエストをセットアップします
  • 自分宛にメールを送信します。
  • データが正しく表示されることを確認します。
成功です!これで独自のスタイルをテンプレートに適用できます。ドラッグ&ドロップでメールをデザインするを参照してください。

プッシュテンプレート

プッシュ通知には文字数制限とオペレーティングシステムの制約があるため、すべてのアイテムを表示する代わりに、最初の商品を表示し、適切な文法で合計数を示します。 以下は構築するプッシュ通知の例です:
メッセージフィールド:
Liquid
{% assign cart = message.custom_data.cart %}
{% assign item_count = cart.size | plus: 0 %}
{% if item_count == 1 %}
You left {{cart.first.product_name}} in your cart.
{% endif %}
{% if item_count == 2 %}
You left {{cart.first.product_name}} and {{item_count | minus: 1}} more item in your cart.
{% endif %}
{% if item_count > 2 %}
You left {{cart.first.product_name}} and {{item_count | minus: 1}} more items in your cart.
{% endif %}
詳細については、Liquid構文の使用を参照してください。
画像フィールド:
Liquid
{{message.custom_data.cart.first.product_image | default: "https://i.imgur.com/ssPCfbC.png"}}
詳細については、通知画像とリッチメディアを参照してください。
起動URLフィールド:
Liquid
{{cart_url | default: "https://yourdomain.com/cart"}}
成功です!テンプレートを保存し、そのtemplate_idCreate message APIリクエストでcustom_dataプロパティと一緒に使用してテストしてください。

トラブルシューティングとベストプラクティス

  • シンプルに保つ:テンプレートで実際に使用するデータのみを含めてください
  • 2KB以下に抑える:特に配列を含む場合、ペイロードサイズを監視してください
  • 一貫した命名規則を使用する:全体を通してsnake_caseまたはcamelCaseで統一してください
  • 送信前にバリデーションする:null値、空の配列、必須フィールドを確認してください
テンプレート設計:
  • オプションフィールドには常にdefaultフィルターを使用してください
    Liquid
    {{message.custom_data.user_name | default: "there"}}
    
  • ループ前に配列サイズを確認してください
    Liquid
    {% if message.custom_data.items.size > 0 %}
      {% for item in message.custom_data.items %}
        {{item.name}}
      {% endfor %}
    {% endif %}
    
  • エッジケースでテストしてください:空の配列、欠落フィールド、最大アイテム数
エラーハンドリング:
  • バリデーションエラーをキャッチするために、APIレスポンスをサーバーサイドでログに記録してください
  • メッセージ配信率を監視してください — 急激な低下はLiquidエラーを示している可能性があります
  • 重要なトランザクションメッセージ用にフォールバックテンプレートを準備しておいてください
パフォーマンス:
  • 複雑なLiquidロジックを使用する代わりに、バックエンドで複雑なデータを事前にフォーマットしてください
  • テンプレートをキャッシュして、多数のAPI呼び出しで再利用してください
  • 大量のトランザクションメッセージとマーケティングキャンペーンを分離することを検討してください
原因: Liquid構文エラーまたはフィールド名の不一致解決方法:
  • custom_dataとテンプレート間でフィールド名が完全に一致していることを確認してください(大文字小文字を区別)
  • タイプミスを確認してください:{{message.custom_data.name}}であり、{{message.custm_data.name}}ではありません
  • 欠落フィールドをキャッチするためにdefaultフィルターを使用してください
  • 本番環境に導入する前に、実際のcustom_data構造でテンプレートをテストしてください
原因: custom_dataが2KB制限を超えています解決方法:
  • ペイロードから不要なフィールドを削除してください
  • 可能な場合はフィールド名と値を短縮してください
  • 配列を最初の3〜5アイテムに制限してください
  • 大きな静的コンテンツ(完全なHTMLなど)はテンプレートに移動してください

関連ページ

サポートが必要ですか?サポートチームとチャットするか、support@onesignal.comにメールしてください以下を含めてください:
  • 発生している問題の詳細と再現手順(利用可能な場合)
  • OneSignal App ID
  • 該当する場合は、External IDまたはSubscription ID
  • 該当する場合は、OneSignalダッシュボードでテストしたメッセージのURL
  • 関連するログまたはエラーメッセージ
お気軽にお問い合わせください!