# OpenAI Ads Conversion API エクスポート連携

## 概要

OpenAI Ads Conversion API コネクターは、Treasure AI から OpenAI Ads Pixel にサーバーサイドのコンバージョンイベントをエクスポートします。[OpenAI Ads Conversions API](https://developers.openai.com/ads/conversions-api) を使用して、標準イベントまたはカスタムイベントを検証、バッチ処理、送信します。

コネクターはイベントタイプごとに OpenAI イベントデータの形式を導出し、制限対象のユーザー識別子を正規化してハッシュ化します。1リクエストあたり最大1,000件のイベントを送信します。

## 前提条件

- Treasure AI の基本的な知識。
- 有効な OpenAI Ads アカウント。
- 既存の OpenAI Ads Web Pixel とその **Pixel ID**。
- OpenAI Ads アカウントのサーバーサイド **Conversions API key**。


## 制限事項と既知の問題

- イベントのタイムスタンプは、過去7日以内で、未来10分以内である必要があります。
- 1リクエストに含められるイベントは最大1,000件です。リクエスト内のイベントを1件でも OpenAI が拒否すると、リクエスト全体が失敗します。
- **Skip Invalid Records** は、アップロード前のコネクター検証で拒否されたレコードに適用されます。OpenAI がアップロード済みのバッチを拒否した後に、1件のイベントだけを分離することはできません。
- OpenAI API は、各ユーザーリストフィールドの有効で一意な値のうち、最初の3件だけを使用します。
- 未加工のメールアドレス、電話番号、外部 ID、名、姓は、送信前に正規化され、SHA-256 でハッシュ化されます。
- Android GAID は `android_advertising_id` を使用してサポートされます。
- OpenAI のドキュメントでは、送信成功時の完全なレスポンススキーマは定義されていません。測定結果とアトリビューション結果は OpenAI Ads Manager で確認してください。


## Treasure コンソールを使用する

### 新しい接続を作成する

クエリ結果をエクスポートする前に、認証とデータ接続を作成します。

1. **Treasure コンソール**を開きます。
2. **Integrations Hub > Catalog** に移動します。
3. **OpenAI Ads Conversion API** を検索して選択します。


![](/assets/new_connector_logo.d0d75fa2cf1fe7deb94c1d90f78cdba33a6ca88df7bbb83ee0c41601b67a55a5.01afb486.webp)

1. **Create Authentication** を選択します。
2. サーバーサイドの **Conversions API Key** を入力します。


![](/assets/new_connector_config.ab5335996c2d0e625e088756f0b1df3de21550b7c14b7031dc7b6be2c41c4420.01afb486.webp)

1. **Continue** を選択します。
2. 認証の名前を入力し、**Done** を選択します。
3. 認証を選択し、コネクターのパラメーターを設定します。


### 認証パラメーター

| フィールド | 説明 | 必須 |
|  --- | --- | --- |
| **Conversions API Key** | コンバージョンイベントの送信にのみ使用するサーバーサイドキー。キーはシークレットとして保存され、作成後に表示されることはありません。 | Yes |


### クエリを定義する

Treasure コンソールでは、データをエクスポートする複数の方法がサポートされています。Data Workbench からエクスポートするには、次の手順を実行します。

1. **Data Workbench > Queries** に移動します。
2. **New Query** を選択し、クエリを定義します。
3. **Export Results** を選択します。
4. 既存の OpenAI Ads Conversion API 認証を選択するか、前述の手順で認証を作成します。
5. エクスポートパラメーターを設定します。


![](/assets/export_config.d82d97ee87ce4b907ddbc614ea761ca26749edc4d176895748abe54da58dda02.01afb486.webp)

1. **Done** を選択します。


### コネクター設定パラメーター

| フィールド | 説明 | 必須 | デフォルト |
|  --- | --- | --- | --- |
| **Pixel ID** | コンバージョンイベントを受け取る OpenAI Ads Pixel ID。 | Yes |  |
| **Skip Invalid Records** | 有効にすると、コネクターの検証に失敗したレコードをカウントしてスキップします。無効にすると、最初の無効なレコードでジョブが停止します。 | No | `true` |


## クエリデータの仕様

クエリ結果の各行は、1件のコンバージョンイベントを表します。列名の前後の空白は削除され、大文字と小文字を区別せずに照合されます。たとえば、`EVENT_ID`、`Event_Id`、`event_id` は同じものとして扱われます。

大文字と小文字、または前後の空白だけが異なる重複名は無効です。不明な列は無視されます。`NULL` 値を持つ列は、そのレコードではスキップされます。

### エクスポートクエリの仕様

| 仕様 | 説明 |
|  --- | --- |
| **必須列** | すべてのレコードに次の列が必要です。- `event_id`
- `event_type`
- `event_timestamp`

 |
| **データ形式** | コネクターは `event_type` から `events[].data.type` を導出します。データタイプ用の別の列は含めないでください。 |
| **カスタムイベント** | `event_type` が `custom` の場合、`custom_event_name` が必要です。1～64文字の英字、数字、アンダースコア、ハイフンを含み、先頭と末尾は英字または数字である必要があります。また、標準イベント名と一致してはいけません。 |
| **Web イベント** | `action_source` が `web` の場合、`source_url` が必要です。URL スキームとホストを含める必要があります。 |
| **アプリのライフサイクルイベント** | `app_installed` と `app_opened` では、`action_source` に `mobile_app` を指定する必要があります。 |
| **金額** | `data_amount` が存在する場合、`data_currency` が必要です。アイテム単位の値では、`content_amount[N]` が存在する場合に `content_currency[N]` またはイベントレベルの `data_currency` を指定します。 |
| **番号付きユーザーフィールド** | ユーザーリスト列では、`email`、`email1`、`email2` のような数字のサフィックスを使用できます。OpenAI はスキーマの順序に従って有効で一意な値の最初の3件を使用し、追加の値はイベントを拒否せずに無視します。 |
| **番号付きコンテンツアイテム** | 同じ数字のサフィックスを持つコンテンツ列は、`events[].data.contents[]` 内の1つのアイテムを構成します。サフィックスのない列は最初のアイテムを構成します。 |
| **バリアント辞書のペア** | `content_variant_dict_key[N]` と `content_variant_dict_value[N]` は、同時に指定する必要があります。これらにより、対応するサフィックスのコンテンツアイテムに文字列マップが作成されます。たとえば、キー `size` と値 `medium` は `{"size":"medium"}` を生成します。 |
| **重複列** | 前後の空白を削除し、大文字と小文字を正規化した後に列名が重複することは許可されません。 |
| **不明な列** | サポートされている名前またはパターンに一致しない列は無視されます。 |


### サポートされているイベントタイプ

| `event_type` | 導出される `data.type` | 説明 |
|  --- | --- | --- |
| `app_installed` | `customer_action` | ユーザーがアプリケーションをインストールします。`action_source=mobile_app` が必要です。 |
| `app_opened` | `customer_action` | ユーザーがアプリケーションを開きます。`action_source=mobile_app` が必要です。 |
| `appointment_scheduled` | `customer_action` | ユーザーがミーティング、デモ、または相談を予約します。 |
| `checkout_started` | `contents` | ユーザーがチェックアウトを開始します。 |
| `contents_viewed` | `contents` | ユーザーが商品、リスト、記事、その他のコンテンツ単位を表示します。 |
| `custom` | `custom` | 標準分類に含まれないユーザー定義イベントです。`custom_event_name` が必要です。 |
| `items_added` | `contents` | ユーザーがカート、バンドル、または選択項目に1つ以上のアイテムを追加します。 |
| `lead_created` | `customer_action` | ユーザーがリードフォームを送信するか、連絡を依頼します。 |
| `order_created` | `contents` | 購入が完了します。 |
| `page_viewed` | `contents` | ユーザーが重要なページにアクセスするか、表示します。 |
| `registration_completed` | `customer_action` | ユーザーがアカウントまたはイベントの登録フローを完了します。 |
| `subscription_created` | `plan_enrollment` | 有料サブスクリプションが開始されます。 |
| `trial_started` | `plan_enrollment` | 無料トライアルが開始されます。 |


### イベントフィールド

| 列名 | 送信先フィールド | データ型 | 必須 | 説明 |
|  --- | --- | --- | --- | --- |
| `event_id` | `events[].id` | String | Yes | 空でない安定した識別子。再試行とブラウザー/API の重複排除には同じ値を再利用します。 |
| `event_type` | `events[].type` | String | Yes | サポートされている標準イベント名または `custom`。照合では大文字と小文字を区別しません。 |
| `event_timestamp` | `events[].timestamp_ms` | Long または Timestamp | Yes | ミリ秒単位の Unix 時刻、またはミリ秒に変換された Embulk タイムスタンプ。許可された API の時間範囲内である必要があります。 |
| `custom_event_name` | `events[].custom_event_name` | String | `event_type=custom` の場合 | カスタムイベント名。OpenAI は値を小文字に変換します。 |
| `source_url` | `events[].source_url` | String | `action_source=web` の場合 | Web コンバージョンが発生した URL。空白以外の値にはスキームとホストを含める必要があります。 |
| `action_source` | `events[].action_source` | String | 条件付き | 使用できる値は `web`、`mobile_app`、`offline`、`physical_store`、`phone_call`、`email`、`other` です。照合では大文字と小文字を区別しません。 |
| `oppref` | `events[].oppref` | String | No | OpenAI の不透明なアトリビューション識別子。変更せずにそのまま渡されます。 |
| `opt_out` | `events[].opt_out` | Boolean または Long | No | ブール値または `0`/`1` を使用します。 |


### イベントデータフィールド

| 列名 | 送信先フィールド | データ型 | 必須 | 説明 |
|  --- | --- | --- | --- | --- |
| `data_amount` | `events[].data.amount` | Long | No | 通貨の標準的な最小単位で指定する金額。たとえば、USD 42.00 には `4200` を使用します。 |
| `data_currency` | `events[].data.currency` | String | `data_amount` が存在する場合 | 3文字の ISO 4217 コード。コネクターは値を大文字に変換します。 |
| `data_plan_id` | `events[].data.plan_id` | String | No | 内部プラン識別子。`plan_enrollment` および `custom` データタイプでのみ使用できます。 |


### コンテンツアイテムフィールド

数字のサフィックスを使用して、複数のコンテンツアイテムを作成します。たとえば、`content_id1`、`content_name1`、`content_quantity1` は同じアイテムを表します。

コンテンツフィールドは、導出されるデータタイプが `contents`、`plan_enrollment`、または `custom` の場合にサポートされます。`customer_action` イベントでは無効です。

| 列名 | 送信先フィールド | データ型 | 説明 |
|  --- | --- | --- | --- |
| `content_id`, `content_id[N]` | `events[].data.contents[].id` | String | 商品、アイテム、またはコンテンツの内部識別子。 |
| `content_group_id`, `content_group_id[N]` | `events[].data.contents[].group_id` | String | 商品グループまたは親アイテムの識別子。 |
| `content_name`, `content_name[N]` | `events[].data.contents[].name` | String | 人が読めるアイテム名。 |
| `content_type`, `content_type[N]` | `events[].data.contents[].content_type` | String | `product`、`plan`、`page` などの空でないアイテムカテゴリ。 |
| `content_quantity`, `content_quantity[N]` | `events[].data.contents[].quantity` | Long | アイテム数量。 |
| `content_amount`, `content_amount[N]` | `events[].data.contents[].amount` | Long | 通貨の標準的な最小単位で指定するアイテム単位の金額。 |
| `content_currency`, `content_currency[N]` | `events[].data.contents[].currency` | String | 3文字の ISO 4217 コード。`data_currency` がイベント全体に適用される場合は省略できます。 |
| `content_variant_dict_key`, `content_variant_dict_key[N]` | `events[].data.contents[].variant_dict` のキー | String | 同じサフィックスの値列とペアで使用します。 |
| `content_variant_dict_value`, `content_variant_dict_value[N]` | `events[].data.contents[].variant_dict` の値 | String | 同じサフィックスのキー列とペアで使用します。 |


### ハッシュ化されるユーザーマッチングフィールド

未加工の値は正規化され、UTF-8 でエンコードされた後、小文字の16進数による SHA-256 ハッシュに変換されます。64文字の16進数ハッシュが指定された場合は、そのまま使用して小文字に変換します。

| 列名 | 送信先フィールド | 正規化 |
|  --- | --- | --- |
| `email`, `email[N]` | `events[].user.emails_sha256[]` | 先頭と末尾の空白を削除し、小文字に変換します。 |
| `phone_number`, `phone_number[N]` | `events[].user.phone_numbers_sha256[]` | 空白、括弧、ピリオド、ハイフン、先頭のプラス記号、先頭のゼロを削除します。結果は8～15桁の数字である必要があります。 |
| `external_id`, `external_id[N]` | `events[].user.external_ids_sha256[]` | 先頭と末尾の空白を削除します。大文字と小文字、その他の文字は保持します。 |
| `first_name`, `first_name[N]` | `events[].user.first_names_sha256[]` | 小文字に変換し、空白と ASCII 句読点を削除します。ASCII 以外の文字は保持します。 |
| `last_name`, `last_name[N]` | `events[].user.last_names_sha256[]` | 小文字に変換し、空白と ASCII 句読点を削除します。ASCII 以外の文字は保持します。 |


### 未加工のユーザーマッチングフィールド

| 列名 | 送信先フィールド | データ型 | 注記 |
|  --- | --- | --- | --- |
| `region`, `region[N]` | `events[].user.regions[]` | String | 未加工の地域値。正規化後の最大長は128文字です。 |
| `postal_code`, `postal_code[N]` | `events[].user.postal_codes[]` | String | 英字、数字、空白、ハイフンを使用できます。最大32文字です。 |
| `city`, `city[N]` | `events[].user.cities[]` | String | 未加工の都市名。正規化後の最大長は128文字です。 |
| `country`, `country[N]` | `events[].user.countries[]` | String | 2文字の国コード。コネクターは値を大文字に変換します。 |
| `android_advertising_id` | `events[].user.android_advertising_id` | String | UUID 形式の未加工の Android GAID。Apple IDFA はサポートされていません。 |
| `obref` | `events[].user.obref` | String | Pixel の `__obref` Cookie に含まれる不透明なブラウザー参照。空白以外で、測定への同意がある場合にのみ送信されます。 |
| `ip_address` | `events[].user.ip_address` | String | 有効な IPv4 または IPv6 アドレス。 |
| `user_agent` | `events[].user.user_agent` | String | 空でないクライアントの User-Agent 文字列。 |


### クエリの例

```sql
SELECT
  CONCAT('order-', CAST(order_id AS VARCHAR)) AS event_id,
  'order_created' AS event_type,
  CAST(TO_UNIXTIME(order_time) * 1000 AS BIGINT) AS event_timestamp,
  'web' AS action_source,
  confirmation_url AS source_url,
  total_amount_minor_units AS data_amount,
  currency_code AS data_currency,
  customer_email AS email,
  country_code AS country,
  product_id AS content_id,
  product_name AS content_name,
  'product' AS content_type,
  quantity AS content_quantity,
  'size' AS content_variant_dict_key,
  product_size AS content_variant_dict_value
FROM completed_orders
```

### (オプション) Query Export ジョブをスケジュールする

Scheduled Jobs と Result Export を使用して、指定したターゲット宛先に出力結果を定期的に書き込むことができます。

Treasure Data のスケジューラー機能は、高可用性を実現するために定期的なクエリ実行をサポートしています。

2 つの仕様が競合するスケジュール仕様を提供する場合、より頻繁に実行するよう要求する仕様が優先され、もう一方のスケジュール仕様は無視されます。

例えば、cron スケジュールが `'0 0 1 * 1'` の場合、「月の日」の仕様と「週の曜日」が矛盾します。前者の仕様は毎月 1 日の午前 0 時 (00:00) に実行することを要求し、後者の仕様は毎週月曜日の午前 0 時 (00:00) に実行することを要求するためです。後者の仕様が優先されます。

#### Treasure コンソール を使用してジョブをスケジュールする

1. **Data Workbench > Queries** に移動します
2. 新しいクエリを作成するか、既存のクエリを選択します。
3. **Schedule** の横にある None を選択します。
![](/assets/image2021-1-15_17-28-51.f1b242f6ecc7666a0097fdf37edd1682786ec11ef80eff68c66f091bc405c371.0f87d8d4.png)
4. ドロップダウンで、次のスケジュールオプションのいずれかを選択します:
![](/assets/image2021-1-15_17-29-47.45289a1c99256f125f4d887e501e204ed61f02223fde0927af5f425a89ace0c0.0f87d8d4.png)
| ドロップダウン値 | 説明 |
|  --- | --- |
| Custom cron... | [Custom cron... の詳細](#custom-cron-details)を参照してください。 |
| @daily (midnight) | 指定されたタイムゾーンで 1 日 1 回午前 0 時 (00:00 am) に実行します。 |
| @hourly (:00) | 毎時 00 分に実行します。 |
| None | スケジュールなし。 |


#### Custom cron... の詳細

![](/assets/image2021-1-15_17-30-23.0f94a8aa5f75ea03e3fec0c25b0640cd59ee48d1804a83701e5f2372deae466c.0f87d8d4.png)

| **Cron 値** | **説明** |
|  --- | --- |
| `0 * * * *` | 1 時間に 1 回実行します。 |
| `0 0 * * *` | 1 日 1 回午前 0 時に実行します。 |
| `0 0 1 * *` | 毎月 1 日の午前 0 時に 1 回実行します。 |
| "" | スケジュールされた実行時刻のないジョブを作成します。 |


```
 *    *    *    *    *
 -    -    -    -    -
 |    |    |    |    |
 |    |    |    |    +----- day of week (0 - 6) (Sunday=0)
 |    |    |    +---------- month (1 - 12)
 |    |    +--------------- day of month (1 - 31)
 |    +-------------------- hour (0 - 23)
 +------------------------- min (0 - 59)
```

次の名前付きエントリを使用できます:

- Day of Week: sun, mon, tue, wed, thu, fri, sat.
- Month: jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec.


各フィールド間には単一のスペースが必要です。各フィールドの値は、次のもので構成できます:

div
| フィールド値  | 例  | 例の説明  |
|  --- | --- | --- |
| 各フィールドに対して上記で表示された制限内の単一の値。 |  |  |
| フィールドに基づく制限がないことを示すワイルドカード
`'*'`。 | `'0 0 1 * *'` | 毎月 1 日の午前 0 時 (00:00) に実行するようにスケジュールを設定します。 |
| 範囲 `'2-5'`
フィールドの許可される値の範囲を示します。 | `'0 0 1-10 * *'` | 毎月 1 日から 10 日までの午前 0 時 (00:00) に実行するようにスケジュールを設定します。 |
| カンマ区切りの値のリスト `'2,3,4,5'`
フィールドの許可される値のリストを示します。 | `0 0 1,11,21 * *'` | 毎月 1 日、11 日、21 日の午前 0 時 (00:00) に実行するようにスケジュールを設定します。 |
| 周期性インジケータ `'*/5'`
フィールドの有効な値の範囲に基づいて、
スケジュールが実行を許可される頻度を表現します。 | `'30 */2 1 * *'` | 毎月 1 日、00:30 から 2 時間ごとに実行するようにスケジュールを設定します。
`'0 0 */5 * *'` は、毎月 5 日から 5 日ごとに午前 0 時 (00:00) に実行するようにスケジュールを設定します。 |
| `'*'`
ワイルドカードを除く上記の
いずれかのカンマ区切りリストもサポートされています
`'2,*/5,8-10'` | `'0 0 5,*/10,25 * *'` | 毎月 5 日、10 日、20 日、25 日の午前 0 時 (00:00) に実行するようにスケジュールを設定します。 |


1. (オプション) Delay execution を有効にすることで、クエリの開始時刻を遅延させることができます。


### クエリを実行する

クエリに名前を付けて保存して実行するか、単にクエリを実行します。クエリが正常に完了すると、クエリ結果は指定された宛先に自動的にエクスポートされます。

設定エラーにより継続的に失敗するスケジュールジョブは、複数回通知された後、システム側で無効化される場合があります。

(オプション) Delay execution を有効にすることで、クエリの開始時刻を遅延させることができます。

## Audience Studio で Segment をアクティベートする

Audience Studio で activation を作成することで、segment データをターゲットプラットフォームに送信することもできます。

1. **Audience Studio** に移動します。
2. parent segment を選択します。
3. ターゲット segment を開き、右クリックして、**Create Activation** を選択します。
4. **Details** パネルで、Activation 名を入力し、前述の Configuration Parameters のセクションに従って activation を設定します。
5. **Output Mapping** パネルで activation 出力をカスタマイズします。


![](/assets/ouput.b2c7f1d909c4f98ed10f5300df858a4b19f71a3b0834df952f5fb24018a5ea78.8ebdf569.png)

- Attribute Columns
  - **Export All Columns** を選択すると、変更を加えずにすべての列をエクスポートできます。
  - **+ Add Columns** を選択して、エクスポート用の特定の列を追加します。Output Column Name には、Source 列名と同じ名前があらかじめ入力されます。Output Column Name を更新できます。**+ Add Columns** を選択し続けて、activation 出力用の新しい列を追加します。
- String Builder
  - **+ Add string** を選択して、エクスポート用の文字列を作成します。次の値から選択します:
    - String: 任意の値を選択します。テキストを使用してカスタム値を作成します。
    - Timestamp: エクスポートの日時。
    - Segment Id: segment ID 番号。
    - Segment Name: segment 名。
    - Audience Id: parent segment 番号。


1. **Schedule** を設定します。


![](/assets/snippet-output-connector-on-audience-studio-2024-08-28.a99525173709da1eb537f839019fa7876ffae95045154c8f2941b030022f792c.8ebdf569.png)

- スケジュールを定義する値を選択し、オプションでメール通知を含めます。


1. **Create** を選択します。


batch journey の activation を作成する必要がある場合は、[Creating a Batch Journey Activation](/products/customer-data-platform/journey-orchestration/batch/creating-a-batch-journey-activation) を参照してください。

## (オプション) Workflow でエクスポート結果を設定する

Treasure Workflow で既存の OpenAI Ads Conversion API 接続を使用します。

```yaml
_export:
  td:
    database: conversions_db

+openai_conversion_export:
  td>: queries/openai_conversions.sql
  database: ${td.database}
  result_connection: openai_ads_conversions
  result_settings:
    pixel_id: "xxxxxx"
    skip_invalid_records: true
```

## (オプション) CLI を使用してエクスポート連携する

[TD Toolbelt](https://toolbelt.treasuredata.com/) を使用すると、コマンドラインからクエリ結果をエクスポートできます。`--result` に既存のコンソール認証とコネクター設定を指定します。

```json
{
  "type": "openai_conversion_api",
  "conversions_api_key": "xxxxxx",
  "pixel_id": "xxxxxxx",
  "skip_invalid_records": true
}
```

### CLI パラメーター

| 名前 | 説明 | 値 | デフォルト | 必須 |
|  --- | --- | --- | --- | --- |
| `type` | コネクタータイプの識別子。 | `openai_conversion_api` |  | Yes |
| `conversions_api_key` | サーバーサイドの Conversions API キー。 | String |  | Yes |
| `pixel_id` | イベントを受け取る OpenAI Ads Pixel ID。 | String |  | Yes |
| `skip_invalid_records` | ジョブを停止せず、ローカルで無効なレコードをスキップします。 | `true` / `false` | `true` | No |


### CLI の例

```bash
td query \
  --result '{"type":"openai_conversion_api","conversions_api_key":"xxxx","pixel_id":"xxxxxx","skip_invalid_records":true}' \
  -d conversions_db \
  "SELECT event_id, event_type, event_timestamp, email FROM conversion_events" \
  -T presto
```

## その他

- [OpenAI Ads Conversions API](https://developers.openai.com/ads/conversions-api)
- [OpenAI Ads Supported Events](https://developers.openai.com/ads/supported-events)