Websites promotion & analytics

Select your language

Ask a question +38 096 558 7514

Scripts in Google Ads

Nobody really thinks about automating things until there's a ton of repetitive tasks piling up. It's the same story with contextual advertising. That's when Google Ads scripts come to the rescue.

Google Ads scripts are nifty little programs that let you control your Google Ads account's functions using JavaScript, all without you having to do it manually.

Important note! "Without you having to do it manually" means you can set them to run as often as every hour or as seldom as once a month, and you don't need to log into your account to perform specific tasks. The script will handle it all for you.

In your Google Ads account, scripts are pretty easy to find:

Tools ➔ Bulk Actions ➔ Scripts<

After that, you'll see an open JavaScript editor where you can start working your magic.

Scripts in Google Ads

The possibilities with scripts are huge. From basic notifications to performing active tasks in your account, they can do a lot. We've been through it all ourselves since we write our own scripts for Google Ads to streamline our workflow.

You'll find loads of free scripts online, but most of them are pretty generic. We found that out of thousands of free scripts, only 2 or 3 were actually useful to us:

Script to notify about low account balance

The mechanism is pretty straightforward: if your account balance dips below a certain amount, you get an email alert. The script looks like this:


    function main() {
  //Script settings
  var days = 7; // Minimum number of days to send notification
  var alertLimit = 30000; // Minimum balance to send notification
  var email = [' This email address is being protected from spambots. You need JavaScript enabled to view it.']; //Add email addresses to receive the alert
  var alertType = true; // true - alert when low balance, false - alert based on number of days
  var includeVAT = true;
  var budgetOrder = AdWordsApp.budgetOrders().get().next();
  var SpendingLimit = budgetOrder.getSpendingLimit(); // Total account limit
  var adjustments = budgetOrder.getTotalAdjustments(); // Funds returned to account
  var Spent = AdWordsApp.currentAccount().getStatsFor('ALL_TIME').getCost(); // All-time spend
  var lastWeekSpent = AdWordsApp.currentAccount().getStatsFor('LAST_7_DAYS').getCost(); // Spend in last 7 days
  var thisMonthSpent = AdWordsApp.currentAccount().getStatsFor('THIS_MONTH').getCost();
  var vat = thisMonthSpent * 0.2;
  var limit = budgetOrder.getSpendingLimit();
  var spent = AdWordsApp.currentAccount().getStatsFor('ALL_TIME').getCost();
  var amountOfBudget = limit - spent+388;  
  Logger.log("Account balance - " + amountOfBudget);
  if (alertType) {
    if (amountOfBudget < alertLimit) {
      sendSimpleTextEmail(email);
    }
  }

  function sendSimpleTextEmail(mail) {
    MailApp.sendEmail( mail,
                      'Low Budget Alert! ' + AdWordsApp.currentAccount().getName(),
                      'Funds are running low in the Holostenko & Partners account. Please add funds!');    
  }
} 
    

This script is super helpful if you frequently top up your balance or if you don't check into Google Ads very often.

Script to pause ads with no impressions


    var TO_NOTIFY = "This email address is being protected from spambots. You need JavaScript enabled to view it.";
function main() {
  var kwIter = AdWordsApp.keywords()
    .withCondition("Impressions = 0") // could be "Clicks = 0" also
    .forDateRange("ALL_TIME")
    .withCondition("Status = ENABLED")
    .withCondition("CampaignStatus = ENABLED")
    .withCondition("AdGroupStatus = ENABLED")
    .get();
  var toPause = [];
  while (kwIter.hasNext()) {
    var kw = kwIter.next();
    toPause.push(kw);
    if(AdWordsApp.getExecutionInfo().isPreview() &&
       AdWordsApp.getExecutionInfo().getRemainingTime() < 10) {
      break;
    }
  }
  for(var i in toPause) {
    toPause[i].pause();
    //Or you can use toPause[i].remove(); to delete the ad
  }
  // Send notification email
  MailApp.sendEmail(TO_NOTIFY, 
                    "AdWords Script Paused "+toPause.length+" Keywords.", 
                    "Your AdWords Script paused "+toPause.length+" keywords.");
}
  

This script lets you clean up ads — thousands of them that haven't received any impressions, and doing it manually would be a real pain.

Script to pause and resume campaigns on holidays


Pausing campaigns:

function main() {
  var searchdisplaycampIter = AdsApp.campaigns().withCondition("LabelNames CONTAINS_ALL ['holidays']").get()
  while(searchdisplaycampIter.hasNext()){
    var searchdisplaycamp = searchdisplaycampIter.next()
    searchdisplaycamp.pause()
  }
  
  var videocampIter = AdsApp.videoCampaigns().withCondition("LabelNames CONTAINS_ALL ['holidays']").get()
  while(videocampIter.hasNext()){
    var videocamp = videocampIter.next()
    videocamp.pause()
  }
  
  var shopcampIter = AdsApp.shoppingCampaigns().withCondition("LabelNames CONTAINS_ALL ['holidays']").get()
  while(shopcampIter.hasNext()){
    var shopcamp = shopcampIter.next()
    shopcamp.pause()
  }
}

Resuming campaigns:

function main() {
  var searchdisplaycampIter = AdsApp.campaigns().withCondition("LabelNames CONTAINS_ALL ['holidays']").get()
  while(searchdisplaycampIter.hasNext()){
    var searchdisplaycamp = searchdisplaycampIter.next()
    searchdisplaycamp.enable()
    searchdisplaycamp.removeLabel('holidays')
  }
  
  var videocampIter = AdsApp.videoCampaigns().withCondition("LabelNames CONTAINS_ALL ['holidays']").get()
  while(videocampIter.hasNext()){
    var videocamp = videocampIter.next()
    videocamp.enable()
    videocamp.removeLabel('holidays')
  }
  
  var shopcampIter = AdsApp.shoppingCampaigns().withCondition("LabelNames CONTAINS_ALL ['holidays']").get()
  while(shopcampIter.hasNext()){
    var shopcamp = shopcampIter.next()
    shopcamp.enable()
    shopcamp.removeLabel('holidays')
  }
}

Both scripts run according to a set schedule.
  

If you've got bids at the keyword level and need to maintain a specific position, this is a great option for hourly adjustments—or however you set it up.

You can find more free solutions on www.freeadwordsscripts.com.

But these are all standard free solutions that don't always hit the mark. That's why we started developing our own.

As an agency, we discovered ways to make working with contextual advertising more comfortable:

  • Hourly monitoring of campaign daily budgets, which lets us manage very active accounts with limited budgets.
  • Daily tracking of expenses and other metrics, with notifications for any issues or unusual situations.
  • Hourly bid adjustments at the ad group level (or keyword level).
  • Plus a bunch of other custom tweaks.

Google Scripts open up new possibilities for automation when standard automated rules just don't cut it. That's why we dove into working with scripts—it allows us to be more flexible and dynamic.

Custom scripts made to order

Custom scripts Google Ads

For online stores, projects with large accounts, or even small and medium businesses, we offer services to write Google Ads scripts tailored to your needs. You give us the logical task, and we'll handle the execution. For more details, send us a request or get in touch via the agency's contact numbers.

* For clients on the Ultra package, our custom-developed scripts for controlling contextual advertising are available by default.

If you have any questions about our services, please write how to contact you and briefly describe your business.

* Your personal data is completely protected and will not be disclosed to third parties.

Please select the best way to contact you.

  • United States+1
  • United Kingdom+44
  • Afghanistan (‫افغانستان‬‎)+93
  • Albania (Shqipëri)+355
  • Algeria (‫الجزائر‬‎)+213
  • American Samoa+1
  • Andorra+376
  • Angola+244
  • Anguilla+1
  • Antigua and Barbuda+1
  • Argentina+54
  • Armenia (Հայաստան)+374
  • Aruba+297
  • Ascension Island+247
  • Australia+61
  • Austria (Österreich)+43
  • Azerbaijan (Azərbaycan)+994
  • Bahamas+1
  • Bahrain (‫البحرين‬‎)+973
  • Bangladesh (বাংলাদেশ)+880
  • Barbados+1
  • Belarus (Беларусь)+375
  • Belgium (België)+32
  • Belize+501
  • Benin (Bénin)+229
  • Bermuda+1
  • Bhutan (འབྲུག)+975
  • Bolivia+591
  • Bosnia and Herzegovina (Босна и Херцеговина)+387
  • Botswana+267
  • Brazil (Brasil)+55
  • British Indian Ocean Territory+246
  • British Virgin Islands+1
  • Brunei+673
  • Bulgaria (България)+359
  • Burkina Faso+226
  • Burundi (Uburundi)+257
  • Cambodia (កម្ពុជា)+855
  • Cameroon (Cameroun)+237
  • Canada+1
  • Cape Verde (Kabu Verdi)+238
  • Caribbean Netherlands+599
  • Cayman Islands+1
  • Central African Republic (République centrafricaine)+236
  • Chad (Tchad)+235
  • Chile+56
  • China (中国)+86
  • Christmas Island+61
  • Cocos (Keeling) Islands+61
  • Colombia+57
  • Comoros (‫جزر القمر‬‎)+269
  • Congo (DRC) (Jamhuri ya Kidemokrasia ya Kongo)+243
  • Congo (Republic) (Congo-Brazzaville)+242
  • Cook Islands+682
  • Costa Rica+506
  • Côte d’Ivoire+225
  • Croatia (Hrvatska)+385
  • Cuba+53
  • Curaçao+599
  • Cyprus (Κύπρος)+357
  • Czech Republic (Česká republika)+420
  • Denmark (Danmark)+45
  • Djibouti+253
  • Dominica+1
  • Dominican Republic (República Dominicana)+1
  • Ecuador+593
  • Egypt (‫مصر‬‎)+20
  • El Salvador+503
  • Equatorial Guinea (Guinea Ecuatorial)+240
  • Eritrea+291
  • Estonia (Eesti)+372
  • Eswatini+268
  • Ethiopia+251
  • Falkland Islands (Islas Malvinas)+500
  • Faroe Islands (Føroyar)+298
  • Fiji+679
  • Finland (Suomi)+358
  • France+33
  • French Guiana (Guyane française)+594
  • French Polynesia (Polynésie française)+689
  • Gabon+241
  • Gambia+220
  • Georgia (საქართველო)+995
  • Germany (Deutschland)+49
  • Ghana (Gaana)+233
  • Gibraltar+350
  • Greece (Ελλάδα)+30
  • Greenland (Kalaallit Nunaat)+299
  • Grenada+1
  • Guadeloupe+590
  • Guam+1
  • Guatemala+502
  • Guernsey+44
  • Guinea (Guinée)+224
  • Guinea-Bissau (Guiné Bissau)+245
  • Guyana+592
  • Haiti+509
  • Honduras+504
  • Hong Kong (香港)+852
  • Hungary (Magyarország)+36
  • Iceland (Ísland)+354
  • India (भारत)+91
  • Indonesia+62
  • Iran (‫ایران‬‎)+98
  • Iraq (‫العراق‬‎)+964
  • Ireland+353
  • Isle of Man+44
  • Israel (‫ישראל‬‎)+972
  • Italy (Italia)+39
  • Jamaica+1
  • Japan (日本)+81
  • Jersey+44
  • Jordan (‫الأردن‬‎)+962
  • Kazakhstan (Казахстан)+7
  • Kenya+254
  • Kiribati+686
  • Kosovo+383
  • Kuwait (‫الكويت‬‎)+965
  • Kyrgyzstan (Кыргызстан)+996
  • Laos (ລາວ)+856
  • Latvia (Latvija)+371
  • Lebanon (‫لبنان‬‎)+961
  • Lesotho+266
  • Liberia+231
  • Libya (‫ليبيا‬‎)+218
  • Liechtenstein+423
  • Lithuania (Lietuva)+370
  • Luxembourg+352
  • Macau (澳門)+853
  • North Macedonia (Македонија)+389
  • Madagascar (Madagasikara)+261
  • Malawi+265
  • Malaysia+60
  • Maldives+960
  • Mali+223
  • Malta+356
  • Marshall Islands+692
  • Martinique+596
  • Mauritania (‫موريتانيا‬‎)+222
  • Mauritius (Moris)+230
  • Mayotte+262
  • Mexico (México)+52
  • Micronesia+691
  • Moldova (Republica Moldova)+373
  • Monaco+377
  • Mongolia (Монгол)+976
  • Montenegro (Crna Gora)+382
  • Montserrat+1
  • Morocco (‫المغرب‬‎)+212
  • Mozambique (Moçambique)+258
  • Myanmar (Burma) (မြန်မာ)+95
  • Namibia (Namibië)+264
  • Nauru+674
  • Nepal (नेपाल)+977
  • Netherlands (Nederland)+31
  • New Caledonia (Nouvelle-Calédonie)+687
  • New Zealand+64
  • Nicaragua+505
  • Niger (Nijar)+227
  • Nigeria+234
  • Niue+683
  • Norfolk Island+672
  • North Korea (조선 민주주의 인민 공화국)+850
  • Northern Mariana Islands+1
  • Norway (Norge)+47
  • Oman (‫عُمان‬‎)+968
  • Pakistan (‫پاکستان‬‎)+92
  • Palau+680
  • Palestine (‫فلسطين‬‎)+970
  • Panama (Panamá)+507
  • Papua New Guinea+675
  • Paraguay+595
  • Peru (Perú)+51
  • Philippines+63
  • Poland (Polska)+48
  • Portugal+351
  • Puerto Rico+1
  • Qatar (‫قطر‬‎)+974
  • Réunion (La Réunion)+262
  • Romania (România)+40
  • Russia (Россия)+7
  • Rwanda+250
  • Saint Barthélemy+590
  • Saint Helena+290
  • Saint Kitts and Nevis+1
  • Saint Lucia+1
  • Saint Martin (Saint-Martin (partie française))+590
  • Saint Pierre and Miquelon (Saint-Pierre-et-Miquelon)+508
  • Saint Vincent and the Grenadines+1
  • Samoa+685
  • San Marino+378
  • São Tomé and Príncipe (São Tomé e Príncipe)+239
  • Saudi Arabia (‫المملكة العربية السعودية‬‎)+966
  • Senegal (Sénégal)+221
  • Serbia (Србија)+381
  • Seychelles+248
  • Sierra Leone+232
  • Singapore+65
  • Sint Maarten+1
  • Slovakia (Slovensko)+421
  • Slovenia (Slovenija)+386
  • Solomon Islands+677
  • Somalia (Soomaaliya)+252
  • South Africa+27
  • South Korea (대한민국)+82
  • South Sudan (‫جنوب السودان‬‎)+211
  • Spain (España)+34
  • Sri Lanka (ශ්‍රී ලංකාව)+94
  • Sudan (‫السودان‬‎)+249
  • Suriname+597
  • Svalbard and Jan Mayen+47
  • Sweden (Sverige)+46
  • Switzerland (Schweiz)+41
  • Syria (‫سوريا‬‎)+963
  • Taiwan (台灣)+886
  • Tajikistan+992
  • Tanzania+255
  • Thailand (ไทย)+66
  • Timor-Leste+670
  • Togo+228
  • Tokelau+690
  • Tonga+676
  • Trinidad and Tobago+1
  • Tunisia (‫تونس‬‎)+216
  • Turkey (Türkiye)+90
  • Turkmenistan+993
  • Turks and Caicos Islands+1
  • Tuvalu+688
  • U.S. Virgin Islands+1
  • Uganda+256
  • Ukraine (Україна)+380
  • United Arab Emirates (‫الإمارات العربية المتحدة‬‎)+971
  • United Kingdom+44
  • United States+1
  • Uruguay+598
  • Uzbekistan (Oʻzbekiston)+998
  • Vanuatu+678
  • Vatican City (Città del Vaticano)+39
  • Venezuela+58
  • Vietnam (Việt Nam)+84
  • Wallis and Futuna (Wallis-et-Futuna)+681
  • Western Sahara (‫الصحراء الغربية‬‎)+212
  • Yemen (‫اليمن‬‎)+967
  • Zambia+260
  • Zimbabwe+263
  • Åland Islands+358
Thanks! Your message has been sent.
Sending failed. Please fix the errors and try again.