April 7, 2024

Інструкція по скрипту додавання автоправил

Данний скрипт підходить для нутри. Рекомендую видалити ваші інші автоправила, щоб все працювало без збою. Скрипт працює з адсетами, тому якщо у вас є інші адсети - можна просто вимикати кампанію/об'яву з цим адсетом (в такому випадку автоправила будуть активувати ваші адсети, але кампанія/об'ява у вас буде вимкнена вручну).

Ось які автоправила активуються скриптом:

- вимкнути адсет, якщо немає лідів та спенд > 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 хвилин (мінімальний час коли фб робить адпейд автоправилами) у вас може скрутити бюджет більший ніж ваша мінімальна ціна за лід.