The script checks all the entries in your accounts’ Google Ads change history installed at the MCC level. If a user changes outside of your list of ‘recognized’ users or your ‘domain’, you will get an alert via email. The alert mail contains the number of changes and a link to the Google Sheet that lists all changes by unrecognized users.

Follow on Github: https://github.com/andrew-Clicktrain/ppc-listenr-script/blob/main/main.js

/**
*
* The Ultimate Change History MCC Script
*
* The script checks all the entries in the Google Ads change history of your accounts and installed at the MCC level, 
* and if there is a change by a user outside of your list of 'recognized' users or your 'domain', you will get an alert via email.
* The alert mail contains the number of changes as well as a link to the Google Sheet that lists all changes by unrecognized users.
*
* 
* @initalAuthor: Nils Rooijmans
* 
* Branched Version 2.0
* @author: Andrew Bloch
* 
* For more features like specific user insights and predicted hours visit - clicktrain.com/ppc-tool/
*/


// CHANGE SETTINGS HERE

var spreadsheetId = ""; // Insert the ID of the new blank main spreadsheet between the double quotes
var emailAddresses = "andrew@test.com"; 
var yourDomain = "test.com"; 

var ignoreUsers = [
  'john@doe.com'
];

// NOTE: if you want to add multiple users, one per line, with a comma separating the lines. I.e.:
// var ignoreUsers = [
// 'john@doe.com',
// 'jane@doe.com',
// 'jill@johns.com'
// ];
var period = "YESTERDAY";
var sendMail = true;
var emailSubject = "PPCListenr - WARNING - Change by person outside of the Agency";
var emailBody =
  "\n" +
  "***\n" +
  "\n" +
  "This script checks changes in the 'Change history':\n" +
  "\n" +
  "For all changes during " + period + "\n" +
  "   check if there is a change being made by users other than " + ignoreUsers + "\n" +
  "   if so, alerts are logged in Google Sheet: https://docs.google.com/spreadsheets/d/" + spreadsheetId + "\n" +
  "\n" +
  "If there is an alert, an email is sent to:\n" + emailAddresses + "\n";



function main() {

    prepareOutputSheet(true) 

    var ids = [];   
    var accounts = MccApp.accounts().get();
    while (accounts.hasNext() && ids.length < 50) {
      var account = accounts.next();
      var customerId = account.getCustomerId();
    
        ids.push(customerId);
      
    }

  
    MccApp.accounts().withIds(ids).executeInParallel(
      'getChangeAlerts')
  }


function getChangeAlerts() {

    var accountName = AdsApp.currentAccount().getName();
  
    var changeAlerts = [];
  
    var query = "SELECT " +
      "campaign.name, " +
      "change_event.change_date_time, " +
      "asset.type, " +
      "change_event.change_resource_type, " +
      "change_event.changed_fields, " +
      "change_event.user_email " +
      "FROM change_event " +
      "WHERE change_event.change_date_time DURING " + period + " " +
      "AND change_event.user_email NOT REGEXP_MATCH '.*@" + yourDomain + "' " +
      "AND change_event.user_email NOT IN ('"+ignoreUsers.join("', '")+"') "+
      "AND change_event.client_type IN ('GOOGLE_ADS_RECOMMENDATIONS', 'GOOGLE_ADS_WEB_CLIENT')" +
      "ORDER BY change_event.change_date_time DESC " +
      "LIMIT 9999 "; // Max of 10k changes reported per request
  

    try {
      var result = AdsApp.search(query);
    } catch (e) {
      alert("Issue retrieving results from search API: " + e);
    }

    while (result.hasNext()) {
      var row = result.next();
      
      var campaignName = "";
      var assetType = "";
  
      try {
        campaignName = row.campaign.name;
      } catch (e) {}

      try {
        assetType = row.asset.type;
      } catch (e) {}
  

      if (!campaignName && assetType){
        campaignName = assetType
      }
      try {
        var change = [
          row.changeEvent.changeDateTime,
          accountName,
          row.changeEvent.userEmail,
          campaignName,
          row.changeEvent.changeResourceType,
          row.changeEvent.changedFields,
        ];

          changeAlerts.push(change)
      

      } catch (e) {
        Logger.log("Issue with parsing results from search API: " + e);
      }
  
    }
       
        if (changeAlerts.length > 0) {
          reportResults(changeAlerts);
          sendEmail(changeAlerts.length);
        }
  }


function addHeaderToOutputSheet(sheet) {

  var header = [
    "Date",
    "Account",
    "User",
    "Location",
    "Type",
    "Fields",
  ];

  sheet.appendRow(header);
}


function reportResults(changes) {
    let sheet = prepareOutputSheet(false);
    addOutputToSheet(changes, sheet);
}


function prepareOutputSheet(clear) {

    var spreadsheet = SpreadsheetApp.openById(spreadsheetId);
    if (!spreadsheet) {
      alert("Cannot open new reporting spreadsheet");
      return;
    }
    var sheet = spreadsheet.getActiveSheet();
    if (!sheet) {
        alert("Cannot open new reporting sheet") ;
        return ;
    }  

    if (clear){
        sheet.clearContents();
        addHeaderToOutputSheet(sheet);
       // sheet.insertRowsBefore(2, output.length); // add empty rows below header row
     }
    return sheet;
     
}


function addOutputToSheet(output, sheet) {
  
  
 
    var numberOfRows = sheet.getLastRow() ;
     
    var startRow = numberOfRows + 1;
     
    var range=sheet.getRange(startRow, 1, output.length, output[0].length) ;
    range.setValues(output) ; 
   
    Logger.log("\nNumber of rows added to output sheet: "+output.length+"\n\n");
     
  }
  



function sendEmail(numberOfAlerts) {

  var accountName = AdsApp.currentAccount().getName();

  if (sendMail) {

    var emailString =
      "Number of changes: " + numberOfAlerts + "\n" +
      "See details: https://docs.google.com/spreadsheets/d/" + spreadsheetId + "\n" + emailBody;

    MailApp.sendEmail(emailAddresses, emailSubject + " | " + accountName, emailString);
    Logger.log("Sending alert mail");
  }
}

function alert(string) {
  Logger.log("### " + string);
}

The Complete System for PPC Management

Clicktrain Logo
Tailored Solutions
Looking for an Enterprise PPC solution for large agencies or an in-house team?
Menu
Login
Join As Talent
Hire PPC Talent
Blog
PPC Resource Monitoring
About Us
Info
ClickTrain Marketing Platform LTD
Address: 265 269 Wimbledon
Park Rd, SW19 6NW, London
Compliance
Platform Terms and Conditions
Website Terms
Privacy Policy
Quick Links
PPC Freelancers
PPC Specialists
PPC Consultants
Google Ads Specialists
White Label Management
Copyright© ClickTrain, 2021. All rights reserved