【GAS】Yahoo広告の運用データをスプレッドシートに自動取得する方法(v19対応)
2025年更新:本記事はv19対応の解説に更新しました。コードサンプルは順次更新予定です。
Yahoo!広告のインプレッション数・クリック数・コンバージョン数・費用などの運用データを、毎日手作業で確認するのは手間がかかります。本記事では GAS(Google Apps Script) を使って、Yahoo!広告のデータをスプレッドシートへ自動で取得・蓄積する方法を解説します。
Yahoo!広告 APIの最新バージョンは v19 です。旧バージョン(v7など)はサポートが終了しているため、これから実装する方はv19をご利用ください。
詳細な仕様はこちらの公式ドキュメントを参照してください。
その他の広告媒体の取得方法
目次
Yahoo!広告アプリケーションの登録
Yahoo!広告 API管理ツールにアクセスし、広告運用を行っているYahoo!ビジネスIDでログインします。
「アプリケーションを追加」からアプリケーションを新規登録します。
登録画面で必要事項を入力して確認を選択します。リダイレクトURIには「oob」を入力してください。
登録完了後、クライアントID と クライアントシークレット が表示されるのでメモしておきます。

認証コードの取得
以下の形式でURLを作成してブラウザでアクセスします。
CLIENT_ID:登録したクライアントIDREDIRECT_URI:アプリケーション登録時に設定したURLTHIS_VALUE_SHOULD_BE_UNIQUE_PER_REQUEST:任意の文字列(乱数でOK)
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
ブラウザでアクセスしてアクセス許可を承認すると、認可コードが画面に表示されます。この値をメモします。


アクセストークン・リフレッシュトークンの取得
ターミナルから下記のcurlコマンドを実行します。
CLIENT_ID:クライアントIDCLIENT_SECRET:クライアントシークレットREDIRECT_URI:登録時に設定したURLAUTH_CODE:先ほど取得した認可コード
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時間で失効 するため、GASではリフレッシュトークンを使って毎回新しいアクセストークンを取得する実装にします。
スプレッドシートとGASの作成
スプレッドシートを作成し、「db」という名前のシートを追加します。
「ツール」→「スクリプトエディタ」からGASを作成します。
✅ 以下のコードは v19 対応版です。clientId・clientSecret・refreshToken・mccAccountId・targetAccountId を設定してご利用ください。
/**
* Yahoo!広告 検索広告 API v19 対応版
*/
function main() {
const ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('db');
if (!ss) throw new Error("シート 'db' が見つかりません。");
// --- 設定情報 ---
const clientId = "****";
const clientSecret = "****";
const refreshToken = "****";
// MCCアカウントを利用する場合
const mccAccountId = "****"; // MCCアカウントID(x-z-base-account-id用)
const targetAccountId = "****"; // データを取得したい広告アカウントID
// 1. アクセストークン取得 (POST)
const accessToken = yahooAdLogin(clientId, clientSecret, refreshToken);
// 2. レポート作成ジョブの追加 (v19)
const reportName = "Search_Report_" + Utilities.formatDate(new Date(), "JST", "yyyyMMdd_HHmmss");
const createReportResponse = yahooAdCreateSearchReport(accessToken, mccAccountId, targetAccountId, reportName);
const reportJobId = createReportResponse.rval.values[0].reportDefinition.reportJobId;
console.log(`Search Report Job Created: ${reportJobId}`);
// 3. レポート作成完了までループで確認 (最大2分)
let isCompleted = false;
for (let i = 0; i < 12; i++) {
isCompleted = yahooAdCheckSearchReportStatus(accessToken, mccAccountId, targetAccountId, reportJobId);
if (isCompleted) break;
console.log("レポート作成中... (10秒待機)");
Utilities.sleep(10000);
}
if (!isCompleted) throw new Error("レポート作成がタイムアウトしました。");
// 4. レポートの取得とパース
const reportData = yahooAdDownloadSearchReport(accessToken, mccAccountId, targetAccountId, reportJobId);
if (reportData && reportData.length > 0) {
const lastRow = ss.getRange("B:B").getValues().filter(String).length;
const targetRow = lastRow + 1;
ss.getRange(targetRow, 1, reportData.length, reportData[0].length).setValues(reportData);
console.log(`${reportData.length}件のデータを追記しました。`);
} else {
console.log("対象期間にデータがありませんでした。");
}
}
/** 共通ヘッダー生成 */
function getSearchHeaders(accessToken, mccAccountId) {
return {
'Authorization': `Bearer ${accessToken}`,
'x-z-base-account-id': mccAccountId,
'Content-Type': 'application/json'
};
}
/** 認証: アクセストークン取得 */
function yahooAdLogin(clientId, clientSecret, refreshToken) {
const url = "https://biz-oauth.yahoo.co.jp/oauth/v1/token";
const options = {
method: 'post',
payload: {
grant_type: "refresh_token",
client_id: clientId,
client_secret: clientSecret,
refresh_token: refreshToken,
}
};
const response = UrlFetchApp.fetch(url, options);
return JSON.parse(response.getContentText()).access_token;
}
/** 検索広告レポート作成 (v19) */
function yahooAdCreateSearchReport(accessToken, mccAccountId, targetAccountId, reportName) {
const url = "https://ads-search.yahooapis.jp/api/v19/ReportDefinitionService/add";
const payload = {
accountId: targetAccountId,
operand: [{
reportName: reportName,
reportType: "CAMPAIGN",
reportDateRangeType: "YESTERDAY",
reportDownloadFormat: "CSV",
reportDownloadEncode: "UTF8",
reportLanguage: "JA",
reportCompressType: "NONE",
reportIncludeDeleted: "TRUE",
fields: [
"CAMPAIGN_NAME", "DAY", "CLICKS", "CONVERSIONS", "COST",
"IMPS", "CLICK_RATE", "AVG_CPC", "CONV_RATE", "CONV_VALUE"
]
}]
};
const options = {
method: 'post',
headers: getSearchHeaders(accessToken, mccAccountId),
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(url, options);
const json = JSON.parse(response.getContentText());
if (response.getResponseCode() !== 200) throw new Error("Create Error: " + response.getContentText());
return json;
}
/** 検索広告レポートステータス確認 (v19) */
function yahooAdCheckSearchReportStatus(accessToken, mccAccountId, targetAccountId, reportJobId) {
const url = "https://ads-search.yahooapis.jp/api/v19/ReportDefinitionService/get";
const options = {
method: 'post',
headers: getSearchHeaders(accessToken, mccAccountId),
payload: JSON.stringify({ accountId: targetAccountId, reportJobIds: [reportJobId] })
};
const response = UrlFetchApp.fetch(url, options);
const status = JSON.parse(response.getContentText()).rval.values[0].reportDefinition.reportJobStatus;
if (status === "COMPLETED") return true;
if (status === "FAILED") throw new Error("レポート作成失敗");
return false;
}
/** 検索広告レポートダウンロードと整形(最適化版) */
function yahooAdDownloadSearchReport(accessToken, mccAccountId, targetAccountId, reportJobId) {
const url = "https://ads-search.yahooapis.jp/api/v19/ReportDefinitionService/download";
const options = {
method: 'post',
headers: getSearchHeaders(accessToken, mccAccountId),
payload: JSON.stringify({ accountId: targetAccountId, reportJobId: reportJobId })
};
const response = UrlFetchApp.fetch(url, options);
const csvData = Utilities.parseCsv(response.getContentText());
if (csvData.length <= 1) return [];
csvData.shift();
return csvData.filter(row =>
row.length > 0 && row[0] !== "" && row[0] !== "Total" && row[0] !== "合計"
).map(row => [
row[0], row[1],
Number(row[2]) || 0, Number(row[3]) || 0, Number(row[4]) || 0,
Number(row[5]) || 0, row[6],
Number(row[7]) || 0, row[8],
Number(row[9]) || 0
]);
}
取得期間の設定について
reportDateRangeType の値を変更することで取得対象期間を切り替えられます。
| TODAY | 本日 |
| YESTERDAY | 昨日 |
| LAST_7_DAYS | 本日を除く過去7日間 |
| LAST_14_DAYS | 本日を除く過去14日間 |
| LAST_30_DAYS | 本日を除く過去30日間 |
| LAST_WEEK | 先週の月曜日〜日曜日 |
| LAST_BUSINESS_WEEK | 先週の月曜日〜金曜日(5営業日) |
| THIS_MONTH | 当月(本日含む) |
| LAST_MONTH | 前月 |
| ALL_TIME | 取得可能な全期間 |
実行方法
GASのエディタで main 関数を選択して「実行」ボタンを押します。初回はGoogleアカウントの承認が必要です。
実行が完了すると、「db」シートに前日分のキャンペーンデータが1行追加されます。毎日自動で取得したい場合は、トリガーを設定して定期実行してください。
- 「トリガー」→「トリガーを追加」
- 関数:
main - イベントのソース:時間主導型
- 時間の間隔:日タイマー(例:午前6〜7時)
よくある質問
v7のコードをv19に移行するには?
APIエンドポイントの /api/v7/ の部分を /api/v19/ に変更します。レスポンスの構造に変更がある場合は公式のマイグレーションガイドを参照してください。
エラー「HttpRequestError」が出る場合は?
アクセストークンの有効期限(1時間)が切れている可能性があります。リフレッシュトークンを使って新しいアクセストークンを取得してから再実行してください。また、クライアントID・シークレット・アカウントIDの設定値を再確認してください。
取得できるデータ項目を増やすには?
fields 配列に項目名を追加します。利用可能なフィールド一覧は公式APIリファレンスで確認できます。
スプレッドシートのシート名を変えたい場合は?
コード冒頭の getSheetByName('db') の 'db' を任意のシート名に変更してください。






ディスカッション
コメント一覧
記事参考にさせて頂きました。
実際に導入してみて動いたのですが、30日分の過去データを取得するにはどのようにしたらいいか教えて頂けないでしょうか。
reportDateRangeTypeで取得するデータを変更はできたのですが、取り出すことができず躓いております。
コメントありがとうございます。
“YESTERDAY” を “LAST_30_DAYS” にしていただければ
過去30日分の期間合計データを取得できます。
デイリーのデータを取得したい場合は
“fields”に”DAY”を追加することで日別データが取得できます。
はじめまして!
アクセストークン・リフレッシュトークンの取得で詰んでいます。
$ {“error”:”invalid_request”}
設定を見直しているのですが、以下のリダイレクトURIは自分のサイトURLではなく「oob」なのでしょうか?「oob」だと「リダイレクト後、URLバーに表示されているcode=AUTH_CODEのAUTH_CODEが認可コードになるので値をメモします。」でリダイレクトされなかったのですが…。
>登録画面で必要事項を入力して確認を選択します。リダイレクトURIには「oob 」を入力してください。
>リダイレクト後、URLバーに表示されているcode=AUTH_CODEのAUTH_CODEが認可コードになるので値をメモします。
ご質問ありがとうございます。
仕様が変わっておりましたので一部記事を修正いたしました。
WEBアプリ等で認可コードを取得したい場合は、リダイレクトURIにWEBアプリ等のURIを設定します。
今回は認可コードを取得するだけでいいので、oobと設定しブラウザ上に表示され認可コードを取得します。
https://developer.yahoo.co.jp/yconnect/v1/server_app/explicit/authorization.html
記事参考にさせていただいております。
10行目の
const accountId = “****”; // 広告アカウントID
の箇所に有力するアカウントIDですが、こちらはYahooビジネスマネージャーにログインする際のログインIDでお間違いないでしょうか?
ご質問ありがとうございます。
広告管理画面で表示される広告アカウントのIDになります。
はじめまして!
初心者なのですが、最後に記載のあったスクリプトをコピペして実行すると下記のようなエラーが出てしまします。
=======================
TypeError: Cannot read property ‘getRange’ of null
(匿名) @ コード.gs:31
(匿名) @ コード.gs:28
main @ コード.gs:25
=======================
何が原因か理解できず、どこを修正すれば良いかご教示頂けないでしょうか?
ご質問ありがとうございます。
おそらく「db」シートを作成されていないのではないかと思いますのでスプレッドシートで「db」という名前のシートを作成実行してみてください。
初めまして。こちらの記事を参考にさせていただき、Yahoo検索広告の入力自動化に成功しました!
ありがとうございます!
現在こちらを元にYahooディスプレイ広告の入力自動化も試しており、もしご存知でしたら下記について教えていただきたいです。お手隙でよろしくお願いいたします。
【困りごと】
Yahooディスプレイ広告APIへのリクエストが400になる
【試したこと】
記事のスクリプト内の70行目などの検索広告APIの記述部分をたとえば下記のようにディプレイ広告に変更しました。それ以外のheadersなどの書き方は変えておりません。
https://ads-display.yahooapis.jp/api/v7/ReportDefinitionService/add
【エラー】
Exception: Request failed for https://ads-display.yahooapis.jp returned code 400. Truncated server response: {“rid”:”*****************”,”errors”:[{“code”:”0005″,”message”:”Bad request.”,”details”:[]}]} (use muteHttpExceptions option to examine full response)
エラーは記事のスクリプトでいう71行目の箇所で発生し、アクセストークンが無効なのかheaderの書き方が検索広告APIと異なっているかなどの線で調査をしております。
【補足】
自分はスクリプト内でアカウントIDごとに検索広告かディスプレイ広告かをフラグで付与し、同じアクセストークンを使ってURLなどのみを変更してそれぞれの広告APIへリクエストをしております。
検索広告のアカウントIDの際は問題なく通るのでアクセストークン自体は機能していそうです。
もし何かご存知でしたらお手隙でご確認いただけますと幸いです。
よろしくお願いいたします。
コメントありがとうございます!
ディスプレイ広告はリクエストデータが異なります。
Yahoo!ディスプレイ広告の記事を投稿しましたのでこちらを参考にしてください。
https://next-k.site/blog/archives/2022/12/11/981
お気軽にご質問いただければ幸いです。
ご返信ありがとうございます!
また、ディスプレイ広告に関する記事のご投稿ありがとうございます!早速参考にさせていただきます!