SPAG's voor Shopping (Single Product AdGroups)

Gebruik dit script om shopping campagnes automatisch uit te breiden met nieuwe producten in Merchant Center.

Start nu!
SPAG's voor Shopping (Single Product AdGroups)
SPAG's Get started!

Om zoveel mogelijk controle te hebben over de zoekwoorden per product in onze shopping campagnes, zetten wij alle producten altijd alleen in een advertentiegroep. Om die manier kan je woorden uitsluiten per product waarop andere producten dan alsnog vertoond kunnen worden. 

Maar zodra je meer dan 10 producten in een shop hebt staan, wil je dit liever niet handmatig doen. Je moet dan namelijk per product een advertentiegroep aanmaken, product toevoegen, bod toevoegen, advertentie toevoegen en 'Overige producten' uitsluiten. Daarom hebben we een script gemaakt die via een koppeling met Merchant Center dit automatisch bijwerkt. Het script doorloopt alle producten en kijkt of deze al in de shopping campagnes staan. Zijn de producten nieuw, dan worden deze toegevoegd aan de campagnes.

Campagnes handmatig opzetten

Vanuit Google Ads Scripts kunnen we geen nieuwe Shopping campagnes aanmaken. Daarom moet je deze zelf aanmaken en instellen naar wens. Wanneer je daarna dit script voor de eerste keer draait, zul je dit meerdere keren moeten doen om ervoor te zorgen dat alle producten erin zitten. Gemiddeld haalt het script 500 producten in een half uur, dus draai het script de eerst keer vaak genoeg om alle producten toe te voegen. Je hebt de mogelijkheid om de campagnes te splitsen op basis van een veld uit Merchant Center, bijvoorbeeld brand of productType. Wanneer je dit wilt doen, zorg er dan voor dat de campagnenaam ook de brand of productType bevat, zodat het script de juiste campagne kan selecteren voor het product.

Instellingen

Om dit script goed te kunnen draaien, moet je de volgende zaken goed instellen:

  • LOG: Geef aan of het script de tussenstappen moet rapporteren, door de waarde aan te passen naar 'true'.
  • MERCHANT_ID: Het ID van het Merchant Center account. De gebruiker die het script draait, moet ook als gebruiker zijn toegevoegd aan Merchant Center. Je moet ook de geavanceerde API 'Shopping Content' aanzetten in het script (rechtsbovenin).
  • DEFAULT_BID: De Max. CPC die ingevuld wordt voor elk product en advertentiegroep.
  • SPLIT_FIELD: Wil je je campagnes opsplitsen op basis van een veld uit Merchant Center? Vul deze dan hier in.

Frequentie: Wanneer je meer dan 500 producten hebt, stel je deze de eerste keer in voor elk uur. Wanneer alle producten dan in de campagnes staan, wijzig je dit naar dagelijks. Zorg ervoor dat je een tijdstip kiest na het updaten van je productfeed in Merchant Center.

The script
// Copyright 2020. Increase BV. All Rights Reserved.
//
// Created By: Tibbe van Asten
// for Increase B.V.
//
// Created 15-04-2019
// Last update: 14-01-2020
//
// ABOUT THE SCRIPT
// All products in the productfeed are checked for existance in the
// Google Shopping campaigns. If new, they're added to the right campaign
//
////////////////////////////////////////////////////////////////////

var config = {

  LOG : true,

  // Connect Merchant Center. Add user to MC that runs this script.
  // Also enable Advanced API 'Shopping content'.
  MERCHANT_ID : "123456789",

  // Set a default bid. This will be used for adgroups and products
  DEFAULT_BID : 0.5,

  // Campaigns can't be created by this script. You'll have to do this by hand.
  // Do you want to split your campaigns by a field from Merchant Center?
  // Possible values: brand, productType
  // For example: when you split by brand, make sure the brand is in the campaign name
  SPLIT_FIELD : "brand"
}

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

function main(){

  // First off, we collect all productdata from Merchant Center.
  // We also check all active adgroups
  var products = connectMerchant();
  var activeProducts = activeAdGroups();

  var addProducts = {};

  // All products of the feed will be checked
  for (var i = 0; i < products.length; i++) {

    // If the products-Id is already the name of an existing adgroup, we don't add it.
    // If the product is out of stock, we don't add it.

    if(activeProducts.indexOf(products[i]["offerId"]) < 0){
      var productId = products[i]["offerId"];
      var productName = products[i]["title"];

      // If you want to split your campaigns, we'll add this to info
      if(config.SPLIT_FIELD != ""){
        var split = products[i][config.SPLIT_FIELD];
      }

      if (addProducts[productId] == null) {
        addProducts[productId] = [];
      }
      addProducts[productId].push([productId, split, productName]);
    }

  } // for statement

    if(config.LOG === true){
      Logger.log("Found " + Object.keys(addProducts).length + " to be added");
      Logger.log(" ");
    }

  // Adding all products not already in the campaigns
  for (var key in addProducts) {

    var campaignSelector = AdsApp
      .shoppingCampaigns()
      .withCondition("Status = ENABLED");

    if(config.SPLIT_FIELD != ""){
      campaignSelector = campaignSelector.withCondition("Name CONTAINS '" + addProducts[key][0][1] + "'");
    }

    var campaignIterator = campaignSelector.get();

    while(campaignIterator.hasNext()){
      var campaign = campaignIterator.next();

      // Adding adgroup to Shopping campaign
      var shoppingAdGroup = campaign
        .newAdGroupBuilder()
        .withName(addProducts[key][0][0] + " - " + addProducts[key][0][2])
        .withCpc(config.DEFAULT_BID)
        .withStatus("ENABLED")
        .build()
        .getResult();

        if(config.LOG === true){
          Logger.log(shoppingAdGroup.getName() + " added to " + campaign.getName());
        }

      // Adding an ad to the new adgroup
      var ad = shoppingAdGroup
        .newAdBuilder()
        .build()
        .getResult();

      // Creating the root productgroup 'All Products' and select it
      shoppingAdGroup.createRootProductGroup();
      var root = shoppingAdGroup.rootProductGroup();

      // Creating a productgroup for this product
      root.newChild().itemIdBuilder()
        .withBid(config.DEFAULT_BID)
        .withValue(addProducts[key][0][0])
        .build();

      // Making sure all other products in this adgroup are excluded
      var children = root.children().get();
      while (children.hasNext()) {
        var child = children.next();
        if (child.isOtherCase()) {
          child.exclude();
        }
      } // childrenIterator

    } // campaignIterator

  } // addProductsIterator

} // function main()

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

function activeAdGroups(){

  var activeProducts = [];

  // We will check if an adGroup with this ID as name already exists
  var adGroupIterator = AdsApp
    .shoppingAdGroups()
    .withCondition("CampaignStatus = ENABLED")
    .withCondition("Status != REMOVED")
    .get();

  while(adGroupIterator.hasNext()){
    var adGroup = adGroupIterator.next();
    activeProducts.push(adGroup.getName().split(" - ")[0]);
  } // adGroupIterator

  return activeProducts;

} // activeAdGroups

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

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++) {

        // We only add products from Merchant Center when in stock
        if(productList.resources[i]["availability"] == "in stock"){
          products.push(productList.resources[i]);
        }
        
      }
    }

    pageToken = productList.nextPageToken;
    pageNum++;
  } while (pageToken);

  return products;

} // function connectMerchant
Show whole script!
The Experts
Tibbe van Asten Head of PPC @ Increase
Nils Rooijmans Water Cooler Topics
Martijn Kraan Freelance PPC Specialist
Bas Baudoin Teamlead SEA @ Happy Leads
How about you? JOIN US!
Sharing Knowledge
Caring

Kennis delen

Adsscripts.com staat voor het delen van kennis. In de huidige markt houden SEA-specialisten de kennis en ervaring graag voor zich. Wij zijn er van overtuigd dat het delen van kennis ervoor kan zorgen dat iedereen beter wordt in haar of zijn werk. Daarom lopen wij hier graag in voorop, door onze kennis over scripts te delen met iedereen.

Wil jij ook graag een bijdrage leveren? Wij staan open voor nieuwe ideeën en feedback op alles wat je op Adsscripts.com vindt.

Neem contact op

Training &
Workshop
Neem contact op!
Adsscripts Training & Workshop