TikTok APIを用いて広告レポートを自動的に取得する

[PONOS Advent Calendar 2022](https://qiita.com/advent-calendar/2022/ponos)の3日目の記事です。

昨日は[@block](https://qiita.com/block)さんでした。

# はじめに
今回は[TikTok API for Business](https://ads.tiktok.com/marketing_api/docs?id=1735712062490625)を使用し、広告レポートの取得を行う方法を紹介してみようと思います。
他のプラットフォームでも類似の機能を持つAPIが存在しておりますが、TikTokの[Reporting API](https://ads.tiktok.com/marketing_api/docs?id=1738864739862530)では同期レポートと非同期レポートという2種のレポート取得方法があり、それぞれで取得できるデータに違いがある点が特徴的です。

# 事前手順
APIを利用するにあたり、アカウントの準備などが必要になります。
基本的にはこちらの[公式ドキュメント](https://ads.tiktok.com/marketing_api/docs?id=1735713609895937)の通りなのですが、注意点なども踏まえた上で、改めてまとめてみたいと思います。

1. [TikTokビジネスアカウントの作成](https://ads.tiktok.com/marketing_api/docs?id=1738855099573250)
公式手順通り、まずはアカウントを作成します。
1. [アカウントの開発者登録](https://ads.tiktok.com/marketing_api/docs?id=1738855176671234)
こちらも公式手順通り、**My Apps**ページから**Become a Developer**をクリックして開発者登録を進めます。
利用目的など、入力欄がいくつかあります。
1. [開発者アプリを登録する](https://ads.tiktok.com/marketing_api/docs?id=1738855242728450)
これはAPIを利用するアプリということになります。作成後は審査が入ります。
    * **アプリの権限選択**では必要最低限のみチェックを入れましょう。レポートのみが目的であれば、ReportingカテゴリのチェックでOKですが、利用手段に応じて選択してください。
    * **リダイレクトURL**の入力欄があります。これは、後述の認証用のコードを取得する際に使用されるため、詳しくはそちらで紹介しますが、WEBブラウザで認証操作を行った人が、認証後に設定したURLに対して認証コード（**auth_code**）がパラメータについた状態でリダイレクトされるようになっています。
そのため、自身で認証する場合は自身が所有する（例えば会社のWEBサイトなど）でも動作しますが、システム的に認証コードを受け取りたい場合などの場合は適切なURLを設定することになると思います。
もちろん**関係のないWEBサイトのURLを指定した場合、リクエストパラメータの認証コード（auth_code）が漏れる危険があるため、絶対にNGです。**
また、自身で認証する場合はURLパラメータからコードを自分で取り出すことになるため、**ローカルホストのURLでも支障はないように思いますが、実際にやってみたところ(2022年現在)審査が通りませんでしたのでご注意ください。**

以上、ここまでがまず最低限の事前手順となります。

# APIで利用するトークンを取得する
APIを利用するために、長期アクセストークンを取得する必要があります。
取得方法は簡単に言えば二つのステップがあります。
1. **認証コード（auth_code）** を取得する。
1. **長期アクセストークン** を取得する。

この操作を具体的に説明する前に、以下の注意点があります。
`auth_codeは1時間のみ有効で、1回のみ使用可能です。auth_codeの有効期限を過ぎると、再度、認証の手順を行う必要があります。`
つまり、**これらの操作は一連して行う必要があり、失敗した場合は改めてauth_codeの発行を行わなければいけません**。自身で発行するようなケースではそれほど困りませんが、そうでない場合は厄介です。そうしたケースでは、前述にある**リダイレクトURL**に、長期アクセストークンを発行するための処理を仕込んだページを用意しておくなど、システムの対応があるとよさそうです。
今回はそのケースではないため、手動で取得しますが、あらかじめどのような操作を行うのかを先に見て、準備しておいたほうがよいです。

## [認証コード（auth_code） を取得する](https://ads.tiktok.com/marketing_api/docs?id=1738373141733378)
この操作は**開発者アプリ**が**広告主**から承認を得るための操作です。
ここでいう広告主というのは、実際のところは取得したいデータを持つ広告アカウントの権利を持った人のことです。
1. My Appsに移動し、認可を要求したいアプリをクリックします。
1. 基本情報から、広告主の承認用URLを見つけます。
1. このURLを広告主に送信し、広告主が認可できるようにします。
今回のケースでは、自身が広告アカウントの権利を有しているため、自分で認可します。
1. 広告主はブラウザで認証URLを入力し、案内に従って認可を行います。
URLを入力すると、アプリ作成時に付与した権限が表示されますので、問題ないことを確認して許可します。
**広告主のメールアドレスに対して確認コードが送信されるので、1分以内にそれを入力して確定します。**
1. **auth_code**を取り出す
アプリ作成時に登録したURLに対してリダイレクトされます。この時、以下の例のように**URLパラメータにauth_codeが含まれています**。
`https://ads.tiktok.com/marketing_api/docs？state=your_custom_params&code=3c6dc21d2db289199737bcb8c006c23aaf000a1e&auth_code=1234c21d2db289199737bcb8c006c23aaf000a1e&id=1701890905779201`
※ TikTokのドキュメントから抜粋
このauth_codeを教えてもらいます（今回は自分なので不要ですが）。

## 長期アクセストークンを取得する
auth_codeを使用してリクエストを送ることで、長期アクセストークンを取得することができます。
繰り返しになりますが、auth_codeには回数と時間に制限があるため、前段の作業からスムーズに行うことが必要です。

このリクエストに必要なパラメータは三つあります。
* secret
* app_id
* auth_code

**auth_code**は前段の手順で入手しています。**app_id**と**secret**は**My Apps**からアプリを選択して確認することができるので、事前に用意しておきましょう。

今回はcurlを利用して長期アクセストークンを取得してみました。
*※ 2022年11月現在、公式ドキュメントに記載されているURLが古い状態になっており、実際にリクエストを送信するとリダイレクトのレスポンスが返されます。以下は正しいURLに置き換えています。*
### リクエスト
```
curl https://biz-api.tiktok.com/open_api/v1.3/oauth2/access_token/ -v \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
        "secret": "SECRET",
        "app_id": "APP_ID",
        "auth_code": "AUTH_CODE"
      }'
```
### レスポンス
```
HTTPS/1.1 200 OK
{
  "message": "OK",
  "code": 0,
  "data": {
    "access_token": "xxxxxxxxxxxxx",
    "scope": [
      4
    ],
    "advertiser_ids": [
      "123456789",
      "123456781"
    ]
  },
  "request_id": "2020042715295501023125104093250"
```
このレスポンスに含まれるaccess_tokenが長期アクセストークンです。

`※ 長期アクセストークンに有効期限はありません。`
`※ 広告主は認可を取り消すことが可能です。`

# APIを利用する
これでAPIを利用するために必要な要素が全て揃いましたので、実際にAPIを利用してみます。
## APIの簡単紹介
まず最初にAPIの要点を簡単に紹介させていただきます。
### 2種類の取得方法
このAPIには2種類のレポートの取得方法があります。
* [同期レポート](https://ads.tiktok.com/marketing_api/docs?id=1738864778664961)
* [非同期レポート](https://ads.tiktok.com/marketing_api/docs?id=1738864800380930)

公式ドキュメントによると、*最近のデータを取得したいのか、過去のデータを取得したいのかによって使い分ける* となっています。
これについて実際に試したところ、取得できるデータには以下のような違いが見られました。
* 同期レポートは直近10日間程度の期間のデータしか取得できない
* 同期レポートは無効化された広告のデータは含まれない
* **非同期レポートを利用するためには許可リストの申請が必要**
こちらは、My Appsの開発者アプリ詳細ページの許可リストで、非同期レポートを追加することで申請できるようです。

### 4種類のレポート
取得したいデータに応じて4種のレポートが用意されていますので、公式ドキュメントを参考に簡単に紹介しておきます。
* Basic report
キャンペーン、広告グループ、広告、広告アカウントの4つのレベルで支出およびパフォーマンスデータを取得できます。
* Audience report
年齢、性別、国/地域、興味などの視聴者属性によって、支出やパフォーマンスのデータをグループ化することができます。
*※ 視聴者レポートのデータは、リアルタイムデータではありません。視聴者データの処理には10～12時間の待ち時間が発生します。*
* Playable ads report
プレイアブル広告に関するデータを取得するために使用します。
* DSA (DPA) report
ダイナミック・ショーケース広告（ダイナミック・プロダクト広告）に関するデータを取得するために使用します。

`※ オークション広告データは、4つのレポートタイプすべてに対応しています。`
`※ 予約広告データは、基本レポート（キャンペーン、広告グループ、広告、広告アカウントレベル）のみに対応しています。`

## 非同期レポートを取得する
今回はより手順が複雑な非同期レポートの取得を行います。
同期レポートは単一のAPIで取得できる一方で、非同期レポートでは以下の三つのAPIを順番に使用します。
1. [タスク作成](https://ads.tiktok.com/marketing_api/docs?id=1740302766489602)
1. [タスクチェック](https://ads.tiktok.com/marketing_api/docs?id=1740302781443073)
1. [タスクダウンロード](https://ads.tiktok.com/marketing_api/docs?id=1740302808815618)

APIの利用にはこれまでに準備したデータと、その他のパラメータを指定するのみであるため、特に特別な実装はありません。簡単です。

### 1. タスク作成
非同期レポートでは、まずレポートタスクの作成をリクエストする必要があります。
#### リクエスト
##### 基本情報

| 項目 | 値 |
|---:|:---|
| URI | https\://biz-api.tiktok.com/open_api/v1.3/report/task/create/ |
| METHOD | POST |

##### HTTPヘッダ
| key | value |
|---:|:---|
| Access-Token | **長期アクセストークン** |

##### リクエストパラメータ
代表的なものを記載します。詳細については公式ドキュメントをご覧ください。
| key | value |
|---:|:---|
| advertiser_id | 広告アカウントのIDを指定します |
| start_date | 集計期間の指定です。<br>"2022-11-01" のようなフォーマットで指定します。 |
| end_date | 集計期間の指定です。<br>"2022-11-01" のようなフォーマットで指定します。 |
| report_type | 前述の4種のレポートの種別を指定します。 |
| dimensions | グルーピングの条件を指定します。<br>'["stat_time_day", "platform", "adgroup_id"]' のような文字列です。 |
| data_level | 照会したいレポートのデータのレベル（粒度のような）を指定します。<br>report_typeがBASIC、AUDIENCEまたはCATALOGの場合は必須です。 |
| metrics | レポートに含めたいメトリクスを指定します。<br>'["spend", "impressions", "clicks", "conversion"]' のような文字列です。 |
| output_format | 結果のフォーマットを指定します。<br>CSV_STRING, CSV_DOWNLOAD, XLSX_DOWNLOADのいずれかを指定します。 |

**output_format** については、基本的には *CSV_STRING* で問題ないと思います（デフォルト値です）。*CSV_DOWNLOAD*　や *XLSX_DOWNLOAD* を指定した場合は、後述の**ダウンロードのAPIのレスポンスがJsonになり、Json内部にダウンロード先URLが含まれる形になります**。**CSV_STRINGの場合は、ダウンロードのAPIのレスポンスそのものがCSVになります**。

#### レスポンス
重要なのは **task_id** です。このIDを用いてその後のリクエストを行うため、保存しておく必要があります。
APIの結果は **code** 値で返されます。詳しくは[公式ドキュメント](https://ads.tiktok.com/marketing_api/docs?id=1737172488964097)を参照してください。

```http
HTTPS/1.1 200 OK
{
    "message": "OK",
    "code": 0,
    "data": {
        "task_id": "69334"
    },
    "request_id": "202102260452050101151531921A10A657"
}
```

### 2. タスクチェック
タスクの完了を待つため、このAPIを利用して完了状態を確認します。
実際に試したところ、（データ量などによって前後するかと思いますが）**手元の環境では3分程度の時間を要しました。**
そのため、あまり待ち続けるのも処理として無駄になると思われますので、あらかじめ数分後にリクエストするようにしたほうが効率的かもしれません。
もちろんTikTok側のことを考え、チェックする際のインターバルには注意しましょう。

#### リクエスト
##### 基本情報

| 項目 | 値 |
|---:|:---|
| URI | https\://biz-api.tiktok.com/open_api/v1.3/report/task/check/ |
| METHOD | GET |

##### HTTPヘッダ
| key | value |
|---:|:---|
| Access-Token | **長期アクセストークン** |

##### リクエストパラメータ
代表的なものを記載します。詳細については公式ドキュメントをご覧ください。
| key | value |
|---:|:---|
| advertiser_id | 広告アカウントのIDを指定します |
| task_id | 作成時のレスポンスに含まれるtask_idを使用します |

#### レスポンス
重要なのは **status** です。
**QUEUING, PROCESSING, SUCCESS, FAILED**　の4つのステータスが存在しています。SUCCESSであれば完了とみなせます。

```http
HTTPS/1.1 200 OK
HTTPS/1.1 200 OK
{
    "message": "OK",
    "code": 0,
    "data": {
        "status": "SUCCESS",
        "message": ""
    },
    "request_id": "2021022606090301011517615608212B1C"
}
```

### 2. タスクダウンロード
このAPIを利用することで、完了したレポートを取得できます。
**レスポンスのフォーマットは、タスク作成時のoutput_formatの指定により異なる**点に注意が必要です。

#### リクエスト
##### 基本情報

| 項目 | 値 |
|---:|:---|
| URI | https\://biz-api.tiktok.com/open_api/v1.3/report/task/download/ |
| METHOD | GET |

##### HTTPヘッダ
| key | value |
|---:|:---|
| Access-Token | **長期アクセストークン** |

##### リクエストパラメータ
代表的なものを記載します。詳細については公式ドキュメントをご覧ください。
| key | value |
|---:|:---|
| advertiser_id | 広告アカウントのIDを指定します |
| task_id | 作成時のレスポンスに含まれるtask_idを使用します |

#### レスポンス
**CSV_STRING** を指定していた場合は、そのままCSVの中身が返却されます。
そうでない場合はJsonがレスポンスされます。こちらについても[公式ドキュメント](https://ads.tiktok.com/marketing_api/docs?id=1740302808815618)を参照ください。

# まとめ
情報量は多いように見えますが、TikTokのAPIは他のプラットフォームと比較しても、シンプルなほうなのではないかな？と感じました。いかがだったでしょうか？
ただ、非同期レポートの最終的なレポート結果のフォーマットの選択肢として、Jsonも選べたらいいなーと少し思っています。

明日は[@Portier](https://qiita.com/Portier)さんです。