【AdWordsScript】日次・キャンペーン別の予算設定

AdWordsの自動化ルールを多用していくと、「入札単価の自動調整はできるが、キャンペーンの予算調整ができない」という壁に行き着きます。

ただ、AdWords Scriptを使うと、キャンペーンの予算調整も可能になります。ということで、日別・キャンペーン別の予算設定を行うためのスクリプトを公開します。

## 使い方の概要
日別・キャンペーン別の予算情報は、Google Docsのスプレッドシート上に保持します。日次で夜1:00ごろにAdWords Scriptが自動実行されるように設定しておき、AdWords Scriptから、Google Docs上のスプレッドシートにアクセスし、その日に設定すべきキャンペーンごとの予算データを取り出し、その予算を各キャンペーンに設定していきます。

## スプレッドシートのフォーマット

下記のような列を持つスプレッドシートを作成します。シートの名前は「予算データ」としておいてください（スプレッドシートのファイル名ではなくシートの名前、ファイル名は何でもOKです）。

| A | B | C |
|---|---|---|
|日付|キャンペーン名|予算|
|2014/07/15 | キャンペーン名1 | 5000 |
|2014/07/15 | キャンペーン名2 | 4000 |
|2014/07/15 | キャンペーン名3 | 10000 |
|2014/07/15 | キャンペーン名4 | 0 |
|2014/07/16 | キャンペーン名1 | 4000 |
|2014/07/16 | キャンペーン名4 | 1000 |

https://docs.google.com/spreadsheets/d/1aFMaO3m8w8pKQDSkptZX7AOsiH_0ImzDrRJVdkrRMAI/edit#gid=0

にテンプレートとして利用できるサンプルのフォーマットを置いていますので、コピーして使って構いません。


## スクリプト

上記のスプレッドシートと連携させるための設定や、実行ログの送信先メールアドレス、クライアント名などいくつか設定できる項目は、上の方にまとめています。

''(シングルクォート)で囲まれた中を適切なものに書き換えて行ってください。

**スプレッドシートのキー** とは、スプレッドシートのURLが

https://docs.google.com/spreadsheets/d/1aFMaO3m8w8pKQDSkptZX7AOsiH_0ImzDrRJVdkrRMAI/edit#gid=0

のような形式だったとき、

**1aFMaO3m8w8pKQDSkptZX7AOsiH_0ImzDrRJVdkrRMAI**

になります。

下記のスクリプトをコピーして、AdWordsアカウントの「一括処理＞スクリプト」と進み、スクリプトを追加、権限周りの承認を行い、「**プレビュー**」を行ってください（プレビューなら実際のアカウントに反映されないので、うまく動くかの確認のために使えます）。

プレビューした結果、問題なければ、スクリプトの一覧画面に戻り、「スケジュールを作成」とし、１日１回、01:00くらいに実行するようにすればOKです。

なお、スクリプトの実行時に、実行した日に該当する予算データが存在しない場合は、予算の変更は行われず、現状維持になります。


```日次・キャンペーン別の予算設定.js
var GOOGLE_DOCS_SPREAD_SHEET_KEY = '【スプレッドシートのキーを記載】';
var SHEET_NAME = '予算データ';
var EXECUTION_LOG_MAIL = '【実行ログの送信先メールアドレス】';
var CLIENT_NAME = '【クライアント名】';
var EXECUTION_LOG = [];

function main() {
  var date = new Date();
  var budget_data = getBudgetDataFromSpreadsheet(date, GOOGLE_DOCS_SPREAD_SHEET_KEY, SHEET_NAME);
  log(budget_data.length + "件のキャンペーンの予算データを更新します。");
  update(budget_data);
  sendmailLog(date);
}

function update(budget_data) {
  for (var i = 0; i < budget_data.length; i++) {
    setCampaignBudget(budget_data[i][1], budget_data[i][2]);
  }
}

function sendmailLog(date) {
  for (var i = 0; i < EXECUTION_LOG.length; i++) {
    EXECUTION_LOG[i] = "<li>" + EXECUTION_LOG[i] + "</li>";
  }
  var content = "<ul>" + EXECUTION_LOG.join("") + "</ul>";
  MailApp.sendEmail({
    "to": EXECUTION_LOG_MAIL,
    "subject": "【 " + CLIENT_NAME + "】" + formatDate(date) + "の日別・キャンペーン別予算の設定ログ通知",
    "htmlBody": content
  });
}

function formatDate(d) {
  return Utilities.formatDate(d, "Asia/Tokyo", "yyyy/MM/dd");
}

function getBudgetDataFromSpreadsheet(date, sheet_id, sheet_name) {
  var sheet = SpreadsheetApp.openById(sheet_id).getSheetByName(sheet_name);
  var lastRow = sheet.getLastRow();
  var data = sheet.getDataRange().getValues();
  var results = [];
  for (var i = 1; i < data.length; i++) {
    try {
      if (formatDate(data[i][0]) == formatDate(date)) {
        results.push(data[i]);
      }
    } catch (ex) {
      log("スプレッドシートの" + (i + 1) + "行目のデータを取得する際にエラーが発生しました。日付のフォーマットをご確認ください。");
    }
  }
  return results;
}


function setCampaignBudget(campaignName, budget) {
  var campaignIterator = AdWordsApp.campaigns().withCondition('Name = "' + campaignName + '"').get();
  if (campaignIterator.hasNext()) {
    var campaign = campaignIterator.next();
    if (budget == 0) {
      campaign.pause();
      log("キャンペーンの停止：name = " + campaign.getName() + "(停止理由:設定された予算が0円のため)");
    } else {
      campaign.enable();
      campaign.getBudget().setAmount(budget);
      log("【予算の自動変更】 Campaign with name = " + campaign.getName() + " has budget " + campaign.getBudget().getAmount());
    }
  } else {
    log("指定されたキャンペーン(" + campaignName + ") が見つかりません。名称を確認してください。");
  }
}

function log(message) {
  Logger.log(message);
  EXECUTION_LOG.push(message);
}
```