Balance check automation for Google Ads
Our algorithm calculates how many days worth of advertising funds the budget has left and sends notifications to Telegram
Task
Digital Geeks have multiple accounts in Google Ads, managed by different specialists. If the money runs out in one of the accounts, the advertising campaign will be paused, so it is necessary to monitor the current balance.
Doing this manually is time-consuming and tedious. We decided to automate the process and create an algorithm that will send notifications about the remaining credit on Telegram.
Solution
We integrated Google Ads and Telegram using Google Ads script. It runs automatically and collects information about the remaining balance for each active advertising campaign (i.e., the one that received more than one click in the last two weeks).
The algorithm automatically determines the number of days worth of advertising funds in the account by calculating the average expenditures for the previous day and dividing the current balance by it.
If the budget has less than 5 days worth of advertising funds, the script sends a notification to the dedicated Telegram chat. The message contains the account’s name, the previous day's cost, the current balance and the number of days before the campaign is paused. This information can be sent not only to the messenger, but also by e-mail.
Results
Automation not only saves time for Digital Geeks employees, but also helps to minimize the impact of the human factor. Our solution insures customers against accidental pausing of advertising campaigns and losing leads.
You are free to use our code to automate checking of the remaining credit in your accounts.
Script for Google Ads

<pre>
<code>

var bud = 0

function main ()
{
     sendTelegramMessage('Budget check in Google Ads:', CHAT_ID);
  
  var accounts = MccApp.accounts()
  .withCondition("Clicks >= 1")
  .forDateRange("LAST_14_DAYS")
  .executeInParallel("budgetControl")

     Logger.log(bud);
     sendTelegramMessage('Budget check: complete', CHAT_ID);

}

function budgetControl()
{
  
 var accountName = AdWordsApp.currentAccount().getName();
 var budgets = AdWordsApp.budgetOrders().withCondition('Status = ACTIVE').get();
 while (budgets.hasNext())
   {
    try {
         var budget = budgets.next();
        if (budget.getSpendingLimit() !== null ) 
            {
              var startDate = timeFormat(budget.getStartDateTime());
              var cost = AdWordsApp.currentAccount().getStatsFor(startDate,today()).getCost().toFixed(2);
              var last7DaysCostByDay = (AdWordsApp.currentAccount().getStatsFor("YESTERDAY").getCost()).toFixed(2);
              var limit = budget.getSpendingLimit().toFixed(2);
              var remainingDays = rDays(limit, cost, last7DaysCostByDay);
              var budgetNow = (limit - cost).toFixed(2);
              
        if (budgetNow < 0)
          
        {
            var budgetNow = 0;
        }
              
        else 
        
        {
            var budgetNow = budgetNow;
        }
              
    Logger.log([accountName, limit, cost, budgetNow,last7DaysCostByDay,remainingDays]);
    
    if (remainingDays < 6 && last7DaysCostByDay >0) 
    
    {
    bud = 1

      sendTelegramMessage('Account ' + accountName+ '. Remaining days = ' + remainingDays + '.' + ' Current balance = ' + budgetNow + ' rubles.'+ ' Yesterday’s cost = ' + last7DaysCostByDay + ' rubles.',CHAT_ID);

        /*
    MailApp.sendEmail(CONFIG.email,
    CONFIG.names +' / Account budget is getting low: ' + accountName,
    'Account ' + accountName + ' . Current balance = ' + budgetNow +
    '. Cost per day = ' + last7DaysCostByDay + ' in the account currency. ' +
    'Budget has ' + remainingDays + 'day(s) worth of advertising funds. Account budget is getting low. It is necessary to warn the PM.');
    */
      
    }
    }
    }
    catch (e) 

    {

    Logger.log(e);

      sendTelegramMessage('Budget Control script error ' + accountName);
    //MailApp.sendEmail(CONFIG.email,
    //'Budget Control script error',
    //'Budget Control script check requested ' + accountName + ' ' + e);
      
    }
    }
  
}


function timeFormat (date)
  {
var year = date.year.toString();
var month = date.month.toString();
var day = date.day.toString();
  
  if (month.length == 1)
  
  {
  month = "0" + month;
  }
  if (day.length == 1) {
  day = "0" + day;
  }
  
  return [year, month, day].join("");
  }

function today () {
var date = new Date();
var timeZone = AdWordsApp.currentAccount().getTimeZone();
var format = 'yyyyMMdd';
return Utilities.formatDate(date, timeZone, format);
}
  
  
function rDays(limit, cost, last7DaysCostByDay) {
var remainingDays = ((limit - cost) / last7DaysCostByDay).toFixed();
if (remainingDays < 1 || remainingDays == "Infinity" || remainingDays == "-Infinity" || remainingDays == -0 ) {
remainingDays = 0;
}
return remainingDays;
}



function sendTelegramMessage(text, chat) {
var CONFIG2 = {
TOKEN: TOKEN_ID,
//CHAT_ID: '211002715'
  CHAT_ID: '-575137669'
  
};
var telegramUrl = 'https://api.telegram.org/bot' + CONFIG2.TOKEN + '/sendMessage?chat_id=' + chat + '&text=';
var message = encodeURIComponent(text);
var sendMessageUrl = telegramUrl + message;
var options = {
method: 'POST',
contentType: 'application/json'
};
  

   try {
      UrlFetchApp.fetch(sendMessageUrl, options);
  } catch (e) {
    // Logs an ERROR message.
       Logger.log(Error: ' +e);
    Logger.log('User: ' + chat);
  }
}

function rDays(limit, cost, last7DaysCostByDay) {
var remainingDays = ((limit - cost) / last7DaysCostByDay).toFixed();
if (remainingDays < 1 || remainingDays == "Infinity" || remainingDays == "-Infinity" || remainingDays == -0 ) {
remainingDays = 0;
}
return remainingDays;
}


</code>
</pre>