-
-
Save dvygolov/c2077f391bd15ba2f75d7496afb47a67 to your computer and use it in GitHub Desktop.
| 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; | |
| } |
What a wonderful script! You're just GENIUS! Now I spend not 8 hours working a day but only 3 for run ads and then after all I do just chill
What a wonderful script! You're just GENIUS! Now I spend not 8 hours working a day but only 3 for run ads and then after all I do just chill
Haha, if that's true - lucky you are!
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
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)
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 :)
Sadly it doesn't work anymore :c
Sadly it doesn't work anymore :c
What exactly doesnt' work?
Use this service to create a one-liner from this script.
After you got a one-liner use
javascript: (async () => { one-liner })();to create a bookmarklet.