Ads Manager Scripts

  • Accounts can be retrieved using AdsManagerApp.accounts().get(), by specific IDs using withIds(), or by label using withCondition("LabelNames...").

  • Multiple accounts can be updated either in series by iterating through a selection and using AdsManagerApp.select(account), or in parallel for larger tasks using executeInParallel().

  • Updating accounts in parallel with executeInParallel() involves a main function to select accounts and specify a function (processAccount) to be run on each account, with an optional callback function (allFinished) for post-processing results.

  • The processAccount function, called by executeInParallel(), automatically switches the context to the selected account, allowing direct use of AdsApp calls for operations within that account.

Get all accounts

function getAllAccounts() {  const accountIterator = AdsManagerApp.accounts().get();  for (const account of accountIterator) {  const accountName = account.getName() ? account.getName() : '--';  console.log('%s,%s,%s,%s', account.getCustomerId(), accountName,  account.getTimeZone(), account.getCurrencyCode());  } }

Get accounts from customer IDs

function getAccountsFromCustomerIds() {  // This is useful when you are reading customer IDs from an external data  // source, such as a Google Spreadsheet.  // You can also use the condition "CustomerId in ['123-456-7890',  // '345-678-9000', '890-123-6000']".  const accountIterator = AdsManagerApp.accounts()  .withIds(['123-456-7890', '345-678-9000', '890-123-6000'])  .get();  for (const account of accountIterator) {  const accountName = account.getName() ? account.getName() : '--';  console.log('%s,%s,%s,%s', account.getCustomerId(), accountName,  account.getTimeZone(), account.getCurrencyCode());  } }

Get accounts by label

function getAccountsByLabel() {  // Only CONTAINS and DOES_NOT_CONTAIN operators are supported.  const accountIterator = AdsManagerApp.accounts()  .withCondition("LabelNames CONTAINS 'High spend accounts'")  .get();  for (const account of accountIterator) {  const accountName = account.getName() ? account.getName() : '--';  console.log('%s,%s,%s,%s', account.getCustomerId(), accountName,  account.getTimeZone(), account.getCurrencyCode());  } }

Update multiple accounts in series

function updateAccountsInSeries() {  // You can use this approach when you have only minimal processing to  // perform in each of your client accounts.  // Select the accounts to be processed.  const accountIterator = AdsManagerApp.accounts()  .withCondition("LabelNames CONTAINS 'Cars'")  .get();  for (const account of accountIterator) {  // Switch to the account you want to process.  AdsManagerApp.select(account);  // Retrieve all Search and Display campaigns to be paused.  const campaignIterator = AdsApp.campaigns()  .withCondition("LabelNames = 'Christmas promotion'")  .get();  for (const campaign of campaignIterator) {  console.log(`Pausing campaign ${campaign.getName()} in ` +  `account ${account.getCustomerId()}`);  campaign.pause();  }  } }

Update multiple accounts in parallel

function updateAccountsInParallel() {  // You can use this approach when you have a large amount of processing  // to do in each of your client accounts.  // Select the accounts to be processed. You can process up to 50 accounts.  const accountSelector = AdsManagerApp.accounts()  .withCondition("LabelNames CONTAINS 'High spend accounts'")  .withLimit(50);  // Process the account in parallel. The 'processAccount' function will  // be called in the context of each account in the selector. The 'allFinished' function  // will be called in this script once processing is complete, and is optional.  accountSelector.executeInParallel('processAccount', 'allFinished'); } /**  * Process one account at a time. This method is called by the executeInParallel  * method call in updateAccountsInParallel function for every account that  * it processes.  *  * @return {Number} the number of campaigns paused by this method.  */ function processAccount() {  // executeInParallel will automatically switch context to the account being  // processed, so all calls to AdsApp will apply to the selected account.  const campaignIterator = AdsApp.campaigns()  .withCondition("LabelNames = 'Christmas promotion'")  .get();  for (const campaign of campaignIterator) {  console.log(`Pausing campaign ${campaign.getName()} in ` +  `account ${account.getCustomerId()}`);  campaign.pause();  }  // Optional: return a string value. If you have a more complex JavaScript  // object to return from this method, use JSON.stringify(value). This value  // will be passed on to the callback method, if specified, in the  // executeInParallel method call.  return campaignIterator.totalNumEntities().toFixed(0); } /**  * Post-process the results from processAccount. This method will be called  * once all the accounts have been processed by the executeInParallel method  * call.  *  * @param {Array.<ExecutionResult>} results An array of ExecutionResult objects,  * one for each account that was processed by the executeInParallel method.  */ function allFinished(results) {  for (const result of results) {  console.log(`Customer ID: ${result.getCustomerId}; ` +  `status = ${result.getStatus}.`);  // Check the execution status. This can be one of ERROR, OK, or TIMEOUT.  if (result.getStatus() == 'ERROR') {  console.log(`-- Failed with error: '${result.getError()}'.`);  } else if (result.getStatus() == 'OK') {  // This is the value you returned from processAccount method. If you  // used JSON.stringify(value) in processAccount, you can use  // JSON.parse(text) to reconstruct the JavaScript object.  const retval = result.getReturnValue();  console.log(`--Processed ${retval} campaigns.`);  } else {  // Handle timeouts here.  }  } }