Yahoo!広告 スクリプト | Developer Center
English事例集(その他)
・Q.Google App Scriptでスプレッドシートの行を削除するdeleteRows()と同等の機能は提供されていますか?・Q.データ分析で使うため、毎日キャンペーンの入札戦略と目標値を出力したいのですが、可能ですか?
・Q.AccountService.get()で一度に取れる件数は500件までだと思いますが、それ以上取りたい場合はどうすればよいですか?
Q.Google App Scriptでスプレッドシートの行を削除するdeleteRows()と同等の機能は提供されていますか?
A.deleteRow()及び、deleteRows()の提供はありません。下記に同等の機能を再現した関数をご用意しましたので、ご参考にいただければと思います。
動作確認バージョン:v202406
コードサンプル ここをクリックすると折り畳みます。
function main() {
const ss = SpreadsheetApp.openById('スプレッドシートID');
const sh = ss.getSheetByName('シート名');
deleteRows(sh, 3, 2);
}
/**
* 指定したシートから指定した範囲の行を削除する関数。
* SpreadsheetApp.deleteRowsを使用せず、getValuesとsetValuesを使用して行を削除します。
*
* @param {SheetObject} sheet - 操作対象のシート名。
* @param {number} startRow - 削除を開始する行番号(1から始まる)。
* @param {number} numRows - 削除する行数。
*/
function deleteRows(sheet, startRow, numRows){
const lastRow = sheet.getLastRow();
const lastColumn = sheet.getLastColumn();
const data = sheet.getRange(1, 1, lastRow, lastColumn).getValues();
const endRow = startRow + numRows - 1;
const newData = [];
for (let i = 0; i < data.length; i++) {
if (i < startRow - 1 || i >= endRow) {
newData.push(data[i]);
}
}
sheet.clear();
if (newData.length > 0) {
sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}
}
Q.データ分析で使うため、毎日キャンペーンの入札戦略と目標値を出力したいのですが、可能ですか?
A.はい、以下のスクリプトで実現できます。
動作確認バージョン:v202406
コードサンプル ここをクリックすると折り畳みます。
/*このソースコードは MIT License のもとで提供されています。
https://ads-developers.yahoo.co.jp/ja/ads-script/post/30418913.html
■スクリプト内容
スプレッドシートに、実行時点でのキャンペーンの入札戦略の設定を出力します。
■利用方法
1.当スクリプトを、検索広告のアカウントに設定してください。
2.定数を以下のように設定してください。
■定数
・SPREAD_SHEET_ID //スプレットシートIDを指定
・OUTPUT_SHEET_NAME //出力シート名
・FLAG_MAIL //結果をメール送信するならtrue、しないならfalse
・MAIL_TO //メール送信先のYahoo! BusinessID
・MAIL_TITLE //メールタイトル
・FLAG_SLACK //結果をSlack送信するならtrue、しないならfalse
・URL_FETCH_APP //SlackのWebhook URL
■制限事項
・ヘッダ行は出力しないので、ご自身でスプレッドシートに記載をお願いいたします。
日 キャンペーンID キャンペーン名 入札戦略 目標値
*/
//設定が必要な定数
const SPREAD_SHEET_ID = 'SPREAD_SHEET_ID';
const SHEET_NAME = 'SHEET_NAME'
const FLAG_MAIL = false;
const MAIL_TO = ['Yahoo! JAPAN Business ID'];
let MAIL_TITLE = 'キャンペーンマスタ出力';
const FLAG_SLACK = false;
const URL_FETCH_APP = 'SLACK_WEBHOOK_URL';
//設定が不要な定数(変更するとエラーになります)
const accountId = AdsUtilities.getCurrentAccountId();
let TEXT_MESSAGE_ARRAY = [];
const SPREAD_SHEET_URL = '\nhttps://docs.google.com/spreadsheets/d/' + SPREAD_SHEET_ID;
function main() {
try {
const ss = validateAndGetSpreadsheet(SPREAD_SHEET_ID);
//出力用データ生成
const outputData = createOutputData();
//スプレッドシートに出力
const outputSh = validateAndGetSheet(ss);
const lastRow = outputSh.getLastRow();
outputSh.getRange('A' + (lastRow + 1)).setValues(outputData);//追記
logAndMessage('スプレッドシートに' + outputData.length + '件のデータを出力しました');
//通知
validateAndSendMail();
validateAndSendSlack();
} catch (error) {
MAIL_TITLE = '!!エラー発生!!' + MAIL_TITLE;
logAndMessage('エラーが発生しました。詳細は管理画面のログをご確認ください。\n' + error);
validateAndSendMail();
validateAndSendSlack();
throw error;//ログ上でエラーにするため再スロー
}
}
function createOutputData() {
//キャンペーンマスタ取得
const campaignValues = getCampaignMaster();
//出力用データ生成
const todayStr = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd');
let outputData = [];
for (let i = 0; i < campaignValues.length; i++) {
const campaign = campaignValues[i].campaign;
const biddingInfo = getBiddingInfo(campaign.biddingStrategyConfiguration);
if (biddingInfo.biddingStrategyStr == '') {
throw new Error('キャンペーンID:' + campaign.campaignId
+ ' の入札戦略の取得に失敗しました。biddingStrategyConfiguration:'
+ JSON.stringify(campaign.biddingStrategyConfiguration));
}
outputData.push([
todayStr,
campaign.campaignId,
campaign.campaignName,
biddingInfo.biddingStrategyStr,
biddingInfo.biddingValue
]);
}
Logger.log('出力データを' + outputData.length + '件作成しました');
return outputData;
}
function getCampaignMaster() {
const campaigns = Search.CampaignService.get({
accountId: accountId,
numberResults: 10000,//念のため最大値
}).rval;
if (campaigns.totalNumEntries == 0) {
throw new Error('アカウント内にキャンペーンが存在しません。');
}
return campaigns.values;
}
//入札戦略・値の出力用文字列を生成する{biddingStrategyStr:入札戦略名 ,biddingValue:値}
//生成できなかった場合は、それぞれ空文字になる。呼び出し元でエラーハンドルする。
function getBiddingInfo(biddingStrategyConfiguration) {
const biddingScheme = biddingStrategyConfiguration.biddingScheme;
const biddingStrategyType = biddingScheme.biddingStrategyType;
let biddingStrategyStr = '';
let biddingValue = '-';
switch (biddingStrategyType) {
case 'CPC':
biddingStrategyStr = '個別クリック単価';
if (biddingScheme.cpcBiddingScheme.enhancedCpcEnabled == 'TRUE') {
biddingStrategyStr += '(拡張クリック単価)';
}
biddingValue = '-';
break;
case 'TARGET_ROAS':
biddingStrategyStr = '広告費用対効果の目標値';
biddingValue = toPercentage(biddingScheme.targetRoasBiddingScheme.targetRoas);
break;
case 'MAXIMIZE_CLICKS':
biddingStrategyStr = 'クリック数の最大化';
if (biddingScheme.maximizeClicksBiddingScheme.bidCeiling == 0) {
biddingValue = '-';
} else {
biddingStrategyStr += '(上限値を指定する)';
biddingValue = biddingScheme.maximizeClicksBiddingScheme.bidCeiling + '円';
}
break;
case 'TARGET_CPA':
biddingStrategyStr = 'コンバージョン単価の目標値';
biddingValue = biddingScheme.targetCpaBiddingScheme.targetCpa + '円';
break;
case 'MAXIMIZE_CONVERSIONS':
biddingStrategyStr = 'コンバージョン数の最大化';
if (biddingScheme.maximizeConversionsBiddingScheme.targetCpa == null) {
biddingValue = '-';
} else {
biddingStrategyStr += '(目標値を指定する)';
biddingValue = biddingScheme.maximizeConversionsBiddingScheme.targetCpa + '円';
}
break;
case 'MAXIMIZE_CONVERSION_VALUE':
biddingStrategyStr = 'コンバージョン価値の最大化';
if (biddingScheme.maximizeConversionValueBiddingScheme.targetRoas == null) {
biddingValue = '-';
} else {
biddingStrategyStr += '(目標値を指定する)';
biddingValue = toPercentage(biddingScheme.maximizeConversionValueBiddingScheme.targetRoas);
}
break;
case 'TARGET_IMPRESSION_SHARE':
biddingStrategyStr = 'ページ最上部掲載';
biddingValue = biddingScheme.targetImpressionShareScheme.bidCeiling + '円';
break;
}
return { biddingStrategyStr: biddingStrategyStr, biddingValue: biddingValue };
}
function toPercentage(decimal) {
if (typeof decimal !== 'number' || isNaN(decimal)) {
throw new Error('Invalid input: the argument must be a number.');
}
return (decimal * 100).toFixed(2) + '%';
}
//ログ、メールなどに流すテキスト
function logAndMessage(text) {
Logger.log(text);
TEXT_MESSAGE_ARRAY.push(text);
}
function validateAndGetSpreadsheet() {
if (SPREAD_SHEET_ID === 'SPREAD_SHEET_ID' || SPREAD_SHEET_ID === '') {
throw new Error('スプレッドシートIDを設定してください。');
}
try {
return SpreadsheetApp.openById(SPREAD_SHEET_ID);
} catch (e) {
throw new Error('スプレッドシートを開くことが出来ませんでした。スプレッドシートIDまたはスプレッドシートの権限が正しいか確認してください。' + e);
}
}
function validateAndGetSheet(ss) {
if (SHEET_NAME === '') {
throw new Error('シート名を設定してください。');
}
const sh = ss.getSheetByName(SHEET_NAME);
if (sh === null) {
throw new Error('シートが開けませんでした。シート名を確認してください。');
}
return sh;
}
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') + SPREAD_SHEET_URL,
});
}
}
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: TEXT_MESSAGE_ARRAY.join('\n') + SPREAD_SHEET_URL,
}),
});
}
}
Q.AccountService.get()で一度に取れる件数は500件までだと思いますが、それ以上取りたい場合はどうすればよいですか?
A.以下のスクリプトのように、while文を使って500件ずつ取るようにしてください。
動作可能プロダクト:MCC(本スクリプトは検索広告のアカウントのみ)
動作確認バージョン:v202402
コードサンプル ここをクリックすると折り畳みます。
function main(){
let startIndex = 0;
const maxNumberResults = 500;
while (true) {
const accounts = Search.AccountService.get({
accountStatuses: ['SERVING'],
numberResults: maxNumberResults,
startIndex: startIndex * maxNumberResults + 1,
}).rval;
for (let i = 0; i < accounts.values.length; i++) {
let account = accounts.values[i].account;
Logger.log('ID:' + account.accountId + ' 名称:' + account.accountName);
}
startIndex++;
if (accounts.totalNumEntries <= startIndex * maxNumberResults) break;
}
}