Інструкція по скрипту додавання автоправил
Данний скрипт підходить для нутри. Рекомендую видалити ваші інші автоправила, щоб все працювало без збою. Скрипт працює з адсетами, тому якщо у вас є інші адсети - можна просто вимикати кампанію/об'яву з цим адсетом (в такому випадку автоправила будуть активувати ваші адсети, але кампанія/об'ява у вас буде вимкнена вручну).
Ось які автоправила активуються скриптом:
- вимкнути адсет, якщо немає лідів та спенд > Max CPA
- вимкнути адсет, якщо ціна за лід > Max CPA
- увімкнути всі адсети в заданий час
- включення адсетів при долітах лідів.
Ось приклад активованих скриптом автоправил:
Перед застосування скрипту, краще перевірити чи немає у вас інших автоправил:
Тепер заходимо в ads manager, правою кнопкою миші обираємо "перегляд коду" та переходимо в "консоль розробника"
і вводимо сюди код самого скрипту та жмакаємо Enter:
let api = 'https://graph.facebook.com/v14.0';
let headers = {
"accept": "*/*",
"accept-language": "en-US,en;q=0.9",
"content-type": "application/x-www-form-urlencoded",
"sec-ch-ua": "\"Google Chrome\";v=\"107\", \"Chromium\";v=\"107\", \"Not=A?Brand\";v=\"24\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site"
};
var cbo = await campUsesCBO();
await main(cbo);
async function campUsesCBO(){
let accountId = require("BusinessUnifiedNavigationContext").adAccountID;
let f = await fetch(`${api}/act_${accountId}/campaigns?fields=bid_strategy&access_token=${__accessToken}`, {
"headers": headers,
"referrer": "https://business.facebook.com/",
"referrerPolicy": "origin-when-cross-origin",
"body": null,
"method": "GET",
"mode": "cors",
"credentials": "include"
});
let camps = await f.json();
if (camps.data.length==0) return false;
if (camps.data[0]?.bid_strategy??null!=null)
return true;
return false;
}
async function main(cbo){
if (cbo)
alert("Your campaign uses CBO so we'll create auto-rules for campaigns!");
else
alert("Your campaign does NOT use CBO so we'll create rules for adsets!");
let accountId = require("BusinessUnifiedNavigationContext").adAccountID;
await clearRules(accountId);
let maxCPA = prompt('Please write your maximum CPA:');
if (maxCPA == null) {
alert('Max CPA not set, exiting...');
return;
}
let hour = parseInt(prompt(`At which hour should we switch ON ${cbo?"campaign":"adsets"}?`));
if (hour == null) {
alert('Switch ON hour not set, exiting...');
return;
}
let name = `TurnOff ${cbo?'Campaign':'Adset'} Withoud Leads`;
let evalSpec = {
"evaluation_type":"SCHEDULE",
"filters":[
{"field":"spent","operator":"GREATER_THAN","value":(maxCPA*100).toString()},
{"field":"offsite_conversion.fb_pixel_lead","operator":"LESS_THAN","value":"1"},
{"field":"entity_type","value":`${cbo?'CAMPAIGN':'ADSET'}`,"operator":"EQUAL"},
{"field":"time_preset","value":"TODAY","operator":"EQUAL"}
]};
let execSpec = {
"execution_type":"PAUSE",
"execution_options":[{"field":"alert_preferences","value":{"instant":{"trigger":"CHANGE"}},"operator":"EQUAL"}]
};
let schedSpec = {"schedule_type":"SEMI_HOURLY"};
await addRule(accountId, name, evalSpec, execSpec, schedSpec);
name = `TurnOff ${cbo?'Campaign':'Adset'} With Expensive Leads`;
evalSpec = {
"evaluation_type":"SCHEDULE",
"filters":[
{"field":"cost_per_lead_fb","operator":"GREATER_THAN","value":(maxCPA*100).toString()},
{"field":"entity_type","value":`${cbo?'CAMPAIGN':'ADSET'}`,"operator":"EQUAL"},
{"field":"time_preset","value":"TODAY","operator":"EQUAL"}
]
};
execSpec = {
"execution_type":"PAUSE",
"execution_options":[
{"field":"alert_preferences","value":{"instant":{"trigger":"CHANGE"}},"operator":"EQUAL"}
]};
await addRule(accountId, name, evalSpec, execSpec, schedSpec);
name = `TurnOn ${cbo?'Campaign':'Adset'} With Cheap Leads`;
evalSpec = {
"evaluation_type":"SCHEDULE",
"filters":[
{"field":"cost_per_lead_fb","operator":"LESS_THAN","value":(maxCPA*100).toString()},
{"field":"offsite_conversion.fb_pixel_lead","operator":"GREATER_THAN","value":"0"},
{"field":"entity_type","value":`${cbo?'CAMPAIGN':'ADSET'}`,"operator":"EQUAL"},
{"field":"time_preset","value":"TODAY","operator":"EQUAL"}
]
};
execSpec = {
"execution_type":"UNPAUSE",
"execution_options":[
{"field":"alert_preferences","value":{"instant":{"trigger":"CHANGE"}},"operator":"EQUAL"}
]};
await addRule(accountId, name, evalSpec, execSpec, schedSpec);
name = `TurnOn All ${cbo?'Campaigns':'Adsets'} at ${hour}`;
evalSpec = {
"evaluation_type":"SCHEDULE",
"filters":[{"field":"entity_type","value":`${cbo?'CAMPAIGN':'ADSET'}`,"operator":"EQUAL"},{"field":"time_preset","value":"MAXIMUM","operator":"EQUAL"}]
};
execSpec = {
"execution_type":"UNPAUSE",
"execution_options":[
{"field":"alert_preferences","value":{"instant":{"trigger":"CHANGE"}},"operator":"EQUAL"}
]};
schedSpec = {
"schedule_type":"CUSTOM",
"schedule":[
{"days":[0],"start_minute":hour*60,"end_minute":hour*60},
{"days":[1],"start_minute":hour*60,"end_minute":hour*60},
{"days":[2],"start_minute":hour*60,"end_minute":hour*60},
{"days":[3],"start_minute":hour*60,"end_minute":hour*60},
{"days":[4],"start_minute":hour*60,"end_minute":hour*60},
{"days":[5],"start_minute":hour*60,"end_minute":hour*60},
{"days":[6],"start_minute":hour*60,"end_minute":hour*60}
]
};
await addRule(accountId, name, evalSpec, execSpec, schedSpec);
let createCpcRules = confirm('Do you want to create rules based on Max CPC?');
if (createCpcRules){
let maxCPC = prompt("Enter your maximum CPC (for example 0.13):");
let maxClicks = prompt(`Enter clicks limit after which the ${cbo?'campaign':'adset'} will be shut down:`);
name = `TurnOff ${cbo?'Campaign':'Adset'} With Expensive CPC`;
evalSpec = {
"evaluation_type":"SCHEDULE",
"filters":[
{"field":"clicks","operator":"GREATER_THAN","value":(maxClicks).toString()},
{"field":"cpc","operator":"GREATER_THAN","value":(maxCPC*100).toString()},
{"field":"entity_type","value":`${cbo?'CAMPAIGN':'ADSET'}`,"operator":"EQUAL"},
{"field":"time_preset","value":"TODAY","operator":"EQUAL"}
]};
execSpec = {
"execution_type":"PAUSE",
"execution_options":[{"field":"alert_preferences","value":{"instant":{"trigger":"CHANGE"}},"operator":"EQUAL"}]
};
schedSpec = {"schedule_type":"SEMI_HOURLY"};
await addRule(accountId, name, evalSpec, execSpec, schedSpec);
}
let createCpmRules = confirm('Do you want to create rules based on Max CPM?');
if (createCpmRules){
let maxCPM = prompt("Enter your maximum CPM:");
let maxImpressions = prompt(`Enter your maximum impressions after which the ${cbo?'campaign':'adset'} will be shut down:`);
name = `TurnOff ${cbo?'Campaign':'Adset'} With Expensive CPM`;
evalSpec = {
"evaluation_type":"SCHEDULE",
"filters":[
{"field":"impressions","operator":"GREATER_THAN","value":maxImpressions.toString()},
{"field":"cpm","operator":"GREATER_THAN","value":(maxCPM*100).toString()},
{"field":"entity_type","value":`${cbo?'CAMPAIGN':'ADSET'}`,"operator":"EQUAL"},
{"field":"time_preset","value":"TODAY","operator":"EQUAL"}
]};
execSpec = {
"execution_type":"PAUSE",
"execution_options":[{"field":"alert_preferences","value":{"instant":{"trigger":"CHANGE"}},"operator":"EQUAL"}]
};
schedSpec = {"schedule_type":"SEMI_HOURLY"};
await addRule(accountId, name, evalSpec, execSpec, schedSpec);
}
alert('All Done!');
}
async function getAllRules(accountId){
let f = await fetch(`${api}/act_${accountId}/adrules_library?access_token=${__accessToken}`, {
"headers": headers,
"referrer": "https://business.facebook.com/",
"referrerPolicy": "origin-when-cross-origin",
"body": null,
"method": "GET",
"mode": "cors",
"credentials": "include"
});
let rules = await f.json();
return rules;
}
async function deleteRule(ruleId){
let f = await fetch(`${api}/${ruleId}?access_token=${__accessToken}&method=delete`, {
"headers": headers,
"referrer": "https://business.facebook.com/",
"referrerPolicy": "origin-when-cross-origin",
"body": "method=delete",
"method": "POST",
"mode": "cors",
"credentials": "include"
});
let js = await f.json();
console.log(js);
}
async function clearRules(accountId){
let rules = await getAllRules(accountId);
let rulesCount = rules.data.length;
if (rulesCount==0) return;
let clear = confirm(`Do you want to clear all existing autorules (${rulesCount} found)?`);
if (!clear) return;
console.log(`Deleting ${rulesCount} rules.`);
for (const rule of rules.data) {
console.log(`Deleting rule ${JSON.stringify(rule)}...`);
await deleteRule(rule['id']);
};
}
async function addRule(accountId, name, evalSpec, execSpec, schedSpec){
let body = {
"locale":"en_US",
"evaluation_spec":JSON.stringify(evalSpec),
"execution_spec":JSON.stringify(execSpec),
"name":name,
"schedule_spec":JSON.stringify(schedSpec),
"access_token":__accessToken,
"status":"ENABLED"
};
let f = await fetch(`${api}/act_${accountId}/adrules_library?access_token=${__accessToken}`, {
"headers": headers,
"referrer": "https://business.facebook.com/",
"referrerPolicy": "origin-when-cross-origin",
"body": new URLSearchParams(body).toString(),
"method": "POST",
"mode": "cors",
"credentials": "include"
});
let json = await f.json();
console.log(`${name}: ${JSON.stringify(json)}`);
return json;
}
Ну і далі просто заповнюємо дані
В принципі я заповнюю тільки "Maximum CPA" (ваша максимальна ціна за лід) та ставлю час ввімкнення автоправил - 00.00.
Ну і все ) Наблюдайте як працюють автоправила замість вас ).
PS. Але майте на увазі, так як автоправила неможна виставити на період часу менш ніж 30 хвилин, то при високому бюджеті у вас можливий перекрут. Наприклад бюджет в день у вас більше 500$, а в автоправилах у вас максимальна ціна за лід 6$, то за 30 хвилин (мінімальний час коли фб робить адпейд автоправилами) у вас може скрутити бюджет більший ніж ваша мінімальна ціна за лід.