Google Ads Script – Increase shopping feed update frequency

Do your products’ prices change more than once per day?
Or do products easily go out of stock during the day?

If so, bad news: you’re losing money every day!

The Google Merchant Center interface only supports a max of once-per-day updates of the product data in your shopping feed.

 

Google Merchant Center feed schedule rate

 

Because of this fetch rate limitation, your shopping campaigns may show outdated product listing ads on the Google SERP.

Outdated Shopping Product Listing Ads

Even worse, your ideal customer may click on your product, land on your website, only to discover the price isn’t as advertised, and then LEAVE WITHOUT BUYING!

There goes your money.

Now enter a world where your shopping ads are always up-to-date, showing your latest price, and respecting your current availability status.
No more false promises in your shopping ads. Landers that deliver the promise. Converting clicks.

This requires products that are up to date with the data in your shop and product feed. Every hour of the day.

Impossible?
Not anymore.

Here’s my script to automatically update the data in your shopping ads, every hour.

(Don’t worry if you have never run a script before. You do not need any coding skills. It is as simple as copy-paste.)
INSTRUCTIONS:

    1. See the script code below. Install the script in your account.
      Don’t worry if you have never done this before. You do not need any coding skills. It is as simple as copy-paste. Simply follow these instructions on how to set up and schedule Google Ads scripts.
    2. Create a new Google Sheet
      (tip for Chrome users: simply type ‘sheets.new’ in the address bar)
    3. Add your Google Merchant Center ID (Line 17)
      Make sure the account that runs the Google Ads Script has access to the merchant center
    4. Add the complete URL of the spreadsheet to the script (line 19)
    5. Enable the Shopping API: Go to the top right corner of the script, there is a button ‘Advanced API’s’. Click on that button and enable the Shopping Content API.
    6. Preview
    7. Schedule to run hourly

Interested in a MCC version of this script for manager accounts? 
Contact me at nils [at] nilsrooijmans.com.

 

 


/**
*
* Fetch Google Shopping Feeds Every Hour of the day
**
* @author: Nils Rooijmans
*
* INSTRUCTIONS:
* Add your Google Merchant Center ID (Line 17)
* Create a new Google Sheet (tip for Chrome users: simply type 'sheets.new' in the address bar)
* Make sure the account that runs the Google Ads Script has access to the merchant center
* Add the complete URL of the spreadsheet to the script (line 19)
* Enable the Shopping API: Go to the top right corner of the script, there is a button ‘Advanced API’s’. Click on that button and enable the Shopping Content API
* Schedule script to run hourly
*
* Contact nils@nilsrooijmans.com for questions and the MCC version of the script 
*/

var MERCHANT_ID = 12345678; // replace '12345678' with your Google Merchant Center ID

var SPREADSHEET_URL = ""; // insert spreadsheet url 

function main() {

  Logger.log("Fetching enabled feeds for GMC id: "+MERCHANT_ID)
  var fetchedFeeds = fetchEnabledProductFeeds(MERCHANT_ID);
  
  if (fetchedFeeds.length > 0) {
    reportResults(fetchedFeeds);
  } else {
    Logger.log("### zero feeds fetched");
  }
}


function reportResults(fetchedFeeds) {

  //prepare the Spreadsheet
  var ss = SpreadsheetApp.openByUrl(SPREADSHEET_URL);
  var sheet = ss.getActiveSheet();
  sheet.clear();
  
  var header = [
    "Date, Time",
    "Merchant Id",
    "Feed Name", 
    "Feed ID", 
    "Status"
  ];
  
  if (sheet.getRange('A1').isBlank()) {
    sheet.appendRow(header); 
    Logger.log("Added header to sheet");
  }

  var lastRow = sheet.getLastRow();

  // write status to sheet
  var range = sheet.getRange(lastRow+1, 1, fetchedFeeds.length, header.length);
  range.setValues(fetchedFeeds);
  Logger.log("Added results to sheet : "+SPREADSHEET_URL)
}


function fetchEnabledProductFeeds(merchantId) {
  
  var fetchedFeeds = [];
  
  var date = new Date();
  var now = Utilities.formatDate(date, AdsApp.currentAccount().getTimeZone(), "yyyy MMM dd HH:mm");
  Logger.log("The current time (timezone of the account) is: "+ now);
  
  try {
    var productFeeds = ShoppingContent.Datafeeds.list(merchantId);
  } catch(e) {
    Logger.log("### ERROR Fecthing data from merchant: '"+merchantId+"' --> "+e);
    fetchedFeeds.push([now, merchantId, , , "### ERROR Fecthing datafeed: "+e]);    
    return fetchedFeeds;
  }
  
  if (productFeeds.resources) {
    Logger.log("Number of feeds in the account: "+productFeeds.resources.length);
    for (var i = 0; i < productFeeds.resources.length; i++) {
      
      if(productFeeds.resources[i].fetchSchedule && productFeeds.resources[i].fetchSchedule.paused==false) {
        try {
          var dataFeedId = productFeeds.resources[i].id;          
          var response = ShoppingContent.Datafeeds.fetchnow(merchantId, dataFeedId);
          //Logger.log ("Response: "+response);
          Logger.log("Fetched productfeed: '"+productFeeds.resources[i].name+"' with id: '"+dataFeedId+"'");
          fetchedFeeds.push([now, merchantId, productFeeds.resources[i].name, dataFeedId, "Fetch OK"]);
        } catch(e) {
          Logger.log("### ERROR Fecthing datafeed: '"+productFeeds.resources[i].name+"' with id: '"+dataFeedId+"' with fetchUrl: '"+productFeeds.resources[i].fetchSchedule.fetchUrl+"' --> "+e);
          fetchedFeeds.push([now, merchantId, productFeeds.resources[i].name, dataFeedId, "### ERROR Fecthing datafeed: "+e]);
        }
      }
    }
  } else {
    Logger.log("### UNKOWN ERROR Fecthing data from merchant: '"+merchantId+"'"); 
  }
  return fetchedFeeds;
}


We spend tens of thousands of dollars a day in Shopping and the limitation of only being able to update the feed once a day has been a major frustration of ours for a while, especially since price and availability on our site updates multiple times a day. We've just applied the script and it will be a gamechanger for us to reduce wasted spend and increase efficiency!

Matt Depoortere, SEM Manager at Petcircle.com.au - Sydney, Australia

Nils Rooijmans
2023-05-22T16:34:19+00:00

Matt Depoortere, SEM Manager at Petcircle.com.au - Sydney, Australia

We spend tens of thousands of dollars a day in Shopping and the limitation of only being able to update the feed once a day has been a major frustration of ours for a while, especially since price and availability on our site updates multiple times a day. We've just applied the script and it will be a gamechanger for us to reduce wasted spend and increase efficiency!
0
0
Nils Rooijmans

"I really appreciate all the value you give. ... Thanks for constantly sharing awesome scripts and value!"

Nick Poole, SEM Specialist - Sydney, Australia

Nils Rooijmans
2022-11-25T14:08:57+00:00

Nick Poole, SEM Specialist - Sydney, Australia

"I really appreciate all the value you give. ... Thanks for constantly sharing awesome scripts and value!"
0
0
Nils Rooijmans

Join thousands of PPC geeks who already have access:

If the button above isn’t working for you, you can sign up here to get access.