コスト超過通知

更新履歴

2024/07/24 目次を追加


スクリプトの概要

Yahoo!広告スクリプトでは、コストをチェックし、指定したコストを超過した場合に通知することが可能です。
例:今月のコストが10万円以上になっているキャンペーンがあった場合、スプレッドシートにレポート結果を出力してメールで通知したい等
※コストだけではなく、さまざまな指標でのチェックが可能です。

本ページでは、スクリプト内で指定した指標が指定した値を超過した場合に、該当のキャンペーンをスプレッドシートに出力して通知するスクリプトをご紹介します。
なお、設定によっては該当のキャンペーンをオフにすることも可能です。
※当スクリプトは検索広告・ディスプレイ広告共通版となっております。(設定されたアカウントが検索広告のものかディスプレイ広告のものか自動で判定されます)

ご利用の流れ

1.Yahoo!広告スクリプトとGoogleアカウントを連携します
 詳しくはGoogleアカウントとの連携を確認してください。
 ※すでに連携済みの方は次のステップからご設定ください。

2.スプレッドシートIDを取得します
 詳しくはGoogleスプレッドシートIDの取得方法をご覧ください。

実行頻度の設定について

本スクリプトの実行頻度を毎日に設定すると、最新の結果を毎日チェックできるためとても便利です。
※あまり早い時間に設定するとデータが反映されていない場合があります。推奨時間帯は朝6時以降です。
設定画面の例:

サンプルコード内各定数のご説明

後述のサンプルコードにおける各定数の設定方法についてご説明いたします。

■スプレッドシートID、シート名の指定例

スプレッドシートIDの取得方法はこちらをご覧ください。
次の例のように、' '(シングルクオーテーション)で囲んで指定してください。(スプレッドシートID:'12345abcde'、シート名:'Sheet1'の場合)
const SPREAD_SHEET_ID = '12345abcde'; //★書き出すスプレッドシートID。例:'SPREAD_SHEET_ID'
const SHEET_NAME = 'Sheet1';//★スプレッドシートのシート名。例:'シート1'

■メール、Slackの指定例

メール、Slack設定についてをご確認ください。

■キャンペーンIDの指定例

キャンペーンIDについて、初期状態では下記のように書かれております。

const CAMPAIGN_IDS = [];//★判定対象のキャンペーンIDを指定。例:['123456', '234567']

次のように変更してください。(指定対象キャンペーンIDが、123456、234567の場合)
const CAMPAIGN_IDS = ['123456', '234567'];//★判定対象のキャンペーンIDを指定。例:['123456', '234567']

※特定のIDを何も指定しなかった場合はすべてのキャンペーンが対象になります。
※IDを指定する場合は上記の例のように' '(シングルクオーテーション)でそれぞれ囲んでください。

■コストの指定について

チェック対象となるコストを変更する場合、下記の定数に書かれている数値を変更してください。
const TARGET_COST = 100000;//★通知対象としたいコストの値を入力。例:150

■指標の変更について

スクリプト内の下記部分の定数を変更することで、取得する指標を変更できます。
const FIELDS = ['ACCOUNT_NAME', 'CAMPAIGN_ID', 'CAMPAIGN_NAME', 'IMPS', 'CLICKS', 'COST', 'CONVERSIONS'];//レポートフィールド

主な指標
指標名 スクリプトでの値
コスト COST
インプレッション数 IMPS
クリック数 CLICKS
クリック率 CLICK_RATE
平均CPC AVG_CPC
コンバージョン数 CONVERSIONS
コンバージョン率 CONV_RATE
コンバージョンの価値 CONV_VALUE
コスト/コンバージョン数(CPA) COST_PER_CONV
コンバージョンの価値/コンバージョン数 VALUE_PER_CONV

また、本スクリプトではコストを指標としたサンプルをご紹介しておりますが、サンプルコードの下図赤枠部分を変更することで別の指標に変更することが可能です。

■レポートの集計対象期間の変更について

本スクリプトではレポートの集計対象期間を変更することが可能です。実行頻度の変更とともにお試しください。
例1:今月のコストが超えてないか毎日チェックしたい → 期間:今月、実行頻度:毎日
例2:毎週月曜日に先週のコストを超えていないかをチェックしたい → 期間:先週、実行頻度:毎週月曜日
指定可能な集計対象期間については、リファレンス(Search)リファレンス(Display)をご確認ください。
※一部ご利用頂けない集計対象期間がございます。

■指標を超えたキャンペーンを自動でオフにするには

スクリプト内にある次の定数をtrueに変更してください。
const CAMPAIGN_PAUSE_FLAG = false;//コスト超過したキャンペーンをオフにするときはtrue、オフにしないときはfalse

サンプルコード

下記のスクリプトを、「コピー」ボタンを押してコピーし、スクリプトの入力画面に貼り付けてください。(このとき、灰色のコメント部分は消さずに残しておいてください)
「サンプルコード内各定数のご説明」またはスクリプト内に記載の利用方法に沿って、設定が必要な定数を設定してください。

/*
■スクリプト内容
レポートを取得し、指定したコストを超過したキャンペーンがあれば通知します。
またスプレッドシートに結果を通知し、フラグがオンの場合には対象のキャンペーンをオフにします。
■利用方法
1.当スクリプトを、検索広告またはディスプレイ広告のスクリプトとしてください。
2.定数を以下のように設定してください。
■定数
・SPREAD_SHEET_ID:スプレッドシートID
・SPREAD_SHEET_NAME:スプレッドシート名
・TARGET_COST:通知対象としたいコストの値を入力
・CAMPAIGN_IDS:判定対象のキャンペーンIDを指定
・FLAG_MAIL:結果をメール送信するならtrue、しないならfalse
・MAIL_TO:メール送信先のYahoo! BusinessID
・MAIL_TITLE:メールタイトル
・TEXT_MESSAGE:メール。Slack本文
・FLAG_SLACK:Slack配信するときはtrue、配信しないときはfalse
・URL_FETCH_APP:SlackのWebhook URL
・CAMPAIGN_PAUSE_FLAG:コスト超過したキャンペーンをオフにするときはtrue、オフにしないときはfalse
・FIELDS:レポートフィールド
・REPORT_DATE_RANGE_TYPE:レポートの集計対象期間。指定可能な値は下記リファレンスをご確認ください。
リファレンス(Search):https://ads-developers.yahoo.co.jp/ja/ads-script/product-guide/reference/enums/search.ReportDefinitionServiceReportDateRangeType.html
リファレンス(Display):https://ads-developers.yahoo.co.jp/ja/ads-script/product-guide/reference/enums/display.ReportDefinitionServiceReportDateRangeType.html
CUSTOM_DATE、GUARANTEED_CAMPAIGN_PERIOD等、別途期間などの指定が必要な値はご利用できません。
*/
//設定が必要な定数
const SPREAD_SHEET_ID = ''; //書き出すスプレッドシートID。例:'SPREAD_SHEET_ID'
const SHEET_NAME = '';//スプレッドシートのシート名。例:'シート1'
const TARGET_COST = 100000;//通知対象としたいコストの値を入力。例:150
const CAMPAIGN_IDS = [];//判定対象のキャンペーンIDを指定。例:['123456', '234567']
const FLAG_MAIL = true;//メール送信するならtrue、しないならfalse
const MAIL_TO = [];//メール通知先のビジネスIDを指定。例:['abcde12345']
const MAIL_TITLE = 'コスト超過キャンペーン通知';//メールタイトルを指定
let TEXT_MESSAGE = '指定したコスト以上になっているキャンペーンがありました。対象はスプレッドシートをご確認ください。\n' +
  'https://docs.google.com/spreadsheets/d/' + SPREAD_SHEET_ID;//メール本文を指定
const FLAG_SLACK = false;//Slack配信するときはtrue、配信しないときはfalse
const URL_FETCH_APP = '';//SlackのWebhook URL。例:'https://hooks.slack.com/services/XXXXXXXX/XXXXXXXX/XXXXXXXX'
const CAMPAIGN_PAUSE_FLAG = false;//コスト超過したキャンペーンをオフにするときはtrue、オフにしないときはfalse
const FIELDS = ['ACCOUNT_NAME', 'CAMPAIGN_ID', 'CAMPAIGN_NAME', 'IMPS', 'CLICKS', 'COST', 'CONVERSIONS'];//レポートフィールド
const REPORT_DATE_RANGE_TYPE = 'THIS_MONTH_EXCEPT_TODAY';//レポートの集計対象期間
//設定が不要な定数
const accountId = AdsUtilities.getCurrentAccountId();
const productType = AdsUtilities.getProductType();
function main() {
  //初期値判定
  checkInitialValue();
  //スプレッドシート
  const ss = SpreadsheetApp.openById(SPREAD_SHEET_ID);
  let sh = ss.getSheetByName(SHEET_NAME);
  sh.clear();//既存行をクリア
  //レポート取得
  let report = getReport();
  //スプレッドシートに出力
  sh.getRange('A1').setValues(report);
  if (report.length > 1) {//ヘッダ以外の行がある場合のみ
    //キャンペーンオフ
    if (CAMPAIGN_PAUSE_FLAG) {
      pausedCampaign(report);
    }
    //メール通知
    if (FLAG_MAIL) {
      MailApp.sendEmail({
        to: MAIL_TO,
        subject: MAIL_TITLE,
        body: TEXT_MESSAGE
      });
    }
    //Slack通知
    if (FLAG_SLACK) {
      UrlFetchApp.fetch(URL_FETCH_APP,
      {
        method: 'POST',
        contentType: 'application/json',
        payload: {
          text: TEXT_MESSAGE,
        }
      });
    }
  }
}
function getReport(){
  let filters = [
    {//指定したコスト
      field: 'COST',
      filterOperator: 'GREATER_THAN',
      values: [TARGET_COST]
    }
  ];
  if(CAMPAIGN_IDS.length >= 1){
    filters.push(
      {//指定したキャンペーンID
        field: 'CAMPAIGN_ID',
        filterOperator: 'IN',
        values: CAMPAIGN_IDS
      }
    )
  }
  //レポート取得
  let reportData;
  if (productType == 'SEARCH') {
    reportData = AdsUtilities.getSearchReport({
      accountId: accountId,
      fields: FIELDS,
      filters,
      reportDateRangeType: REPORT_DATE_RANGE_TYPE,
      reportType: 'CAMPAIGN',
      reportSkipColumnHeader: 'FALSE',
      sortFields: [//並び順
        {//コストの多い順
          field: "COST",
          reportSortType: "DESC"
        }
      ]
    }).reports[0].rows;
  } else if (productType == 'DISPLAY') {
    reportData = AdsUtilities.getDisplayReport({
      accountId: accountId,
      fields: FIELDS,
      filters,
      reportDateRangeType: REPORT_DATE_RANGE_TYPE,
      reportSkipColumnHeader: 'FALSE',
      sortFields: [//並び順
        {//コストの多い順
          field: "COST",
          reportSortType: "DESC"
        }
      ]
    }).reports[0].rows;
  } else {
    throw new Error('当スクリプトは検索広告またはディスプレイ広告のアカウントに設定してください(MCCアカウント等は対象外です)');
  }
  return reportData;
}
function pausedCampaign(reportData) {
    let campaignOperandArray = [];
    for (let i = 1; i < reportData.length; i++){
      let operand = {
        campaignId: reportData[i][1],
        userStatus: "PAUSED",
      };
      campaignOperandArray.push(operand)
    }
    const productObj = productType == 'SEARCH' ? Search : Display;
    const campaigns = productObj.CampaignService.set({
        accountId: accountId,
        operand: campaignOperandArray,
      }).rval;
    for (let j = 0; j < campaigns.values.length; j++){
      if (campaigns.values[j].operationSucceeded){
        Logger.log("campaignId: " + campaigns.values[j].campaign.campaignId + " をオフにしました。");
      }
    }
    TEXT_MESSAGE = TEXT_MESSAGE + '\n対象のキャンペーンをオフにしました。詳細は実行履歴のログをご確認ください。';
}
function checkInitialValue() {
  let initialValue = "";
  if (SPREAD_SHEET_ID == '' || SPREAD_SHEET_ID == 'SPREAD_SHEET_ID') {
    initialValue = initialValue + 'SPREAD_SHEET_ID,';
  }
  if (SHEET_NAME == '') {
    initialValue = initialValue + 'SHEET_NAME,';
  }
  if (CAMPAIGN_IDS[0] == 123456 && CAMPAIGN_IDS[1] == 234567) {
    initialValue = initialValue + 'CAMPAIGN_IDS,';
  }
  if (FLAG_MAIL == true){
    initialValue = checkMailValue(initialValue);
  }
  if (FLAG_SLACK == true){
    initialValue = checkSlackValue(initialValue);
  }
  let checkWord = /,$/;
  if (checkWord.test(initialValue)){
    initialValue = initialValue.slice(0, -1);
  }
  if (initialValue){
    throw new Error('次の定数が初期値のままです。「' + initialValue + '」');
  }
}
function checkMailValue(initialValue){
  if (MAIL_TO[0] == 'abcde12345' || MAIL_TO.length == 0){
    initialValue = initialValue + 'MAIL_TO,';
  }
  return initialValue;
}
function checkSlackValue(initialValue){
  if (URL_FETCH_APP == 'https://hooks.slack.com/services/XXXXXXXX/XXXXXXXX/XXXXXXXX' || URL_FETCH_APP == '') {
    initialValue = initialValue + 'URL_FETCH_APP,';
  }
  return initialValue;
}

結果確認

指定したコストを超えるキャンペーンがあった場合に、スプレッドシートに結果が出力されれば成功です。