Update prices in textads

Keep the prices of your products in text ads up-to-date with this script. Through a link with Google Merchant Center, prices are checked every hour.

Start Now!
Update prices in textads
Update Get started!

For every ecommerce-shop, it's worthwhile to test whether the use of prices in text ads lead to a higher CTR. If you want to use this on a larger scale, it's important that the prices of all these products are up to date. To ensure that the price on the website is the same as the price in the text ads, you can easily automate this process.

Check current prices

This script makes a link with Google Merchant Center and retrieves all current productprices there. When you let the Merchant Center keep an eye on your stock and prices, the price in the Merchant Center is always updated. The script then runs through all the ads in your account that you have labeled to indicate that there is a price in it. The landing page is used to determine whether the price in the ads is the same as the price in the Google Merchant Center.

Update prices in textads

If the price from GMC is not in the text ad, the price from the ad is replaced. This ensures that your advertisement always contains a current price of the product.

Settings

  • LOG: Specify whether the script should report the intermediate steps by adjusting the value to 'true'.
  • MERCHANT_ID: Enable the advanced API 'Shopping Content' and enter the Merchant Center ID here. Ensure that the user running the script also has access to GMC.
  • CURRENCY: Specify which currency you use in your text ads.
  • DECIMAL_SEPERATOR: By default the prices are in GMC with '.' as a decimal point. If you want to change that in your ads, you can indicate that here.
  • AD_LABEL_HEADLINE: Label all ads that have a price in a headline.
  • AD_LABEL_DESCRIPTION: Label all ads that have a price in a description.

Frequency: Run this script every hour, thus you are assured of up to date prices in your advertisements.

The script
// Copyright 2019. Increase BV. All Rights Reserved.
//
// Created By: Tibbe van Asten
// for Increase B.V.
//
// Created 28-05-2019
// Last update: 10-02-2019
//
// ABOUT THE SCRIPT
// With this script the adcopy will be checked for current pricing
//
////////////////////////////////////////////////////////////////////

var config = {
  
  LOG : true,
  
  // Connect Merchant Center. Add user to MC that runs this script.
  // Also enable Advanced API 'Shopping content'.
  MERCHANT_ID : "127116107",
  
  CURRENCY : "€",
  DECIMAL_SEPERATOR : ",",
  AD_LABEL_HEADLINE : "Price - Headline",
  AD_LABEL_DESCRIPTION : "Price - Description",
  
}

////////////////////////////////////////////////////////////////////

function main() {

  checkLabel(config.AD_LABEL_HEADLINE);
  checkLabel(config.AD_LABEL_DESCRIPTION);
  var products = connectMerchant();

  // We will look at all ads with the label stated in the config
  var adIterator = AdsApp
    .ads()
    .withCondition("LabelNames CONTAINS_ANY ['" + config.AD_LABEL_HEADLINE + "','" + config.AD_LABEL_DESCRIPTION + "']")
    .withCondition("Status = ENABLED")
    .withCondition("AdGroupStatus = ENABLED")
    .withCondition("CampaignStatus = ENABLED")
    .get();
  
    if(config.LOG === true){
      Logger.log(adIterator.totalNumEntities() + " ads");
    }
  
  while (adIterator.hasNext()) {
    var ad = adIterator.next();
    var adUrl = ad.urls().getFinalUrl();
    
    var price = checkPrice(products, adUrl);
    
    // When no price is found in the feed, the ad with price is paused
    if(price == null){      
      	if(config.LOG == true){
          Logger.log("Ad paused");
          Logger.log(" ");
        }
      
      ad.pause();
      continue;
    }
    
    var headline = [];
    var description = [];
    
    var regex = new RegExp("[0-9]+(\\" + config.DECIMAL_SEPERATOR + "[0-9]{1,2})");
    
    // Find the price and replace it    
    for(var i = 1;i < 4;i++){
      headline[i] = eval("ad.getHeadlinePart" + i + "()");
      
      if(headline[i].indexOf(config.CURRENCY) > -1 && headline[i].indexOf(price) < 0){     
        headline[i] = headline[i].replace(regex, price);        
        var label = config.AD_LABEL_HEADLINE;
      }
      
    } // headlineIterator
    
    for(var n = 1;n < 3;n++){
      description[n] = eval("ad.getDescription" + n + "()");
      
      if(description[n].indexOf(config.CURRENCY) > -1 && description[n].indexOf(price) < 0){        
        description[n] = description[n].replace(regex, price);
        var label = config.AD_LABEL_DESCRIPTION;
      }
      
    } // descriptionIterator
    
    // If a headline or description differs, we'll create a new ad
    if(ad.getHeadlinePart1() != headline[1] || ad.getHeadlinePart2() != headline[2] || ad.getHeadlinePart3() != headline[3] || ad.getDescription1() != description[1] || ad.getDescription2() != description[2]){      
      var adGroup = ad.getAdGroup();
      var adOperation = adGroup.newAd().expandedTextAdBuilder()
        .withHeadlinePart1(headline[1])
      	.withHeadlinePart2(headline[2])
        .withHeadlinePart3(headline[3] || "")
        .withDescription1(description[1])    
        .withDescription2(description[2] || "")    
        .withPath1(ad.getPath1() || "")
      	.withPath2(ad.getPath2() || "")
        .withFinalUrl(adUrl)
        .build();
      
      if(adOperation.getErrors() == ""){
        var newAd = adOperation.getResult().applyLabel(label);
        ad.pause();
      } else {
        Logger.log("Failed to create ad in " + adGroup);
      }
      
      if(config.LOG === true){
        Logger.log("Ad replaced in " + ad.getAdGroup().getName());
      }
      
    } // Check for changes lines
    
  } // ad iterator

} // function main()

////////////////////////////////////////////////////////////////////

function checkLabel(label){
  
  if(label !== "" && !AdsApp.labels().withCondition("Name = '"+label+"'").get().hasNext()) {
    AdsApp.createLabel(label);

    	Logger.log("Label " + label + " created");
  }
  
} // function checkLabel()

////////////////////////////////////////////////////////////////////

function connectMerchant(){
  
  	if(config.MERCHANT == "123456789"){
      throw Error("Change the Merchant ID in the settings");
    }  
    
  var pageToken;
  var pageNum = 1;
  var maxResults = 250;
  var products = [];
  
  do {
    var productList = ShoppingContent.Products.list(config.MERCHANT_ID, {
      pageToken: pageToken,
      maxResults: maxResults
    });
    
    if (productList.resources) {
      for (var i = 0; i < productList.resources.length; i++) {
        products.push(productList.resources[i]);
      }
    }

    pageToken = productList.nextPageToken;
    pageNum++;
  } while (pageToken);
  
  return products;
  
} // function connectMerchant

////////////////////////////////////////////////////////////////////

function checkPrice(products, adUrl){
  
  for (var i = 1; i < products.length; i++) { 
    
    // When the link in the feed is the same as the ad url, the price is retrieved
    if(products[i]["link"] == adUrl) { 
    
      // When the saleprice is in the feed, this will be used. If not, the regular price is used.
      if(products[i]["salePrice"]) {
        var price = products[i]["salePrice"]["value"];
      } else {
        var price = products[i]["price"]["value"];
      }
      
      if(config.DECIMAL_SEPERATOR != "."){
        price = price.replace(".", config.DECIMAL_SEPERATOR);
      }
      
      return price;
      
    } // if statement url
    
  } // for statement
  
} // function checkPrice()
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