こんにちは、中都です。
Google広告の管理画面を開いて、昨日の広告費やクリック数をスプレッドシートへ転記する。毎朝やっていると、短い作業でも地味に時間を取られますよね。僕も、こうした運用をしている会社を支援してきました。
Google広告スクリプトを使うと、広告データをスプレッドシートへ出力し、毎日決まった時間帯に更新できます。今回は、出力先の準備、スクリプトの設定、初回実行、定期更新までを順に説明します。まずは1つの広告アカウントのデータを取り出し、管理画面と数字を照合するところから始めましょう。
この記事にスクリプトの全文を載せました。出力用の空のスプレッドシートを用意すれば、コードのコピーから設定まで、このページで進められます。出力先を用意済みの方は、スクリプト全文へ進んでください。
動画でも解説しています
毎日の転記やレポートづくりで、こんな課題はありませんか?
数字を考える前の準備に、時間が取られる
- 毎朝、管理画面の数字をスプレッドシートへコピーしている。
- 転記漏れや貼り付けミスがないか、同じ数字を何度も見比べている。
- 上司から「先月と比べてどう?」と聞かれるたびに、データを集め直している。
数字を把握することは大事ですが、毎回同じ操作をするだけの時間は、できれば減らしたいですよね。データを集める作業を仕組みにして、数字を見て考える時間を残しましょう。
この記事でできるようになること
- 自動出力:日付・キャンペーン名・費用・クリック数などを、専用のシートへ出力する。
- 毎日の更新:実行時間帯を設定し、更新できたかをログで確認する。
- 出力後の活用:集まった表をどう分析に使うかを知る。末尾では、AIに接続して質問する方法も紹介します。
このあと、設定に使うコード全文と、作成・承認・出力結果の画像を見ながら進めます。初回はその場で出力を確認し、定期実行は翌日のログまで見るところをゴールにします。
使うのは、Google広告の「スクリプト」機能
Google広告スクリプトは、Google広告の管理画面でJavaScriptを実行する機能です。広告の設定変更にも使えますが、ここで行うのは実績データを取得して、スプレッドシートへ書き出す処理です。スプレッドシート側の「拡張機能→Apps Script」にコードを貼る手順とは、実行する場所が違います。
スクリプトからGoogleスプレッドシートを読み書きできることは、Googleの公式資料でも案内されています。
ただし、取得した数字がその瞬間の確定値になるわけではありません。コンバージョンの遅れやデータの再集計はあるので、転記の自動化と、数値の確認は分けて考えてください。
1. 出力先のスプレッドシートを用意する
Google広告とシートを扱えるアカウントで準備する
対象のGoogle広告アカウントでスクリプトを作成・承認できることと、出力先のスプレッドシートを編集できることを確認します。複数のGoogleアカウントを使っている方は、広告を開いているアカウントと、シートを開いているアカウントを見比べてください。
最初は既存の予算表に直接出力せず、専用の空のスプレッドシートを使います。出力処理でデータが更新されるため、手入力のメモや集計式を置くタブは分けておくと安心です。
「Google広告データ」と「出力ログ」の2つのタブを作る
Googleスプレッドシートを新規作成し、左下の「+」でタブを追加します。タブ名をそれぞれGoogle広告データと出力ログに変更してください。「Google」のGは大文字です。
1つ目に広告実績、2つ目に実行日時や取得結果を出力します。別の名前にする場合は、後でスクリプト内のタブ名も同じ表記へ変更します。
2. Google広告で新規スクリプトを作る
複数の広告アカウントを管理している場合は、まずデータを取得したい1つの広告アカウントへ切り替えます。そのアカウントの左メニューから「ツール」→「一括操作」→「スクリプト」へ進みます。画面の配置が違う場合も、「スクリプト」という項目を探してください。
「+」を押し、「新規スクリプト」を選びます。編集画面が開いたら、スクリプト名を「日次スプシ出力」など、自分が後で見て用途を分かる名前にします。
最初から入力されているひな形を、次に掲載したスクリプトの全文に置き換えます。貼り付けるのはコードの編集欄です。スクリプト名の入力欄と取り違えないようにしてください。
Google広告→スプレッドシートのスクリプト全文
以下が僕の用意したスクリプトです。「スクリプト全文を開く」を押し、function main()から、末尾のwriteLog関数を含む最後の}までコピーしてください。続いて、{スプシID}とタブ名を自分のものへ変更します。
取得データがあると「Google広告データ」タブの内容・書式を消して書き直します。手入力の予算やメモは別タブへ置き、「出力ログ」のタブも先に作ってから使ってください。
スクリプト全文を開く(151行)
function main() {
const SPREADSHEET_ID = '{スプシID}'; // ←スプシIDを入力してください
const SHEET_NAME = 'Google広告データ'; // ←タブ名を入力してください
const LOG_SHEET_NAME = '出力ログ';
const DAYS_AGO = 90;
// 取得する指標のカスタマイズ(不要な指標はfalseに変更)
const METRICS = {
impressions: true, // インプレッション
clicks: true, // クリック数
cost: true, // コスト
conversions: true, // コンバージョン数
search_impression_share: true, // 検索インプレッションシェア
average_cpc: true, // 平均CPC
ctr: true, // CTR(%)
cvr: true, // CVR(%)
cpa: true // CPA
};
const startTime = new Date();
let logMessage = '';
let status = '成功';
let errorDetail = '';
try {
const sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
const logSheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(LOG_SHEET_NAME);
const today = new Date();
const startDay = new Date();
startDay.setDate(today.getDate() - DAYS_AGO);
const formatDate = date => {
const yyyy = date.getFullYear();
const mm = ('0' + (date.getMonth() + 1)).slice(-2);
const dd = ('0' + date.getDate()).slice(-2);
return `${yyyy}-${mm}-${dd}`;
};
const startDate = formatDate(startDay);
const endDate = formatDate(today);
// 選択された指標に基づいてクエリを構築
let selectFields = ['segments.date', 'campaign.name'];
if (METRICS.impressions) selectFields.push('metrics.impressions');
if (METRICS.clicks) selectFields.push('metrics.clicks');
if (METRICS.cost) selectFields.push('metrics.cost_micros');
if (METRICS.conversions) selectFields.push('metrics.conversions');
if (METRICS.search_impression_share) selectFields.push('metrics.search_impression_share');
if (METRICS.average_cpc) selectFields.push('metrics.average_cpc');
if (METRICS.ctr) selectFields.push('metrics.ctr');
if (METRICS.cpa) selectFields.push('metrics.cost_per_conversion');
const query = `
SELECT ${selectFields.join(', ')}
FROM campaign
WHERE segments.date BETWEEN '${startDate}' AND '${endDate}'
ORDER BY segments.date ASC, campaign.name
`;
var report = AdsApp.report(query);
var rows = report.rows();
// ヘッダーを動的に構築
let headers = ['日付', 'キャンペーン名'];
if (METRICS.impressions) headers.push('インプレッション');
if (METRICS.clicks) headers.push('クリック数');
if (METRICS.cost) headers.push('コスト');
if (METRICS.conversions) headers.push('コンバージョン数');
if (METRICS.search_impression_share) headers.push('検索インプレッションシェア');
if (METRICS.average_cpc) headers.push('平均CPC');
if (METRICS.ctr) headers.push('CTR(%)');
if (METRICS.cvr) headers.push('CVR(%)');
if (METRICS.cpa) headers.push('CPA');
let data = [];
while (rows.hasNext()) {
var row = rows.next();
let rowData = [row['segments.date'], row['campaign.name']];
if (METRICS.impressions) rowData.push(row['metrics.impressions']);
if (METRICS.clicks) rowData.push(row['metrics.clicks']);
if (METRICS.cost) rowData.push(row['metrics.cost_micros'] / 1000000);
if (METRICS.conversions) rowData.push(row['metrics.conversions']);
if (METRICS.search_impression_share) rowData.push(row['metrics.search_impression_share']);
if (METRICS.average_cpc) rowData.push(row['metrics.average_cpc'] / 1000000);
if (METRICS.ctr) rowData.push(row['metrics.ctr'] * 100);
if (METRICS.cvr) {
const cvr = (row['metrics.conversions'] / row['metrics.clicks'] * 100) || 0;
rowData.push(cvr);
}
if (METRICS.cpa) rowData.push(row['metrics.cost_per_conversion'] / 1000000);
data.push(rowData);
}
if (data.length > 0) {
sheet.clear();
sheet.getRange(1, 1, 1, headers.length).setValues([headers]);
sheet.getRange(1, 1, 1, headers.length).setFontWeight('bold').setBackground('#f3f3f3');
sheet.getRange(2, 1, data.length, headers.length).setValues(data);
logMessage = `${data.length}行のデータを取得しました(${startDate}〜${endDate})`;
Logger.log(logMessage);
} else {
logMessage = '取得できるデータがありませんでした';
status = '警告';
Logger.log(logMessage);
}
// ログシートへの記録
writeLog(logSheet, startTime, startDate, endDate, data.length, status, logMessage, errorDetail);
} catch (error) {
status = '失敗';
errorDetail = error.toString();
logMessage = 'エラーが発生しました';
Logger.log(errorDetail);
// エラー時もログに記録
const logSheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(LOG_SHEET_NAME);
writeLog(logSheet, startTime, '', '', 0, status, logMessage, errorDetail);
}
}
function writeLog(logSheet, startTime, startDate, endDate, rowCount, status, message, errorDetail) {
// ログシートのヘッダーが存在しない場合は作成
if (logSheet.getLastRow() === 0) {
const logHeaders = ['実行日時', '取得期間(開始)', '取得期間(終了)', '取得行数', 'ステータス', 'メッセージ', 'エラー詳細'];
logSheet.getRange(1, 1, 1, logHeaders.length).setValues([logHeaders]);
logSheet.getRange(1, 1, 1, logHeaders.length).setFontWeight('bold').setBackground('#f3f3f3');
}
const endTime = new Date();
const executionTime = (endTime - startTime) / 1000; // 秒単位
const logData = [
Utilities.formatDate(startTime, 'Asia/Tokyo', 'yyyy-MM-dd HH:mm:ss'),
startDate,
endDate,
rowCount,
status,
message + ` (実行時間: ${executionTime}秒)`,
errorDetail
];
// 最新のログを2行目に挿入(降順)
logSheet.insertRowAfter(1);
logSheet.getRange(2, 1, 1, logData.length).setValues([logData]);
}
コピーしたら、次のID・タブ名・取得日数の設定へ進みます。コード全文を閉じても、設定の説明はこの下に続きます。
3. スプレッドシートID・タブ名・取得日数を設定する
コードを貼ったら、冒頭の設定項目を自分の出力先に合わせます。特に間違えやすいのが、ファイルを指定するスプレッドシートIDと、ファイル内のタブ名です。
| 設定項目 | 入力・確認する内容 |
|---|---|
| SPREADSHEET_ID | 出力先ファイルのURLにある、/d/ と次の / の間の文字列 |
| SHEET_NAME | 広告実績を出すタブ名。ここでは「Google広告データ」 |
| LOG_SHEET_NAME | 実行結果を記録するタブ名。ここでは「出力ログ」 |
| DAYS_AGO | 何日前から取得するか。90なら、コード上の当日を含めて最大91日分 |
| METRICS | 出力する指標。初回は掲載どおり。CVRを残すならクリック数・コンバージョン数も残す |
ファイルIDとタブ名を合わせる
たとえばURLが https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID/edit なら、設定するのは YOUR_SPREADSHEET_ID の部分です。URL末尾の gid はタブを識別する値なので、ここでは使いません。
上のコードで最初に変更する部分はここです。{スプシID}は波括弧ごと実際のIDへ置き換え、外側の引用符は残してください。タブ名を変えていなければ、SHEET_NAMEとLOG_SHEET_NAMEは掲載どおりで使えます。
const SPREADSHEET_ID = 'YOUR_SPREADSHEET_ID';
const SHEET_NAME = 'Google広告データ';
const LOG_SHEET_NAME = '出力ログ';
const DAYS_AGO = 90;
取得期間と、表が更新される範囲を知っておく
このコードは「90日前から当日まで」を取り直して、出力タブを書き換えます。日々のデータを末尾へ追加して永久に蓄積する方式ではありません。長期保存が必要なら、必要な期間の表を別ファイルへ保存してください。
また、このコードの日付計算はGoogle広告スクリプトの既定タイムゾーン(America/Los_Angeles)を使い、ログの実行日時は日本時間で表示します。日本時間の今日まで取得したつもりでも、取得期間の終了日が前日になる場合があります。必ずログの開始・終了日を確認してください。広告アカウントのタイムゾーンに合わせる改修は、日付・時刻の公式資料を参照できます。
初回は、広告を配信している直近の期間に絞ると結果を照合しやすくなります。たとえばDAYS_AGO = 7にして出力を確認し、その後に90へ戻す進め方です。日数を365などへ変える場合も、件数や処理時間が増えることを踏まえてください。Google広告スクリプトには通常30分の実行時間上限があります。詳しくは実行制限の公式資料を参照してください。
設定を終えたら、編集画面の右下にある「保存」を押します。これでコードは保存されますが、この時点では毎日の自動更新はまだ設定されていません。
4. 承認して初回実行し、データとログを照合する
アクセス権を確認して承認する
初めてプレビューや実行をすると、スクリプトの承認を求められます。「承認」または「今すぐ承認」を押して、Googleの認証画面へ進んでください。
Google広告と出力先シートを扱えるアカウントを選び、表示されたアクセス対象と権限を読みます。Google広告やスプレッドシートの編集を含む権限が表示されるので、コードの処理内容を確認したうえで「続行」などのボタンを押します。
承認後はGoogle広告の編集画面に戻ります。Googleの承認手順にもあるとおり、権限が失効した場合には、後から再承認が必要になることがあります。
「プレビューなら書き込まれない」と思い込まない
Google広告のプレビューモードでも、スプレッドシートへの書き込みは行われます。プレビューが変更を抑える対象は、主にAdsAppを通した広告データです。外部サービスへの処理まで止まるわけではありません。プレビューモードの公式仕様を踏まえ、初回は専用の出力先で動かしてください。
出力先とコードを確認したら、「実行」または「スクリプトを今すぐ実行」を押します。「実行前にプレビューしますか」と表示される場合は、実行する内容を確認して先へ進みます。完了後は「スクリプトの履歴」を開き、終了状態とエラーの有無を見ます。
Google広告データのタブを開く
スプレッドシートへ戻り、「Google広告データ」のタブを開きます。日付・キャンペーン名・表示回数・クリック数・コストなどが並んでいれば、書き込み先は合っています。
ここで、Google広告の管理画面も同じアカウント・同じ期間・同じキャンペーンに揃え、まず配信済みの1日・1キャンペーンを選び、費用とクリック数を比較します。費用・平均CPC・CPAの通貨は広告アカウントの設定に合わせて読み、金額と割合を混ぜないようにします。コンバージョンを含める場合は、どのコンバージョン列を取得しているかも揃えてください。
実演の表にも、CPAなどで#NUM!が出ている箇所があります。掲載コードは数値でないCPAをそのまま割り算するため、表示できない値が残る場合があります。エラーや空欄は「成果ゼロ」とは別です。コンバージョン数と元の管理画面を確認し、原因が分かるまでは平均や合計の計算へ混ぜないでください。
出力ログのタブも確認する
次に「出力ログ」を開き、見出しのすぐ下にある2行目の最新ログを確認します。実行日時・取得期間の開始と終了・取得行数・ステータス・メッセージ・エラー詳細が記録されます。成功という表示だけでなく、意図した期間と行数になっているかまで見ておきましょう。
表が埋まったこと、ログが成功していること、管理画面と数値を照合できたこと。この3つを確認してから、毎日の実行へ進みます。
5. 毎日の実行時間帯を設定する
Google広告の「スクリプト」一覧へ戻り、作成したスクリプトの「Frequency/頻度」の欄にカーソルを合わせ、編集の鉛筆アイコンを押します。頻度を「毎日」にして、実行する時間帯を選び、保存してください。
僕は、朝に確認しやすいように8時〜9時の枠を選びました。ここまで設定すれば、毎朝コピーしなくても、表を開く前にデータが入ってくる。これ、めちゃめちゃ便利ですよね。
指定するのは時間帯なので、「必ず8時ちょうどに終わる」という意味ではありません。
翌日、設定した時間帯が過ぎたら「出力ログ」の実行日時が新しくなったかを確認します。初回の手動実行が成功しただけでは、定期実行の確認は済んでいません。
前日のデータも、指標によってはまだ反映途中です。Googleは、指標ごとの更新頻度と後からの調整を案内しています。コンバージョンやインプレッションシェアを読むときは、取得時点も意識してください。
出力項目を変えるとき・更新できないとき
不要な指標はfalseにする
掲載コードのMETRICSにある対象項目を、trueからfalseへ変更し、保存して再実行します。実演では、検索インプレッションシェアの項目を外しています。検索向けの指標が、すべてのキャンペーンで埋まるとは限りません。
CVRを出す場合は、clicksとconversionsもtrueのままにしてください。掲載コードはこの2つの値を使ってCVRを計算するため、どちらかを外すと、本来のCVRにかかわらず0と表示されることがあります。
列の増減で集計式の参照先がずれることがあるため、項目を変えた後は、元データの見出しと集計用タブの数式を確認してください。
エラーは「どこまで進んだか」で切り分ける
| 症状 | 確認する場所 |
|---|---|
| シートを開けない・権限エラー | SPREADSHEET_ID、承認したGoogleアカウント、出力先ファイルの編集権限 |
| 指定したタブが見つからない | SHEET_NAMEとLOG_SHEET_NAME。大文字小文字、空白も含めてタブ名と一致させる |
| 手動では動くが、毎日更新されない | 一覧の有効・無効、頻度の保存状態、実行履歴、承認した担当者のアクセス権 |
| 「取得できるデータがありませんでした」と出る | 取得期間・配信期間・対象アカウントを確認。0件の実行では前回の表が残るため、表があるだけで更新成功と判断しない |
| 表は更新されたがログがない | 「出力ログ」のタブ名と編集権限を確認。ログへの書き込みだけ失敗する場合があるので、Google広告側の実行履歴も見る |
| 日付や数値が管理画面と違う | 期間、フィルタ、指標の定義、コードの日付基準と広告アカウントのタイムゾーン、データの更新時点 |
また、作成者が広告アカウントから外れると、定期実行が止まることがあります。担当者の異動時には、残る担当者で再承認し、次回の実行結果まで確認してください。
出力した表を、集計や分析に使う
スプレッドシートへ書き出しておくと、関数で見やすい表にしたり、AIと会話しながら数字を見たりしやすくなります。実演では、シートのGeminiへ表の分析を依頼しています。AIの機能は、使っているプランや組織の設定で利用条件が変わります。
Google製品同士ということもあって、このあたりの操作自体は結構簡単にできますね。表を作ったところで終わらず、そのまま分析を頼めるのがいいところです。
いきなり改善案を求めるより、まず「どの期間・どの指標を読んだのか」を揃えるのがおすすめです。行が少ない、コンバージョンがほとんどない、といった表からは、傾向を強く言い切れません。
いつも使っているClaudeやChatGPTでこの表を読みたい方は、末尾のSynapse MCPを使った分析例と接続方法も参考にしてください。
まずは1アカウントで、転記しなくてよい状態を作る
僕が減らしたいのは、数字を考えずに、形式上毎日続けている転記の時間です。数字を把握すること自体は大切なので、出力した表とログを確かめる習慣は残しておきたいですね。
最初は「専用シートへ出力→管理画面と照合→毎日の実行→翌日のログ確認」の順で進めてください。そこまでできたら、AIへの接続や分析を試す土台ができます。
こういう仕組みって、一度作ってしまうと、その後の仕事でも繰り返し使えるんですよね。僕は、最初の設定に時間をかける費用対効果がめっちゃいいと思っています。もちろん、日々のログ確認や権限が変わったときの手入れは必要です。それでも、毎朝同じ転記を繰り返すより、最初に仕組みを作って使い続けられるのはいいですよね。
Synapse MCPなら、集めたデータをAIに聞いて分析できる
シートへ数字が集まったら、次は「何が変わったのか」「どこを見直したいのか」を考える段階です。Synapse MCPを使うと、Google広告やスプレッドシートをClaude・ChatGPTにつなぎ、普段の言葉で数字を尋ねられます。
今回の表をつなげば、比較や集計も会話で頼める
今回作ったスプレッドシートをSynapse MCPへ接続すると、ClaudeやChatGPTが表の値を読み取れます。自分で集計用の関数を組む前に、「期間ごとに合計して」「変化が大きいキャンペーンを教えて」と頼んでみましょう。
接続した「Google広告データ」を読み、2026年8月17日〜23日と8月24日〜30日の広告費・クリック数・コンバージョン数を比べて。期間ごとの合計と、費用の変化が大きいキャンペーンを教えて。必要な行が足りなければ、その範囲も教えて。
日付は、自分の表に入っている比較したい期間へ置き換えてください。AIが示した対象期間・取得範囲と合計を元の表で確かめてから、「次にどの数字を確認したらいい?」と相談できます。CPAを比較するなら、日別CPAを単純平均せず、期間全体の費用÷コンバージョン数で計算してもらいましょう。
設定はGoogleスプレッドシートをAIにつなぐ手順で説明しています。シートを経由せず広告実績を読みたい方には、Google広告を直接つないで分析する方法もあります。
GA4やSearch Consoleも、同じ会話で調べられる
広告だけでなく、GA4のアクセス数やSearch Consoleの検索流入も、それぞれを接続すればAIに質問できます。月別PVの比較やよく読まれる記事の確認なら、GA4の探索レポートの作り方を知らなくても、見たい数字を自然言語で伝えられます。
以下は、Synapse MCPでGA4の週次レポートを作った記事の実演です。画像はGoogle広告の出力結果ではなく、GA4・Search Consoleを使った活用例です。接続から表の取得、グラフ化までを見てみましょう。
① 分析したいデータを接続する
この例では、同じ案件にGA4とSearch Consoleを登録しています。接続後にAI側へMCPリンクを登録すると、会話からデータを読み取れるようになります。
② 知りたい数字を、表で返してもらう
Search Consoleの日別クリック数・表示回数・CTR・平均掲載順位が、Claudeの回答に並んでいます。管理画面から数字をコピーして質問文へ貼る手間を減らせます。
③ 続けてグラフ化を頼む
GA4のセッション数・ユーザー数・PVを日別グラフにした例です。数値の一覧から推移を見たいときも、同じ会話で依頼できます。
たとえばGA4なら、次のように聞けます。
- 「先月のPVと今月のPVを比較して。今月は昨日まで、先月も同じ日数で揃えて」
- 「先月、よく読まれた記事をPVの多い順に教えて。記事のURLも付けて。取得できた範囲も教えて」
質問するときは対象サイトを伝え、記事ページのURLの範囲も指定すると確認しやすくなります。取得したページ数に上限があるため、返ってきた一覧がサイト全体を網羅しているとは限りません。上の画像は日別の表・グラフの実演で、ここに挙げた月別比較や記事ランキングの実行結果ではありません。
まずは、今回の広告データを1つつないでみる
- 出力先を接続する:Synapse MCPにログインし、対象の接続画面で「媒体を追加」からGoogleスプレッドシートを選びます。Google認証後に、今回作ったファイルを指定します。
- 使うAIへ登録する:接続画面の「MCPリンク」から、ClaudeまたはChatGPT向けの接続をAI側の設定へ登録し、認証を完了します。
- 小さな範囲を読んで確かめる:新しい会話で接続を有効にして、下の質問を送ります。
接続したスプレッドシートから、今回作ったファイルを確認して。「Google広告データ」のA1:K20を読み、ファイル名・見出し・値を見せて。
元の表と見出し・値が一致したら、自分のデータをAIから読めたことを確認できます。次に、比較に必要な期間の行を読み取ってもらいましょう。シートの更新はGoogle広告スクリプトが行い、Synapse MCPはそのセル値をAIへ渡します。
フリーは新規登録から14日間、3サービス・各媒体1アカウントまで。自動課金はありません。料金・利用条件を確認できます。Claude・ChatGPT側の利用条件は別途確認してください。
