何を作ったか
Yahoo広告のレポート作成を自動で行い、スラックチャンネルに投稿するGASスクリプトを作りました。
サンプルのコードでは、広告グループごとに費用、表示回数、クリック数、コンバージョン数を集計し、週次で以下のような自動レポートをスラックチャンネルに自動投稿します。
【Yahoo検索広告】広告グループ〇〇の週報です。
先週(月-日)の実績→費用:14074円、表示回数:23926回、クリック数:196回、コンバージョン数:2
前提となる知識
- Yahooリスティング広告
- Google Apps Scriptの使用方法
- Slack Webhook URLの設定方法
API利用開始までの流れ
Yahoo広告APIの利用申請
こちらのページから、利用を申し込む必要があります。
利用申請を出してから許可が降りるまで、数日かかるとの記載がありましたが、私の場合は数分で利用許可のメールが届きました。
アプリケーションの登録
こちらのページの手順に従い、アプリケーションを登録します。
クライアントIDとクライアントシークレットを控えておきます。
初回アクセストークンとリフレッシュトークンの取得
こちらのページの手順に従い、トークンを取得します。
アクセストークンの有効期限は1時間です。リフレッシュトークンは、アプリケーションの承認を解除するまで有効です。
ソースコード
Yahoo広告APIから、コスト、インプレッション、クリック数、コンバージョン数などの値を取得するには、レポート作成APIを叩いた後、生成されたレポートをダウンロードする必要があります。
レポートの生成は非同期処理となり、少し時間がかかります。本スクリプトでは10秒のsleep処理を入れて、レポート生成完了を待っています。
全体の処理
メインの関数です。最終的には、この関数をGASのトリガーに設定します。
function main() {
// 各種設定
const clientId = "YAHOO_AD_API_CLIENT_ID" // クライアントID
const clientSecret = "YAHOO_AD_API_CLIENT_SECRET"; // クライアントシークレット
const refreshToken = "YAHOO_AD_API_REFRESH_TOKEN"; // リフレッシュトークン
const accountId = "YAHOO_AD_ACCOUNT_ID"; // 広告アカウントID
const slackUrl = "SLACK_NOTIFICATION_URL"; // slack webhook url
// アクセストークン取得
const loginResponse = yahooAdLogin(clientId, clientSecret, refreshToken);
const accessToken = loginResponse.access_token;
// YAHOO広告レポートを作成し、作成ジョブのIDを取得
const reportName = Moment.moment().format('YYYYMMDD_HHmmss');
const createReportResponse = yahooAdCreateReport(accessToken, accountId, reportName);
const reportJobIds = createReportResponse.rval.values.map(item => Number(item.reportDefinition.reportJobId));
// レポート作成完了まで10秒間待つ
Utilities.sleep(10000);
reportJobIds.forEach(reportJobId => {
// レポートの取得
const downloadResponse = yahooAdDownloadReport(accessToken, accountId, reportJobId);
// 広告グループごとのレポートをスラックに通知
downloadResponse.forEach(report => {
const message1 = `【Yahoo検索広告】${report.adGroupName}の週報です。`
const message2 = `先週(月-日)の実績→費用:${report.cost}円、表示回数:${report.impressions}回、クリック数:${report.clicks}回、コンバージョン数:${report.conversions}`;
UrlFetchApp.fetch(slackUrl, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify({ text: message1 + message2 }),
muteHttpExceptions: true,
});
});
});
}
Yahoo広告APIのコール部
アクセストークンの取得APIに加え、レポート作成API と レポートダウンロードAPI の2つのYahoo広告APIを利用します。
// アクセストークン取得
function yahooAdLogin(clientId, clientSecret, refreshToken) {
const url = "https://biz-oauth.yahoo.co.jp/oauth/v1/token";
const httpResponse = UrlFetchApp.fetch(url, {
method: 'get',
payload: {
grant_type: "refresh_token",
client_id: clientId,
client_secret: clientSecret,
refresh_token: refreshToken,
},
});
const status = httpResponse.getResponseCode();
if (status !== 200) {
throw 'HttpRequestError';
}
const response = JSON.parse(httpResponse.getContentText());
return response;
}
// 広告レポートを作成するAPIのコール
function yahooAdCreateReport(accessToken, accountId, reportName) {
const url = "https://ads-search.yahooapis.jp/api/v3/ReportDefinitionService/add";
const httpResponse = UrlFetchApp.fetch(url, {
method: 'post',
contentType: 'application/json',
headers: {
'Authorization': `Bearer ${accessToken}`,
},
payload: JSON.stringify({
accountId,
operand: [
{
fields: [
"ADGROUP_ID", // 広告グループID
"ADGROUP_NAME", // 広告グループ名
"COST", // 費用
"IMPS", // 表示回数
"CLICKS", // クリック数
"CLICK_RATE", // クリック率
"AVG_CPC", // 平均クリック単価
"CONVERSIONS", // コンバージョン数
"CONV_RATE", // コンバージョン率
"CONV_VALUE", // コンバージョン値
],
reportCompressType: "NONE", // レポートファイルは圧縮しない
reportDateRangeType: "LAST_7_DAYS", // 過去7日間(当日含まない)の期間指定
reportDownloadEncode: "UTF-8",
reportDownloadFormat: "CSV",
reportIncludeDeleted: "TRUE",
reportIncludeZeroImpressions: "FALSE",
reportLanguage: "JA",
reportName,
reportType: "ADGROUP" // 広告グループごとに集計したレポートを出力する
}
],
}),
});
const status = httpResponse.getResponseCode();
if (status !== 200) {
throw 'HttpRequestError';
}
const response = JSON.parse(httpResponse.getContentText());
return response;
}
// 広告レポート(CSV形式)取得APIをコールし、結果をパースする関数
function yahooAdDownloadReport(accessToken, accountId, reportJobId) {
const url = "https://ads-search.yahooapis.jp/api/v3/ReportDefinitionService/download";
const httpResponse = UrlFetchApp.fetch(url, {
method: 'post',
contentType: 'application/json',
headers: {
'Authorization': `Bearer ${accessToken}`,
},
payload: JSON.stringify({
accountId,
reportJobId,
}),
});
const status = httpResponse.getResponseCode();
if (status !== 200) {
throw 'HttpRequestError';
}
const response = httpResponse.getContentText();
const lines = response.split('\n');
// 対象期間に費用の発生した広告グループが存在しない場合、空配列を返す
if (lines.length === 3) {
return [];
}
// 最初の行:ヘッダー行、最後から2番目の行:合計の行、最後の行:空行 のため、sliceで除外する
return lines.slice(1, -2).map((line) => {
const data = line.split(',');
return {
adGroupId: String(data[0]),
adGroupName: String(data[1]),
cost: Number(data[2]),
impressions: Number(data[3]),
clicks: Number(data[4]),
clickRate: Number(data[5]),
cpc: Number(data[6]),
conversions: Number(data[7]),
conversionRate: Number(data[8]),
conversionValue: Number(data[9]),
};
});
}
まとめ
Web広告の運用では、タイムリなーレポートの作成を要求されます。
これらのレポーティング作業をマニュアルで行うのは非常に骨が折れますね。
APIを活用してレポーティングを自動化し、作業時間を短縮していきたいですね。