Skip to content

Instantly share code, notes, and snippets.

@dvygolov
Last active March 30, 2025 19:37
Show Gist options
  • Select an option

  • Save dvygolov/c2077f391bd15ba2f75d7496afb47a67 to your computer and use it in GitHub Desktop.

Select an option

Save dvygolov/c2077f391bd15ba2f75d7496afb47a67 to your computer and use it in GitHub Desktop.
This script adds 4 (+2) Facebook Autorules, read comment below
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;
}
@veinsis
Copy link

veinsis commented Nov 28, 2022

Yeah I am so happy find your scripts. My work became so easy. You should give me a chance to donate you bro, I didn't found where you collect donations

No problem, USDT TRC20: TKeNEVndhPSKXuYmpEwF4fVtWUvfCnWmra and thanks in advance)

Donated. Thank you for making my work more easier :)

@veinsis
Copy link

veinsis commented Jan 1, 2024

Sadly it doesn't work anymore :c

@dvygolov
Copy link
Author

Sadly it doesn't work anymore :c

What exactly doesnt' work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment