Adword Script to Pause All Enabled Campaigns Once Combined Cost for month is hit

885 views
Skip to first unread message

Joshua Klein

unread,
Dec 30, 2019, 9:36:02 AM12/30/19
to Google Ads Scripts Forum
Hi,

I have a script which I'm not sure if it's correct or not. I want to pause all enabled campaigns for the month once a total cost that I specify is hit. For example, I run 4 campaigns (A,B,C,D) on December 1 and by December 15 they collectively have a total cost of $15,000. I have a script that's set up to run hourly so that if the budget hits $14,850, all campaigns that are enabled would be paused. Can someone please check the following script and let me know where I made a mistake. Am I confusing the var MAX_Budget with TOTAL_COST? I currently use the script below for an account and the campaigns continued to run even though the MAX_Budget I set was 14850. I thought the campaigns would have been paused once the total cost hit 14850. Instead they are still enabled and I've exceeded the total cost I wanted to spend for the current month. Any help is greatly appreciated!

var MAX_Budget = 14850; //change the value as per your requirement


function main() {
  var currentBudget = 0;

  var selector = AdWordsApp.campaigns().withCondition("Status = ENABLED")
          .get();  


  while(selector.hasNext()) {
    var campaign = selector.next();

    currentBudget += campaign.getBudget().getAmount();
   
  Logger.log(currentBudget);
  if (currentBudget >= MAX_Budget) {

      campaign.pause();
      Logger.log("campaign paused" + campaign.getName());
    } 
  }
}

Sigurd

unread,
Dec 30, 2019, 10:04:58 AM12/30/19
to Google Ads Scripts Forum
Hi Joshua,

In Google Ads lingo, budget is the amount a campaign is allowed to spend while the cost is what it has spent already.

So, you should pause your campaigns when cost (not budget) is above your threshold

campaign.getBudget().getAmount() // instead of this you should rather fetch the cost for some period

Also note that AdWordsApp.campaigns() will not give you e.g. shopping campaigns - so you wouldn't necessarily pause all campaigns with this method


Happy coding

  sigurd

Joshua Klein

unread,
Dec 30, 2019, 10:38:33 AM12/30/19
to Google Ads Scripts Forum
Hi Sigurd, 

Thank you for the response! So should I use a completely new AW script? I have multiple campaigns that are agnostic of budget. What I'm trying to do is set a total cost for the month and if the campaigns collectively hit that number, all campaigns that are enabled become paused. 

Joshua Klein

unread,
Dec 30, 2019, 11:46:01 AM12/30/19
to Google Ads Scripts Forum
I found a script I believe should work. I'm only focusing on search: 
///////////////

var CUTOFF_COST = 1125;

var CUTOFF_LABEL = "Total Cost Cutoff";


function main() {


  if (AdWordsApp.currentAccount().getStatsFor("THIS_MONTH").getCost() > CUTOFF_COST) {


    pauseCampaign();

    pauseVideoCampaign();

  }

}


function pauseCampaign() {


  var label = AdWordsApp.labels().withCondition("Name='" + CUTOFF_LABEL + "'").get().next();


  var campaignIterator = label.campaigns().get();

  while (campaignIterator.hasNext()) {

    var campaign = campaignIterator.next();


    Logger.log(campaign.getName());

    campaign.pause();

  }

}


function pauseVideoCampaign() {

  var videoCampaignIterator = AdWordsApp.videoCampaigns()

  .withCondition("LabelNames CONTAINS_ANY ['" + CUTOFF_LABEL +"']")

  .get();

  while (videoCampaignIterator.hasNext()) {

    var videoCampaign = videoCampaignIterator.next();

    Logger.log(videoCampaign.getName());

    videoCampaign.pause();

Google Ads Scripts Forum Advisor

unread,
Dec 30, 2019, 3:03:16 PM12/30/19
to adwords-scripts+apn2wqfvgmtr1nlw...@googlegroups.com, adwords-scripts+apn2wqfvgmtr1nlw...@googlegroups.co, adwords...@googlegroups.com
Hi Joshua,

The most recent script you posted will pause search, display and video campaigns that have the 'Total Cost Cutoff' label. If this label is not applied to any campaigns, then the script will not pause any campaigns. Keep in mind this script will not re-enable any campaigns. If this functionality is desired, then I recommend having the script check to see if it is the first of the month, and if it is, re-enable all campaigns that have the label. Here is a useful guide for working with dates and times.

Regards,
Matt
Google Ads Scripts Team

ref:_00D1U1174p._5001UOFTkN:ref

Joshua Klein

unread,
Dec 30, 2019, 3:12:56 PM12/30/19
to Google Ads Scripts Forum
Hi Matt,

Thanks for the reply. What I'm trying to do is create a script that will pause all enabled campaigns if they hit a specific cost. Will the following work?


function main() {
  
  //update the value of monthlyBudget based on your requirement

  var monthlyBudget = 1980;


  var totalCost = 0;
  var campaignsList = [];
 
  var campaignIterator = AdWordsApp.campaigns()

      .withCondition('Name IN ["Brand","Prospecting"]') //you may change this depending on your requirement

      .get();
 
  while (campaignIterator.hasNext()) {
    var campaign = campaignIterator.next();
     //save in campaignsList the list of campaigns object.
    campaignsList.push(campaign);
    
    //use THIS_MONTH to get data for all days in the current month
    var stats = campaign.getStatsFor('THIS_MONTH');
    var campaignCost = stats.getCost();
    totalCost += campaignCost;
  }
 
  Logger.log("Combined Cost for this month: " +totalCost);
 
  //if totalCost is greater than or equal to monthlyBudget the campaigns specified above will be paused
  if (totalCost >= monthlyBudget){
    for (var i = 0; i < campaignsList.length; i++) {
      var campaign = campaignsList[i];
      Logger.log(campaign.getName())
      campaign.pause();

Google Ads Scripts Forum Advisor

unread,
Dec 30, 2019, 4:24:41 PM12/30/19
to adwords-scripts+apn2wqfvgmtr1nlw...@googlegroups.com, adwords-scripts+apn2wqfvgmtr1nlw...@googlegroups.co, adwords...@googlegroups.com
Hi Joshua,

Yes, the script will sum the cost of all campaigns in the selector, and if the sum exceeds the threshold, then all campaigns that were in that selector will be paused.

Sigurd

unread,
Dec 30, 2019, 4:57:56 PM12/30/19
to Google Ads Scripts Forum
Yeah, the last one should do it. 

You are also welcome to use this script I wrote  - it will do the same but also send you an email when it pauses campaigns

/*

Pause search and regular display campaigns when cost exceed a predefined threshold.
Send email notification when campaigns are paused.

Schedule script to run hourly.


*** Provided "as is" Use at your own peril. No warranty of any kind
 
You are welcome to use and share this code in it's entirety, including the warning above

 sigurd

*/

var settings = {
  
  timePeriod: 'LAST_30_DAYS', // more date range options here http://tiny.cc/10d6hz
  threshold: 500, // change to whatever amount
  
  notify: 'em...@example.com', // Optional. Get notifications when script pauses campaigns
  notifyCc: 'anothe...@example.com', // Optional. Also notify this email
  
}

function main() {
  var account = AdsApp.currentAccount();
  var cost = account.getStatsFor(settings.timePeriod).getCost();
  Logger.log('Threshold is set to: ' + settings.threshold + ', cost so far: ' + Math.round(cost) + ' during: ' + settings.timePeriod + '\n\n*\n\n')  
  if (cost > settings.threshold) {
    var campaignNames = [];
    var accountName = account.getName();
    var accountId = account.getCustomerId()
    var campaignIter = AdsApp.campaigns().get(); // this will not fetch e.g. shopping and app campaigns
    while (campaignIter.hasNext()) {
      var campaign = campaignIter.next();
      var campaignName = campaign.getName();
      campaignNames.push(campaignName);
      var campaignCost = campaign.getStatsFor(settings.timePeriod).getCost();
      campaign.pause()
      Logger.log(campaignName + ' Paused. Campaign cost: ' + campaignCost)
    }
  }
  else if (cost <= settings.threshold){
    Logger.log('Cost is below threshold so won\'t do anything this time. There\'re still ' + Math.round(settings.threshold-cost) + ' left to spend')
    }
  else {Logger.log('This shouldn\'t happen .. check your dates and threshold variables')}
 if(campaignNames.length > 0 && typeof(settings.notify) === 'string' && settings.notify.indexOf('@') !== -1){
    MailApp.sendEmail(settings.notify,campaignNames.length + ' campaigns in account: ' + accountId + ' have been paused by a script', 'Hi,\n\nA Google Ads script running in the Google Ads account  "' + 
                       accountName + '" has paused ' + campaignNames.length + ' campaigns because costs have exceeded the threshold.\n\nCost threshold is set to: ' + settings.threshold +
                        ' but the account has accrued costs of: ' + Math.round(cost) +
                        '\n\n*\n\nThese campaigns are now paused:\n\n' + campaignNames.join('\n'),{cc:settings.cc}
                       )
    Logger.log('\n\n*\n\nEmail sent to: ' + settings.notify + ', cc: ' + settings.cc)
    }
}

Joshua Klein

unread,
Dec 31, 2019, 7:30:03 AM12/31/19
to Google Ads Scripts Forum
Thank you!

Joshua Klein

unread,
Dec 31, 2019, 7:30:16 AM12/31/19
to Google Ads Scripts Forum
Thanks, Sigurd!

Joshua Klein

unread,
Dec 31, 2019, 2:21:07 PM12/31/19
to Google Ads Scripts Forum
If I wanted to continue using the script I have (below) but I wanted to receive an email ONLY if the campaign has been paused. What additional code would I need to add to the following:

function main() {
  //update the value of monthlyBudget based on your requirement

  var monthlyBudget = 2680;


  var totalCost = 0;
  var campaignsList = [];
 
  var campaignIterator = AdWordsApp.campaigns()

      .withCondition('Name IN ["Brand", "Prospecting"]') //you may change this depending on your requirement

      .get();
 
  while (campaignIterator.hasNext()) {
    var campaign = campaignIterator.next();
     //save in campaignsList the list of campaigns object.
    campaignsList.push(campaign);
    
    //use THIS_MONTH to get data for all days in the current month
    var stats = campaign.getStatsFor('THIS_MONTH');
    var campaignCost = stats.getCost();
    totalCost += campaignCost;
  }
 
  Logger.log("Combined Cost for this month: " +totalCost);

  //if totalCost is greater than or equal to monthlyBudget the campaigns specified above will be paused
  if (totalCost >= monthlyBudget){
    for (var i = 0; i < campaignsList.length; i++) {
      var campaign = campaignsList[i];
      Logger.log(campaign.getName())
      campaign.pause();
      
  //Email information

Google Ads Scripts Forum Advisor

unread,
Jan 2, 2020, 12:45:00 PM1/2/20
to adwords-scripts+apn2wqfvgmtr1nlw...@googlegroups.com, adwords-scripts+apn2wqfvgmtr1nlw...@googlegroups.co, adwords...@googlegroups.com
Hi Joshua,

Since campaigns are paused only if the budget is exceeded, you can insert the email function into that IF-block just before the for-loop:

  if (totalCost >= monthlyBudget){
    MailApp.sendEmail('exa...@example.com', 'your_subject', 'email_body');
    for (var i = 0; i < campaignsList.length; i++) {
      var campaign = campaignsList[i];
      Logger.log(campaign.getName())
      campaign.pause();

Regards,
Matt
Google Ads Scripts Team

 

ref:_00D1U1174p._5001UOFTkN:ref

Joshua Klein

unread,
Jan 9, 2020, 12:55:19 PM1/9/20
to Google Ads Scripts Forum
Thanks, Matt! I appreciate the support!
Reply all
Reply to author
Forward
0 new messages