Find Auto Applied Recommendations

Receive an email with all auto applied changes Google made. 

Start Now!
Receive an email with all auto applied changes Google made
Find Auto Get started!

The concept of this script is quite simple; it checks the change history on all the accounts connected to our MCC (My Client Center) every day.

Its task is to find changes made by Auto Applied recommendations.
If it finds any, it sends detailed information about these changes to the specified email address.

In other words, this solution provides security and certainty that Auto Applied recommendations will be under our control.

This will be especially useful for agencies and freelancers managing multiple Google Ads accounts.

Configuration

  1. Set your email address in the EMAIL_SETTINGS variable.
  2. Schedule the script to run once daily in the morning.
  3. Optionally, set the number of days to look back in the LOOKBACK_DAYS variable. The default is 3, with a maximum of 30 days.
The script
/*
Copyright 2023 Krzysztof Bycina, www.LiveAds.pl
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/


// --------------------------------------- Configuration:

const EMAIL_SETTINGS = {
    RECIPIENT: 'YOUR EMAIL HERE',
    SUBJECT: 'Auto-apply Recommendations have been found.'
};

const LOOKBACK_DAYS = 5;  // Specify the number of days to look back (Max 30)

// --------------------------------------- End of the configuration



function main() {
    const dateRange = computeDateRange(LOOKBACK_DAYS);
    const managerAccount = AdsApp.currentAccount();
    const allAccounts = AdsManagerApp.accounts();

    let formattedEmailContent = '<html><body>';

    for (const account of allAccounts) {
        Logger.log('Checking account: ' + account.getName());
        AdsManagerApp.select(account);

        const reportData = fetchReportData(dateRange);
        const accountContent = formatReportData(reportData);
        if (accountContent) {
            Logger.log('Auto-apply Recommendations have been found in account: ' + account.getName());
        }
        formattedEmailContent += accountContent;
    }

    formattedEmailContent += '</body></html>';

    if (formattedEmailContent !== '<html><body></body></html>') {
        sendEmail(formattedEmailContent, EMAIL_SETTINGS);
    } else {
        Logger.log("No changes found. Email not sent.");
    }
}

function computeDateRange(days) {
    const today = new Date();
    const lookbackDate = new Date(today.getTime() - (days - 1) * 24 * 60 * 60 * 1000);
    const formattedStartDate = Utilities.formatDate(lookbackDate, AdsApp.currentAccount().getTimeZone(), 'yyyyMMdd');
    const formattedEndDate = Utilities.formatDate(today, AdsApp.currentAccount().getTimeZone(), 'yyyyMMdd');
    return { start: formattedStartDate, end: formattedEndDate };
}

function fetchReportData(dateRange) {
    const reportFields = [
        'customer.descriptive_name',
        'change_event.change_date_time',
        'campaign.name',
        'ad_group.name',
        'change_event.resource_change_operation',
        'change_event.change_resource_type',
    ];
    const selectStatement = reportFields.join(', ');

    return AdsApp.report(
        `SELECT ${selectStatement} ` +
        `FROM change_event ` +
        `WHERE change_event.change_date_time BETWEEN '${dateRange.start}' AND '${dateRange.end}' AND change_event.user_email = 'Recommendations Auto-Apply' ` +
        `ORDER BY change_event.change_date_time DESC ` +
        `LIMIT 100`
    );
}

function formatReportData(report) {
    const fieldMapping = {
        'customer.descriptive_name': 'Account name',
        'change_event.change_date_time': 'Date and time',
        'campaign.name': 'Campaign name',
        'ad_group.name': 'Ad group name',
        'change_event.resource_change_operation': 'Change type',
        'change_event.change_resource_type': 'Change in'
    };
    let emailContent = '';

    let rows = report.rows();
    while (rows.hasNext()) {
        let row = rows.next();
        emailContent += '<div style="border:1px solid #e5e5e5; padding: 10px; margin-bottom: 10px;">'; 
        for (const field in fieldMapping) {
            let fieldName = fieldMapping[field];
            let fieldValue = field === 'change_event.change_date_time' ? reformatDate(row[field]) : row[field];
            emailContent += `<b>${fieldName}</b>: ${fieldValue}<br>`;
        }
        emailContent += '</div>';
    }

    return emailContent;
}

function reformatDate(dateTimeString) {
    const options = {
        year: 'numeric', month: 'long', day: 'numeric',
        hour: '2-digit', minute: '2-digit',
        hour12: true
    };
    const dateObj = new Date(dateTimeString);
    return dateObj.toLocaleDateString('en-US', options);
}

function sendEmail(content, settings) {
    MailApp.sendEmail({
        to: settings.RECIPIENT,
        subject: settings.SUBJECT,
        htmlBody: content
    });
}
Show whole script!
Loading Comments
The Experts
Tibbe van Asten Team Lead Performance Marketing
Nils Rooijmans Water Cooler Topics
Martijn Kraan Freelance PPC Specialist
Bas Baudoin Teamlead SEA @ Happy Leads
Jermaya Leijen Digital Marketing Strategist
Krzysztof Bycina PPC Specialist from Poland
How about you? JOIN US!
Sharing Knowledge
Caring

Adsscripts.com is all about sharing knowledge. In the current market, PPC specialists like to keep their knowledge and experience to themselves. We're convinced that sharing knowledge can ensure that everyone gets better at their work. We want to change this by sharing our knowledge about scripts with everyone.

Do you also want to contribute? We are open to new ideas and feedback on everything you find on Adsscripts.com.

Contact us

Training &
Workshop
Contact us!
Adsscripts Training & Workshop