インプレッションシェア損失率(予算)超過通知

スクリプトの概要

本ページでは、スクリプト内で指定したインプレッションシェア損失率(予算)が指定した値を超過した場合に、該当のキャンペーンを出力して通知するスクリプトをご紹介します。
例:今日を含まない過去30日間のインプレッションシェア損失率(予算)が10%以上になっているキャンペーンがあった場合、結果をメール本文に記載して通知します。(該当がなかった場合は、通知されません)
 メール本文のイメージ
以下のキャンペーンで、インプレッションシェア損失率が10%以上となっています。
キャンペーン名 AAA
キャンペーン名 BBB

※当スクリプトは検索広告・ディスプレイ広告共通版となっております。(設定されたアカウントが検索広告かディスプレイ広告かを自動で判定します)

インプレッションシェア損失率について

インプレッションシェア損失率については、こちらのヘルプ(検索広告/ディスプレイ広告)をご覧ください。

ご利用の流れ

本スクリプトではGoogleスプレッドシートを利用しないため、サンプルコードの設定のみでご利用可能です。

1.管理画面上のスクリプト作成画面にて、後述のサンプルコードを設定してください。
※スクリプトの新規作成および編集の手順はこちらをご覧ください。

2.管理画面上にてスクリプトの設定を完了後、スクリプトの実行頻度の設定をしてください。
本スクリプトでは「1時間ごと」に設定することを推奨いたします。
※スクリプトの実行頻度の設定手順はこちらをご覧ください。

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

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

■インプレッションシェア損失率(予算)の指定について


チェック対象となるインプレッションシェア損失率(予算)の値を変更する場合、下記の定数に書かれている数値を変更してください。
const BUDGET_LOST_PERCENTAGE = 10;//★通知対象としたいインプレッションシェア損失率(予算)の値を入力。例:10%の場合、10を指定

■集計対象期間の変更と、対象プロダクトの指定について


本スクリプトではインプレッションシェア損失率(予算)をチェックする集計対象期間を変更することが可能です。実行頻度の変更とともにお試しください。

例:毎週月曜日に先週(月〜日)のインプレッションシェア損失率(予算)を超えていないかをチェックしたい
  → 期間:先週(月〜日)、実行頻度:毎週月曜日

本スクリプトは、設定されたアカウントのプロダクト種別(検索広告かディスプレイ広告か)を自動で判定しますので、設定するアカウントのプロダクトに該当する集計対象期間の定数をご設定ください。

初期状態では、それぞれ下記のように書かれております。
設定するアカウントのプロダクトではないほうの定数は、定数を空欄にするか初期状態のままで問題ございません。

ご注意

記述削除は思わぬ挙動の原因になる恐れがあるため、設定するアカウントのプロダクトではないほうの記述も、削除せず残しておくようお願いいたします。

▽検索広告(集計対象期間「過去30日間(今日を含まない)」が初期値)
const DATA_RANGE_SEARCH = 'LAST_30_DAYS';
次のように変更してください。(集計対象期間を「先週(月〜日)」にする場合)
const DATA_RANGE_SEARCH = 'LAST_WEEK';

▽ディスプレイ広告(集計対象期間「過去30日間(今日を含まない)」が初期値)
const DATA_RANGE_DISPLAY = 'DEFINITE_VALUE_THIRTYDAY';
次のように変更してください。(集計対象期間を「先週(月〜日)」にする場合)
const DATA_RANGE_DISPLAY = 'DEFINITE_VALUE_LASTWEEK';
※指定可能な集計対象期間については、リファレンス(Search)リファレンス(Display)をご確認ください。

■メール、Slackの指定例

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

サンプルコード

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

/* このソースコードは MIT License のもとで提供されています。
https://ads-developers.yahoo.co.jp/ja/ads-script/post/30418913.html  */
/*
■スクリプト内容
すべてのキャンペーンについて本日の実績を参照し、インプレッションシェア損失率(予算)が10%より大きくなった場合にメールを送信します。
■利用方法
1.当スクリプトを、検索広告またはディスプレイ広告のスクリプトとしてください。
2.各定数を以下のように設定してください。
■定数
・BUDGET_LOST_PERCENTAGE:インプレッションシェア損失率(予算)の値
・DATA_RANGE_SEARCH:レポートの集計対象期間(Search) リファレンス:https://ads-developers.yahoo.co.jp/ja/ads-script/product-guide/reference/enums/search.ReportDefinitionServiceReportDateRangeType.html
・DATA_RANGE_DISPLAY:レポートの集計対象期間(Display) リファレンス:https://ads-developers.yahoo.co.jp/ja/ads-script/product-guide/reference/enums/display.StatsServiceStatsPeriod.html
・FLAG_MAIL:結果をメール送信するならtrue、しないならfalse
・MAIL_TO:メール送信先のYahoo! BusinessID
・MAIL_TITLE:メールタイトル
・FLAG_SLACK:Slack配信するときはtrue、配信しないときはfalse
・URL_FETCH_APP:SlackのWebhook URL
*/
//設定が必要な定数
const BUDGET_LOST_PERCENTAGE = 10;
const DATA_RANGE_SEARCH = 'LAST_30_DAYS';
const DATA_RANGE_DISPLAY = 'DEFINITE_VALUE_THIRTYDAY';
const FLAG_MAIL = false;
const MAIL_TO = ['Yahoo! BusinessID'];
let MAIL_TITLE = 'インプレッションシェア(予算)損失アラート';
const FLAG_SLACK = false;
const URL_FETCH_APP = 'SLACK_WEBHOOK_URL';
//設定が不要な定数
const PRODUCT_TYPE_YSA = 'SEARCH';
const PRODUCT_TYPE_YDA = 'DISPLAY';
//プロダクトタイプで処理内容を分ける
const productType = AdsUtilities.getProductType();
const accountId = AdsUtilities.getCurrentAccountId();
let TEXT_MESSAGE_ARRAY = [];
function main() {
  //インプレッションシェア損失率(予算)をチェックする。
  try {
    alertImpressionShare();
  } catch (e) {
    MAIL_TITLE += ' スクリプトが失敗しています';
    TEXT_MESSAGE_ARRAY.push('何らかのエラーによりスクリプトが失敗しました。詳細は管理画面のログをご確認ください。');
    sendMailOrSlack();
    throw e;
  }
  sendMailOrSlack();
}
//インプレッションシェア損失率(予算)をチェックする。
function alertImpressionShare() {
  Logger.log('--インプレッションシェア損失率(予算)チェック処理--');
  if (productType == PRODUCT_TYPE_YSA) {
    //キャンペーンレポート全件取得(Search)
    getSearchCampaignReport();
  } else if (productType == PRODUCT_TYPE_YDA) {
    //キャンペーンレポート全件取得(Display)
    getDisplayCampaignReport();
  } else {
    logAndMessage(PRODUCT_TYPE_YSA + 'または' + PRODUCT_TYPE_YDA + 'スクリプトとしてご利用ください。');
  }
}
//ログ、メールなどに流すテキスト
function logAndMessage(text) {
  Logger.log(text);
  TEXT_MESSAGE_ARRAY.push(text);
}
//キャンペーンレポート全件取得(Search)
function getSearchCampaignReport() {
  //レポートを取得する
  const searchReports = AdsUtilities.getSearchReport({
    accountId: accountId,
    reportDateRangeType: DATA_RANGE_SEARCH,
    reportType: 'CAMPAIGN',
    fields: ['CAMPAIGN_NAME', 'BUDGET_LOST_IMPRESSION_SHARE'],
  }).reports[0].rows;
  //インプレッションシェア損失率(予算)をチェック
  alertImpressionShareBudgetLost(searchReports);
}
//キャンペーンレポート全件取得(Display)
function getDisplayCampaignReport() {
  let reportArray = [];
  //実績取得
  const stats = Display.StatsService.get({
    accountId: accountId,
    statsPeriod: DATA_RANGE_DISPLAY,
    type: 'CAMPAIGN'
  }).rval;
  for (let i = 0; i < stats.values.length; i++) {
    let campaignStatsValue = stats.values[i].campaignStatsValue;
    let campaignName = campaignStatsValue.campaignName;
    let impressionShareBudgetLoss = campaignStatsValue.stats.impressionShareBudgetLoss;
    //各値をreportArray配列に追加していく
    reportArray.push([
      campaignName, impressionShareBudgetLoss
    ]);
  }
  //インプレッションシェア損失率(予算)をチェック
  alertImpressionShareBudgetLost(reportArray);
}
//インプレッションシェア損失率(予算)をチェック
function alertImpressionShareBudgetLost(reports) {
  let campainName;
  let budgetLostImpressionShare;
  let initialMessage = true;
  for (let i = 0; i < reports.length; i++) {
    campainName = reports[i][0];
    budgetLostImpressionShare = reports[i][1];
    if (productType == PRODUCT_TYPE_YSA) {
      budgetLostImpressionShare = budgetLostImpressionShare * 100;
    }
    if (budgetLostImpressionShare > BUDGET_LOST_PERCENTAGE) {
      if (initialMessage == true) {
        logAndMessage('以下のキャンペーンで、インプレッションシェア損失率が' + BUDGET_LOST_PERCENTAGE + '%以上となっています。');
        initialMessage = false;
      }
      logAndMessage(campainName);
    }
  }
}
//メール、Slack、もしくはその両方に通知
function sendMailOrSlack() {
  if (TEXT_MESSAGE_ARRAY.length > 0) {
    validateAndSendMail();
    validateAndSendSlack();
  }
}
//メール送信
function validateAndSendMail() {
  if (FLAG_MAIL) {
    if (MAIL_TO.length < 1 || !MAIL_TO.every(str => typeof str === 'string' && /^[a-zA-Z0-9]+$/.test(str))) {
      throw new Error('Yahoo! JAPANビジネスIDを設定してください。メール送信前までに実行された処理は完了しています。');
    }
    MailApp.sendEmail({
      to: MAIL_TO,
      subject: '【アカウントID:' + accountId + '】' + MAIL_TITLE,
      body: TEXT_MESSAGE_ARRAY.join('\n'),
    });
  }
}
//Slackメッセージ送信
function validateAndSendSlack() {
  if (FLAG_SLACK) {
    if (URL_FETCH_APP === 'SLACK_WEBHOOK_URL' || URL_FETCH_APP === '') {
      throw new Error('SlackのWebhook URLを設定してください。Slack送信前までに実行された処理は完了しています。');
    }
    UrlFetchApp.fetch(URL_FETCH_APP, {
      method: 'post',
      contentType: 'application/json',
      payload: JSON.stringify({
        text: '【アカウントID:' + accountId + '】\n' + TEXT_MESSAGE_ARRAY.join('\n'),
      }),
    });
  }
}

結果確認

指定したインプレッション損失率を超えるキャンペーンがあった場合に、実行履歴のログに結果が出力されていれば成功です。