Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Google Ads Unauthorized Change Detector
- *
- * N00b Instructions:
- * 1. This script is for Google Ads and runs in the Google Ads Scripts interface.
- * 2. You need to have MCC (Manager Account) level access to use this script.
- * 3. Before using, you need to set up a few things:
- * a. Create a new Google Sheet to store the change logs.
- * b. Copy the URL of this sheet and paste it in the CONFIG.spreadsheetUrl below.
- * c. List the email addresses that should receive alerts in CONFIG.emailRecipients.
- * d. In CONFIG.trustedUsers, list the email addresses of users whose changes should not trigger alerts.
- * 4. To set up the script in Google Ads:
- * a. In your MCC account, go to Tools & Settings > Bulk Actions > Scripts.
- * b. Click the big blue "+" button to create a new script.
- * c. Give your script a name (e.g., "Unauthorized Change Detector").
- * d. Copy and paste this entire script into the editor.
- * e. Click "Save" and then "Preview" to test the script.
- * f. If everything looks good, click "Run" to execute the script.
- * 5. To run this script regularly:
- * a. After saving, click on "Create schedule" in the scripts interface.
- * b. Choose how often you want the script to run (daily is recommended).
- * c. Select a time for the script to run.
- * d. Click "Submit" to schedule the script.
- *
- * If you encounter any errors or have questions, consult the Google Ads Scripts documentation
- * or seek help from a more experienced user or the Google Ads support team.
- */
- // Global configuration
- const CONFIG = {
- spreadsheetUrl: '[SPREADSHEET URL]', // Replace with your Google Sheet URL
- emailRecipients: '[EMAIL ADDRESS LIST]', // Replace with comma-separated email addresses
- trustedUsers: ['[USER1]', '[USER2]', '[USER3]'], // Replace with trusted user email addresses
- emailSubject: 'Alert: Unauthorized Google Ads Changes Detected',
- timeRange: 'YESTERDAY',
- enableEmailAlerts: true
- };
- // Main execution function
- function executeAudit() {
- const accountIterator = AdsManagerApp.accounts().get();
- while (accountIterator.hasNext()) {
- const account = accountIterator.next();
- AdsManagerApp.select(account);
- auditAccount();
- }
- }
- // Audit individual account
- function auditAccount() {
- const accountName = AdsApp.currentAccount().getName();
- Logger.log(`Auditing account: ${accountName}`);
- const unauthorizedChanges = fetchUnauthorizedChanges();
- if (unauthorizedChanges.length > 0) {
- logChangesToSpreadsheet(unauthorizedChanges);
- if (CONFIG.enableEmailAlerts) {
- notifyViaEmail(unauthorizedChanges.length, accountName);
- }
- } else {
- Logger.log('No unauthorized changes detected');
- recordNoChangesFound();
- }
- }
- // Fetch unauthorized changes
- function fetchUnauthorizedChanges() {
- const query = buildChangeQuery();
- const result = AdsApp.search(query);
- const changes = [];
- while (result.hasNext()) {
- const row = result.next();
- const change = extractChangeInfo(row);
- if (change) changes.push(change);
- }
- return changes;
- }
- // Build AWQL query
- function buildChangeQuery() {
- const fields = [
- 'campaign.name', 'ad_group.name', 'change_event.change_date_time',
- 'change_event.change_resource_type', 'change_event.changed_fields',
- 'change_event.client_type', 'change_event.feed', 'change_event.feed_item',
- 'change_event.new_resource', 'change_event.old_resource',
- 'change_event.resource_change_operation', 'change_event.resource_name',
- 'change_event.user_email'
- ];
- return `SELECT ${fields.join(', ')} FROM change_event
- WHERE change_event.change_date_time DURING ${CONFIG.timeRange}
- AND change_event.user_email NOT IN ('${CONFIG.trustedUsers.join("', '")}')
- ORDER BY change_event.change_date_time DESC
- LIMIT 9999`;
- }
- // Extract change information
- function extractChangeInfo(row) {
- try {
- return [
- row.changeEvent.changeDateTime,
- AdsApp.currentAccount().getName(),
- row.changeEvent.userEmail,
- row.changeEvent.clientType,
- row.campaign ? row.campaign.name : '',
- row.adGroup ? row.adGroup.name : '',
- row.changeEvent.changeResourceType,
- row.changeEvent.changedFields,
- row.changeEvent.feed,
- row.changeEvent.feedItem,
- row.changeEvent.newResource,
- row.changeEvent.oldResource,
- row.changeEvent.resourceChangeOperation
- ];
- } catch (error) {
- Logger.log(`Error extracting change info: ${error}`);
- return null;
- }
- }
- // Log changes to spreadsheet
- function logChangesToSpreadsheet(changes) {
- const sheet = SpreadsheetApp.openByUrl(CONFIG.spreadsheetUrl).getActiveSheet();
- if (sheet.getLastRow() === 0) {
- sheet.appendRow([
- 'Date', 'Account', 'User', 'Client Type', 'Campaign', 'Ad Group',
- 'Change Type', 'Changed Fields', 'Feed', 'Feed Item', 'New Resource',
- 'Old Resource', 'Change Operation'
- ]);
- }
- sheet.insertRowsBefore(2, changes.length);
- sheet.getRange(2, 1, changes.length, changes[0].length).setValues(changes);
- }
- // Record when no changes are found
- function recordNoChangesFound() {
- const sheet = SpreadsheetApp.openByUrl(CONFIG.spreadsheetUrl).getActiveSheet();
- const today = new Date();
- sheet.appendRow([
- Utilities.formatDate(today, AdsApp.currentAccount().getTimeZone(), 'yyyy-MM-dd'),
- 'No unauthorized changes detected'
- ]);
- }
- // Send email notification
- function notifyViaEmail(changeCount, accountName) {
- const body = `
- ${changeCount} unauthorized change(s) detected in account: ${accountName}
- Details available at: ${CONFIG.spreadsheetUrl}
- This audit covers changes made ${CONFIG.timeRange}.
- Trusted users: ${CONFIG.trustedUsers.join(', ')}
- `;
- MailApp.sendEmail(CONFIG.emailRecipients, CONFIG.emailSubject, body);
- Logger.log('Email alert sent');
- }
- // Execute the script
- executeAudit();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement