Skip to content

Instantly share code, notes, and snippets.

@mbaersch
Last active July 9, 2019 23:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbaersch/abbfbb6c3144b1a1fa3492d5f019b29a to your computer and use it in GitHub Desktop.
Save mbaersch/abbfbb6c3144b1a1fa3492d5f019b29a to your computer and use it in GitHub Desktop.
Dynamische Anzeige von Trusted Shops Produktbewertungen
/***********************************************************************/
/****** Dynamische Anzeige von Trusted Shops Produktbewertungen *******/
/***********************************************************************/
/* v1.2 2017 Markus Baersch (@mbaersch)
gandke marketing & software - www.gandke.de */
/******************************* Setup *******************************/
//Bezeichnung des Labels für Anzeigegruppen mit zu behandelnden Keywords angeben
var lblDynParams = "ApiRating";
//zu Kontrollzwecken auf "true" stellen, wenn vorhandene Parameter aufgelistet werden sollen, statt neue zu setzen
var doList = false;
//Sollen zugewiesene Parameter im Log ausgegeben werden?
var doLog = false;
//auf "true" stellen, wenn Tests stattfinden sollen, ohne die API zu belasten (Standardwert dann: 4.2 ;))
var debug = false;
/***************************** Ende Setup ****************************/
var cachedRatings = [];
var cachedAdGroupUrls = [];
function main() {
//Parameter für Keyword ermitteln
function getRating(kw) {
var res = '';
var url = getKwUrl(kw);
if (cachedRatings[url]) {
res = cachedRatings[url];
if (res == "none") res = "";
} else {
//SKU und tsId von Seite abrufen
var prodInfo = getProdInfoFromUrl(url);
var sku = prodInfo.sku;
var tsId = prodInfo.tsId;
//Bewertung für SKU via API auslesen
var res = getRatingFromAPI(sku, tsId);
//Caching Ergebnis für URL
if ((res == "") || (res == 0)) cachedRatings[url] = "none"; else cachedRatings[url] = res;
}
return res;
}
/* Start main() */
var scStart = new Date().getTime();
needsLabel(lblDynParams);
//Anzeigegruppen selektieren, die bearbeitet werden sollen
var cond = "";
try {
var adgs = AdWordsApp.adGroups().withCondition("LabelNames CONTAINS_ALL ['"+lblDynParams+"']").get();
} catch(e) {
Logger.log("Fehler bei der Selektion der Anzeigegruppen - Vorschaumodus ohne existierendes Label? Funktion wird beendet");
return "";
}
while (adgs.hasNext())
if (cond == "") cond = adgs.next().getId(); else cond += ", "+adgs.next().getId();
if (cond != "")
cond = "AdGroupId IN ["+cond+"]";
else {
Logger.log('Keine markierten Anzeigegrupe gefunden - nichts zu tun.');
return "";
}
//aktive Keywords markierter Anzeigegruppen verarbeiten
var kws = AdWordsApp.keywords()
.withCondition(cond)
.withCondition('CampaignStatus = ENABLED')
.withCondition('AdGroupStatus = ENABLED')
.withCondition('Status = ENABLED')
.get();
var ct = 0;
while(kws.hasNext()) {
var kw = kws.next();
if (!doList) {
//Parameter ermitteln und zuweisen
var param1 = getRating(kw);
if(param1) {
ct++;
kw.setAdParam(1, param1);
if (doLog) Logger.log(kw.getText() + ": " + param1);
}
} else {
//Nur vorhandene Parameter auflisten
var p = kw.adParams().get();
if (p.hasNext()) {
var pr = p.next();
if (pr) Logger.log(kw.getText() + "\t: param" + pr.getIndex() + "\t -> " + pr.getInsertionText());
}
}
}
if (!doList) {
var ende = new Date().getTime();
var dauer = Number(((ende - scStart) / 1000 / 60).toFixed(2));
Logger.log("Vorgang abgeschlossen; Dauer: "+dauer+" Minuten. Es wurden Bewertungen zu "+ct.toString()+" Keywords aktualisiert");
}
}
/***********************************************************************/
/********************** Hilfsfunktionen *******************************/
/***********************************************************************/
//Bewertung für Produkt aus API beziehen
function getRatingFromAPI(sku, tsId) {
if (debug) return 4.2;
//Codierung der SKU für API-Aufruf
var encodeHex = function (tmp) {
var str = '';
var uTmp = unescape(encodeURIComponent(tmp));
for (var i = 0; i < uTmp.length; i++) {
str += uTmp.charCodeAt(i).toString(16) + '';
}
return str;
};
var res = "";
try {
var url = "https://cdn1.api.trustedshops.com/shops/"+tsId+
"/products/skus/"+encodeHex(sku)+"/productstickersummaries/v1/quality/reviews.json";
var ApiResult = UrlFetchApp.fetch(url,{muteHttpExceptions: true});
if (ApiResult) {
var rating = JSON.parse(ApiResult);
res = rating.response.data.product.qualityIndicators.reviewIndicator.overallMark;
res = res.toFixed(1);
}
} catch(e) {
res = "";
}
return res;
}
//URL aus Keyword oder Anzeigengruppe zurückliefern
function getKwUrl(kw) {
//Gibt es eine URL beim Keyword?
var res = kw.urls().getFinalUrl();
if (!res) res = kw.urls().getMobileFinalUrl();
//Sonst URL der Anzeigengruppe verwenden
if (!res) {
var adg = kw.getAdGroup();
//URL schon bekannt und zwischengespeichert?
var cachedUrl = cachedAdGroupUrls[adg.getId()];
if (cachedUrl) res = cachedUrl;
else {
//URL der ersten aktiven Anzeige ermitteln
var ads = adg.ads().withCondition("Status = ENABLED").get();
if (ads.hasNext()) {
var ag = ads.next();
res = ag.urls().getFinalUrl();
if (!res) ag.urls().getMobileFinalUrl();
}
//URL zur Anzeigengruppe für weitere KWs zwischenspeichern
if (res) cachedAdGroupUrls[adg.getId()] = cleanUrl(res);
}
}
res = cleanUrl(res);
return res;
}
//SKU aus Zielseite extrahieren
function getProdInfoFromUrl(url) {
var res = {'sku': '', 'tsId': ''};
var response = UrlFetchApp.fetch(url,{muteHttpExceptions: true});
var page = response.getContentText();
//Konfiguration für Produktbewertung suchen
var config = page.match(/_tsProductReviewsConfig\s*=\s*{([\s\S]*?)}/i);
if (page.indexOf('_tsProductReviewsConfig') >= 0) {
if (config) {
//SKU aus Konfiguration extrahieren
var cnf = config[1];
//Trusted Shops Id extrahieren
var tsId = cnf.match(/tsId\s*:\s*\'([\s\S]*?)\'/i);
tsId = tsId[1];
sku = cnf.match(/sku\s*:\s*\[([\s\S]*?)\]/i);
if (!sku) {
sku = cnf.match(/sku\s*:\s*'([\s\S]*?)'/i);
sku = sku[1];
} else {
sku = sku[1].replace(/'/ig, '');
//Sind ggf. mehrere Nummern vorhanden? Nur erste Nummer verwenden
sku = sku.split(",")[0];
}
if (!tsId) {
Logger.log("Trusted Shops Id nicht gefunden bei "+url);
} else {
if (sku) {
res.sku = sku; res.tsId = tsId;
} else
Logger.log("SKU nicht gefunden bei "+url);
}
}
} else Logger.log("Konfigurationsblock nicht gefunden bei "+url);
return res;
}
//Value Track Parameter entfernen, wenn in URL vorhanden
function cleanUrl(url) {
if(url.indexOf('{') >= 0) url = url.replace(/\{[0-9a-zA-Z]+\}/g,'');
return url;
}
function needsLabel(lbl) {
//angefordertes Label anlegen, wenn noch nicht vorhanden
if (!(AdWordsApp.labels().withCondition("Name = '" + lbl + "'").get().hasNext())) {
if (AdWordsApp.getExecutionInfo().isPreview())
Logger.log("Label '"+lbl+"' manuell anlegen, damit die Vorschau genutzt werden kann oder das Script ausführen lassen");
else
AdWordsApp.createLabel(lbl, "Markiert Daten für API Abruf von Produktbewertungen per Script", "#C44E00");
Utilities.sleep(1000);
}
return true;
}
@mbaersch
Copy link
Author

Google AdWords Script zur dynamischen Anzeige von Trusted Shops Produktbewertungen

Das Script befüllt anhand von Ziel-URLs für Keywords oder auf Anzeigengruppenebene alle Keywords mit den entsprechenden Trusted Shops Bewertungen, welche über die API abgerufen werden. Die erforderlichen Parameter werden dazu aus der angegebenen Zielseite ausgelesen.

Voraussetzungen

Die Produktbewertung muss in der Zielseite eingebunden sein. Dadurch enthält die Seite zwar die Bewertung nicht im Quellcode, sondern lädt diese selbst nach, aber so kann das Script dort die notwendigen Angaben zur Ermittlung der Bewertung per API beziehen.

Anzeigegruppen, die diese Funktion nutzen, müssen “lückenlos” mit Bewertungen vom Script versorgt werden können. Damit dies gelingt, sind entweder passende Ziel-Urls auf Keywordebene zu vergeben oder die Kampagne sollte “kleinteilig” auf Anzeigengruppenebene aufgeteilt sein, so dass jedes Produkt eine passende Anzeige oder zumindest eine eigene Ziel-Url besitzt, die zur Produktdetailseite führt.

Installation

Nachdem mindestens eine geeignete Anzeigengruppe im Konto identifiziert oder bestückt wurde, wird / werden diese mit einem Label versehen. Anhand dieses Labels wird definiert, welche Anzeigengruppen das Script bearbeiten soll. Dazu markiert man eine oder mehrere Anzeigegruppen in der Übersicht und wählt unter “Labels” ein bereits bestehendes Label aus oder legt eins an. Das Script verwendet per Vorgabe ein Label mit der Bezeichnung “ApiRating”.

Der Scriptcode wird im Konto unter “Gemeinsam genutzte Bibliothek -> Bulk-Vorgänge -> Scripts” eingetragen. Dazu auf “+Script” klicken, einen Namen vergeben und den kopierten Scriptcode (siehe unten) über die Zwischenablage einfügen. In der Konfiguration sind für einen ersten Durchlauf keine Einstellungen neben der Label-Bezeichnung erforderlich. Bevor das Script gestartet oder die Vorschau genutzt werden kann, ist aber noch eine Autorisierung erforderlich.

Verwendung

Wird das Script gestartet oder (nach Anlage des erforderlichen Labels) in der Vorschau betrachtet, werden anhand der Zieladressen der Keywords oder ersatzweise der verwendeten Anzeigen die Produktkennzeichnungen (“SKU”) und die Trusted Shops ID aus den Zielseiten ausgelesen. Anhand dieser Informationen werden dann die Bewertungen per API tagesaktuell bei Trusted Shops abgerufen und als Parameter “param1″ beim Keyword gespeichert. Nach Abschluss wird die Anzahl der zugewiesenen Bewertungen im Protokoll ausgegeben. Wurde die Variable “doLog” auf “true” gestellt, werden während der Verarbeitung bereits die aktualisierten Keywords und zugewiesenen Bewertungen angezeigt.

Kontrolldurchlauf

Um die korrekte Funktion zu kontrollieren, kann die Variable “doList” nach einem ersten Durchgang auf “true” gestellt werden, um die gespeicherten Parameter der Keywords im Protokoll anzuzeigen (Vorschau reicht aus).

Denn die so definierten Parameter sind weder in AdWords noch dem AdWords Editor sichtbar. Sie haben auch keine Auswirkungen auf die Anzeigen, solange diese nicht im Anzeigentext als Parameter {param1} eingelesen werden. Dazu muss noch eine passende Anzeige erstellt werden.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment