Search code examples
google-ads-api

Alert disapproved products script in Google Ads


I have a Google Ads Script, which is supposed to notify me via e-mail, when products in my merchant center account are disapproved.

There is a "include" filter field in this script, which limits the monitored products, however, I can't get it to work. Everything else seems to be working.

This is the part of the script, where you can filter the products:

var productIdToInclude = [];

I have tried the following versions, to no avail:

var productIdToInclude = ["product123"];
var productIdToInclude = ['product123'];
var productIdToInclude = [product123];

This is the comment in the script about this filter:

// Filters
// These two variables store the product ID's that we want to filter by.
// The ID's need to be in string format e.g. productIdToInclude = ["123"];

The whole script can be found here.

I believe, that I have a synthax error, but I can't figure it out.


Solution

  • Filter logic in the script seems to be working fine for include but for exclude I did found some issue. Update your exclude function and see if that works.

    function satisfiesIdExcludeFilters(productIdToExclude, product) {
      if (productIdToExclude.length) {
        for (index = 0; index < productIdToExclude.length; ++index) {
          if (product['productId'].indexOf(productIdToExclude[index]) !== -1) {
            return false;
          }
        }
        return true;
      } else {
        return true;
      }
    }

    Updated script should look like:

    /**
     *
     * GMC Disapproval Checker
     *
     * This script checks your Google Merchant Centre for disapproved products. It will send you emails if the percentage of
     * disapproved products exceeds a specified threshold. You need to select the Shopping Content api in the Advanced Apis
     * section to run this script.
     *
     * Google AdWords Script maintained on brainlabsdigital.com
     *
     */
    
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    // Options
    
    var merchantId = '';
    // Replace this with your Merchant Center ID.
    
    var threshold = 30;
    // Percentage of disapproved products you would like to be alerted by.
    // Do NOT include the percentage sign in this variable.
    
    var email = ['[email protected]'];
    // Email addresses to send the disapproval alert to.
    // If there is more than one email they should be comma separated
    // - e.g. ["[email protected]", "[email protected]"]
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    // Filters
    // These two variables store the product ID's that we want to filter by.
    // The ID's need to be in string format e.g. productIdToInclude = ["123"];
    // These are actually substrings of the productId so be careful not to use
    // strings which are not reasonably specific.
    
    var productIdToInclude = ['Z200'];
    var productIdToExclude = [];
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
    // Functions
    
    function main() {
    
      var pageToken;
      var maxResults = 250;
      // These variables are used to fetch all the products (maximum of 250) on a page
      // in the merchant centre. We can then iterate over the pages by using the next
      // page token which is given as part of the response to our request.
    
      var totalProducts = 0;
      var disapprovedProducts = [];
    
      do {
        // This is a quick check to see if the filters supplied are valid
        checkFiltersDontContradict(productIdToInclude, productIdToExclude);
    
        var productStatuses = ShoppingContent.Productstatuses.list(merchantId, {
          pageToken: pageToken,
          maxResults: maxResults
        });
    
        // If the 'approvalStatus' of our product is not 'approved' then we say it is disapproved.
        if (productStatuses.resources) {
          for (var i = 0; i < productStatuses.resources.length; i++) {
            product = productStatuses.resources[i];
            if (satisfiesAllFilters(product)) {
              totalProducts += 1;
              if (product['destinationStatuses'][0]['approvalStatus'] == 'disapproved') {
                disapprovedProducts.push(product['productId']);
              }
            }
          }
        } else {
          Logger.log('No more products in account ' + merchantId);
        }
        // We then pull our next PageToken from our response and use it to make a new request.
        // If there is no next PageToken then we exit our iteration.
        pageToken = productStatuses.nextPageToken;
      } while (pageToken);
    
      disapprovalPercentage = (disapprovedProducts.length * 100) / totalProducts;
      Logger.log(disapprovedProducts.length + ' of ' + totalProducts +
        ' products in your account were disapproved - ' +
        disapprovalPercentage.toFixed(2) + '%')
    
      // If our threshold is exceeded then we assemble an email with details of the alert and send it to our contact emails.
      if (disapprovalPercentage >= threshold) {
    
        var subject = merchantId + ' GMC Disapproval Alert Email';
        var message = disapprovedProducts.length + ' of ' + totalProducts +
          ' products in your GMC (' + merchantId + ') were disapproved - ' +
          disapprovalPercentage.toFixed(2) + '%' + '\n' +
          'Disapproved products: ' + disapprovedProducts.join('\n');
    
        MailApp.sendEmail(email.join(','), subject, message);
        Logger.log('Message to ' + email.join(',') + ' sent.');
      }
    }
    
    function checkFiltersDontContradict(productIdToInclude, productIdToExclude) {
      if (productIdToInclude.length && productIdToExclude.length) {
        for (var i in productIdToInclude) {
          if (productIdToExclude.indexOf(productIdToInclude[i]) > -1) {
            throw "Filters have shared values - can not include and exclude simultaneously";
          }
        }
      } else {
        return true;
      }
    }
    
    function satisfiesAllFilters(product) {
      return (satisfiesIdIncludeFilters(productIdToInclude, product) &&
        satisfiesIdExcludeFilters(productIdToExclude, product));
    }
    
    function satisfiesIdIncludeFilters(productIdToInclude, product) {
      if (productIdToInclude.length) {
        for (index = 0; index < productIdToInclude.length; ++index) {
          if (product['productId'].indexOf(productIdToInclude[index]) !== -1) {
            return true;
          }
        }
        return false;
      } else {
        return true;
      }
    }
    
    function satisfiesIdExcludeFilters(productIdToExclude, product) {
      if (productIdToExclude.length) {
        for (index = 0; index < productIdToExclude.length; ++index) {
          if (product['productId'].indexOf(productIdToExclude[index]) !== -1) {
            return false;
          }
        }
        return true;
      } else {
        return true;
      }
    }