Yahoo!広告APIによる広告パフォーマンス計測の自動化

# はじめに
広告運用を行なっている方はあるあるだと思うのですが、パフォーマンスをチェックするために、日々各媒体の管理画面を見にいくのは骨が折れる作業です。
そこで今回はYahoo!広告APIとGoogle SpreadSheetsを使って、Yahoo検索広告とYahooディスプレイ広告のデータを自動的に取得する方法をご紹介します。

# Yahoo!広告APIとは？
従来利用されていたYahoo!プロモーション広告APIがリニューアルされて、Yahoo!広告APIとして生まれ変わりました。
[Yahoo!広告APIのリリースと、現行APIへの新規利用受付の終了について](https://promotionalads.yahoo.co.jp/support/release/727936.html)

Yahoo!広告APIを利用するためには、[申し込み手順](https://ads-developers.yahoo.co.jp/developercenter/ja/startup-guide/apply-api-use.html)に従い、利用申請を行う必要があります。

# アプリケーションの登録
- [Yahoo!広告 API管理ツール](https://connect-business.yahoo.co.jp/cooperation/)にアクセスして、広告運用を行なっているYahoo!ビジネスIDでログインします。
- 登録アプリケーションの画面で登録ボタンを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603058/24b9a04c-6944-ef08-60d6-189612741893.png)

- 登録画面で必要事項を入力して確認を選択します。リダイクレイトURIには、アクセス可能な任意なURL（例：https://qiita.com ）を入力してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603058/aa050f8d-c0ae-b9b8-e5b9-0d711d9cd737.png)

- 登録が完了したら下記のようにアプリケーションの情報が表示されるため、**クライアントID**と**クライアントシークレット**をメモします。
![yahoo_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603058/e27e6fa6-8120-008d-b7c2-85344970157f.png)

# 認可コードの取得
- 下記のURLを作成します。
    - `CLIENT_ID`：冒頭でメモしたクライアントID
    - `REDIRECT_URI `：アプリケーションの登録で設定したURL
    - `THIS_VALUE_SHOULD_BE_UNIQUE_PER_REQUEST `：任意の文字列（※[乱数](https://tomari.org/main/java/password.html)でOK）

```zsh

https://biz-oauth.yahoo.co.jp/oauth/v1/authorize?response_type=code
&client_id=CLIENT_ID
&redirect_uri=REDIRECT_URI
&scope=yahooads
&state=THIS_VALUE_SHOULD_BE_UNIQUE_PER_REQUEST
```

- 作成したURLをブラウザで開くと、Yahoo!ビジネスIDのログインを求められるため、ログインします。
![yahoo_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603058/ca80acf7-d4b2-1acb-e6b4-013fe8d99442.png)

- ログインに成功すると、リダイレクトURIに設定したページがブラウザで表示されます。URLバーに出力されているcode=AUTH_CODEの`AUTH_CODE`が認可コードになるので値をメモします。

# アクセストークン・リフレッシュトークンの取得
- ターミナルから下記のリクエストを実行します。
    - `CLIENT_ID`：冒頭でメモしたクライアントID
    - `CLIENT_SECRET`：冒頭でメモしたクライアントシークレット
    - `REDIRECT_URI `：アプリケーションの登録で設定したURL
    - `AUTH_CODE `：先ほど取得した認可コード

```zsh
curl -X GET \
https://biz-oauth.yahoo.co.jp/oauth/v1/token?grant_type=authorization_code
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&redirect_uri=REDIRECT_URI
&code=AUTH_CODE
```
- 下記のようにアクセストークンとリフレッシュトークンが返却されるので、それぞれの値をメモします。
    - アクセストークンは1時間で失効するため、リフレッシュトークンを使って都度で新しいアクセストークン
を発行する必要があります。

```json
{"access_token":"ACCESS_TOKEN",
"expires_in":"3600",
"token_type":"Bearer",
"refresh_token":"REFRESH_TOKEN"}
```

# レポートの登録
- ターミナルから下記のリクエストを実行して、データダウンロード用のレポートを登録します。
- `operand`内でレポートの出力項目、出力期間など詳細な条件の設定が可能です。詳しくは[Yahoo!広告APIリファレンス](https://yahoojp-marketing.github.io/ads-display-api-documents/?lang=ja&v=1)の`ReportDefinitionService/add`を参照してください。
    - Yahoo検索広告とYahooディスプレイ広告で、URLおよび設定可能な項目が異なります。

```zsh
curl -X POST \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"operand":
  [{
    "accountId": ACCOUNT_ID,
    "fields": [REPORT_FIELDS],
    "reportCompressType": "NONE",
    "reportDateRangeType": "ALL_TIME",
    "reportDownloadEncode": "UTF-8",
    "reportDownloadFormat": "CSV",
    "reportIncludeDeleted": "TRUE",
    "reportLanguage": "JA",
    "reportName": REPORT_NAME,
    "reportType": REPORT_TYPE
  }]}' \
"https://ads-search.yahooapis.jp/api/v1/ReportDefinitionService/add"
```

- jsonが返却されるため、その中に記載された`reportJobId`の値をメモします。 

```json
{
   "errors":null,
   "rid":"...",
   "rval":{
      "values":[
         {
            "errors":null,
            "operationSucceeded":true,
            "reportDefinition":{
               "accountId":ACCOUNT_ID,
               "fields":[...],
               "reportJobId":ここに表示された値をメモ,
               ...
            }
         }
      ]
   }
}
```

# Googleスプレッドシートへの出力
- Googleスプレッドシートのメニューから「ツール > スクリプト エディタ」を選択します。
- 下記のコードを貼り付け、ここまでの手順で得られた設定値を入力します。

```js
// Yahoo!広告の設定
const URL_TOKEN = 'https://biz-oauth.yahoo.co.jp/oauth/v1/token';
const URL_API = 'https://ads-search.yahooapis.jp/api/v1';
const CLIENT_ID = 'xxxxx';
const CLIENT_SECRET = 'xxxxx';
const REFRESH_TOKEN = 'xxxxx';
const ACCOUNT_ID = xxxxx;
const REPORT_JOB_ID = xxxxx;

// 出力先のシート名
var sheet_name = 'xxxxx';

function updateYahooReport() {
    var access_token = getAccessToken(REFRESH_TOKEN);
    var data = donwloadReport(URL_API, access_token, ACCOUNT_ID, REPORT_JOB_ID);
    updateCsv(sheet_name, data);
}

function updateCsv(sheet_name, data) {
  var values = Utilities.parseCsv(data);
  var this_sheet = SpreadsheetApp.getActive().getSheetByName(sheet_name);
  this_sheet.clearContents();
  this_sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}

function getAccessToken(refresh_token) {
    var payload = {
        grant_type: 'refresh_token',
        client_id: CLIENT_ID,
        client_secret: CLIENT_SECRET,
        refresh_token: refresh_token
    };
    var params = {
        payload : payload
    };

    var response = UrlFetchApp.fetch(URL_TOKEN, params);
    var response_body = JSON.parse(response.getContentText());

    return response_body['access_token'];
}

function downloadReport(url, access_token, account_id, report_jod_id) {
    var headers = {
        'Authorization': 'Bearer ' + access_token
    };
    var payload = {
        accountId: account_id,
        reportJobId: report_jod_id
    };
    var params = {
        method : 'post',
        contentType: 'application/json',
        headers: headers,
        payload: JSON.stringify(payload)
    };

    var response = UrlFetchApp.fetch(url + '/ReportDefinitionService/download', params);
    return response;
}
```

- `updateYahooReport` の関数を選択して実行すると、指定したシート名に結果が出力されます。
![capture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603058/d14cb29a-64e9-d08b-bca2-7d572c740c47.png)

# 定期的な出力
- GASのスケジューラー機能を利用することで、定期的にデータを更新することができます。スケジューラー機能は[こちらの記事](https://ikuten.com/gas_trigger)を参考にして下さい。

# さいごに
- Yahoo!広告はFacebook広告やGoogle広告と異なり、Yahooは明示的にレポートを登録しないとデータが出力できない点が独特でした。
- 媒体管理画面と同様、Yahoo検索広告とYahooディスプレイ広告でAPI仕様が異なるので注意が必要です。（いつの日か統合されるのだろうか、、、）