Skip to content

Instantly share code, notes, and snippets.

@quangquy87
Created August 23, 2022 07:59
Show Gist options
  • Save quangquy87/095e1b7e6cffd058ea34c9423087c1f5 to your computer and use it in GitHub Desktop.
Save quangquy87/095e1b7e6cffd058ea34c9423087c1f5 to your computer and use it in GitHub Desktop.
TẮT CHIẾN DỊCH
/****************************
* TẮT CHIẾN DỊCH ĐANG BANH XÁC
* Version 1.0 (21/07/2022)
*
* Created By: Quý Ngô
****************************/
// cấu hình
var CONFIG = {
LAST_N_DAYS: 7, // thời gian quét từ ngày quét trở về trước đó
MAX_COST: 150000, // chi tiêu từ số này trở lên mới bắt đầu tính theo điều kiện dưới là CPA
MAX_CPA: 150000, // CPA tối đa có thể chịu được
EMAIL: '', //Email để nhận thông báo, nhiều email cách nhau bởi dấu ",".VD:'[email protected], [email protected]'
SHEET_URL:
'https://docs.google.com/spreadsheets/d/1mMCUvlM4Dq6fIevsZ_uvcwPwiZewoxLpe6GWgSYKgmQ/edit?usp=sharing',
//Tạo 1 bản sao của sheet này https://docs.google.com/spreadsheets/d/1mMCUvlM4Dq6fIevsZ_uvcwPwiZewoxLpe6GWgSYKgmQ/copy
//Sau đó chia sẻ sheet vừa tạo thêm quyền chỉnh sửa và lấy đường liên kết dán vào SHEET_URL
SHEET_TAB_NAME: 'Tắt campaign',
};
function main() {
const ss = SpreadsheetApp.openByUrl(CONFIG.SHEET_URL);
const DATE_RANGE = `'${getAdWordsFormattedDate(
CONFIG.LAST_N_DAYS,
'yyyy-MM-dd'
)}' AND '${getAdWordsFormattedDate(0, 'yyyy-MM-dd')}'`;
CONFIG.MAX_COST = CONFIG.MAX_COST * 1000000;
CONFIG.MAX_CPA = CONFIG.MAX_CPA * 1000000;
const campaigns = getCampaignReport(DATE_RANGE);
// append to sheet
const appendToSheetRow = Object.values(campaigns);
if (appendToSheetRow.length > 0) {
const sheet = ss.getSheetByName(CONFIG.SHEET_TAB_NAME);
if (sheet === null) {
console.log(
'Vui lòng copy tên của sheet tab vào biến SHEET_TAB_NAME trên cấu hình'
);
} else {
for (const item of appendToSheetRow) {
sheet.appendRow([
convertDateToShortDay(new Date()),
AdsApp.currentAccount().getName(),
item.campaign.id,
item.campaign.name,
item.advertisingChannelType,
item.metrics.impressions,
item.metrics.ctr,
item.cost,
item.metrics.conversions,
item.cpa,
]);
}
}
}
// sent email
if (CONFIG.EMAIL != '') {
var SUB = `${AdsApp.currentAccount().getName()} - Automatic remove bad audience`;
var BODY = `Hi\n\nPlease find below the report of Automatic remove bad audience which were excluded from the AdGroups:\n ${ss.getUrl()}\n\nThanks`;
MailApp.sendEmail(CONFIG.EMAIL, SUB, BODY);
}
}
function getCampaignReport(range) {
var query = `SELECT
campaign.target_cpa.target_cpa_micros,
campaign.status,
campaign.name,
metrics.conversions,
metrics.cost_micros,
metrics.impressions,
metrics.cost_per_conversion,
metrics.ctr,
campaign.advertising_channel_type,
campaign.id
FROM campaign
WHERE
metrics.cost_micros >= ${CONFIG.MAX_COST}
AND campaign.status = 'ENABLED'
AND segments.date BETWEEN ${range}
ORDER BY
metrics.cost_micros DESC`;
const report = AdsApp.search(query);
const results = {};
for (const row of report) {
const campaignId = row.campaign.id;
const conversions = parseFloat(row.metrics.conversions);
const cost = parseFloat(row.metrics.costMicros);
const costPerConversion = parseFloat(row.metrics.costPerConversion);
const cpa = conversions === 0 ? cost : costPerConversion;
row.cpa = Math.floor(cpa / 1000000);
row.cost = Math.floor(cost / 1000000);
if (
(conversions === 0 && cost >= CONFIG.MAX_COST) ||
cpa >= CONFIG.MAX_CPA
) {
if (!results.hasOwnProperty(campaignId)) {
results[campaignId] = {};
}
results[campaignId] = row;
}
}
return results;
}
function convertDateToShortDay(date) {
const dd = String(date.getDate()).padStart(2, '0');
const mm = String(date.getMonth() + 1).padStart(2, '0'); //January is 0!
const yyyy = date.getFullYear();
return dd + '/' + mm + '/' + yyyy;
}
function getAdWordsFormattedDate(d, format) {
var date = new Date();
date.setDate(date.getDate() - d);
return Utilities.formatDate(
date,
AdsApp.currentAccount().getTimeZone(),
format
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment