4 Google Ads Scripts, mit denen Sie Geld & Ressourcen sparen [inkl. Download-Script]

Google hat seit 2018 das Thema Automatisierungen bei Google Ads stark in den Vordergrund gestellt. Trotzdem ist PPC Management zu einem großen Teil noch immer Handarbeit. Zum einen lassen sich "one-size-fits-all" Algorithmen nie 100%ig auf das eigene Geschäftsmodell anwenden, zum anderen beruht Googles Geschäftsmodell nun mal auf den Ausgaben der Werbetreibenden - nicht auf deren Einnahmen. Will man bei mühsamen, wiederkehrenden oder zeitaufwändigen Aufgaben Ressourcen sparen, kommt man irgendwann an Google Ads Scripts nicht mehr vorbei. Im Folgenden haben wir vier unserer liebsten Scripts gesammelt und für Sie aufbereitet.

Autor: trafficdesign

· Veröffentlicht: · Zuletzt aktualisiert: ·

Google Ads

· 15 Min. Lesezeit

Wie werden Google Ads Scripts im Account hinterlegt?

Google Ads Scripts können auf Konto- oder Verwaltungskonto-Ebene hinterlegt werden. Zweiteres hat den Vorteil, dass so bestimmte Vorgänge für viele verschiedene Accounts gleichzeitig automatisieren kann. Die Einrichtung funktioniert bei beiden Arten gleich:

  1. Klicken Sie oben in der Leiste auf Tools (Schraubenschlüssel-Symbol)
  2. Dann unter Bulk-Aktionen auf Scripts
  3. Jetzt befinden Sie sich in der Scripts-Übersicht. Falls noch kein Script im Konto hinterlegt wurde, ist hier noch nicht viel zu sehen. Klicken Sie als Nächstes auf das + Symbol
  4. Es öffnet sich ein Text-Editor: Fügen Sie hier das Script ihrer Wahl ein.
    • Achten Sie darauf, dass Sie die leere Platzhalter-Funktion im Text-Editor vorher entfernen.
  5. Wenn das Script bestimmte Einstellungen benötigt, nehmen Sie diese jetzt vor
  6. Geben Sie dem Script einen eindeutigen Namen und speichern Sie
  7. Als Nächstes muss das Script autorisiert werden (gelbe Leiste oben)
    • Dies ist wichtig, da Scripts Änderungen am Konto durchführen können und dafür eine separate Freigabe benötigen.
  8.  Nun können Sie eine Vorschau durchführen, um zu testen, ob alles funktioniert.
    • Achten Sie hierbei auf die Änderungen und das Protokoll. Die Änderungen zeigen die eigentlichen Vorgänge im Konto, die Protokolle Fehler oder Logs.
  9. Nun können Sie das Script entweder direkt durchführen oder für später planen. Eine regelmäßige Durchführung (z.B. wöchentlich) ist natürlich auch möglich.

Landing Page Checker: Klicks auf fehlerhafte Seiten vermeiden

Bei großen Google Ads Accounts steht man häufig vor der Frage, wie man sicherstellen kann, dass alle Zielseiten noch funktionieren. Gerade wenn es eine Vielzahl an unterschiedlichen Landing Pages gibt, wie zum Beispiel im E-Commerce-Bereich, kann es immer mal wieder vorkommen, dass eine Seite nicht mehr verfügbar oder ein Produkt nicht mehr auf Lager ist. Sobald die Anzahl der Zielseiten in die hunderte oder tausende gerät, ist der Zeitaufwand, der in eine manuelle Kontrolle gesteckt werden muss, oft nicht mehr verhältnismäßig. Google crawlt die Landing Pages natürlich auch regelmäßig und lehnt Anzeigen mit nicht funktionierenden Zielen konsequent ab, für alle Klicks, die bis dahin entstanden sind, muss man jedoch trotzdem bezahlen.

Google Ads Scripts bieten hierfür jedoch eine Lösung: Die Klasse HTTP Response (gibt Inhalte von URL abfragen wieder) und deren Methoden getContentText (gibt den Quelltext wieder), sowie getResponseCode (gibt den Statuscode wieder). Mit diesen Bausteinen lässt sich ein relativ einfaches Script gestalten, dass alle Zielseiten in einem Google Ads Account auf folgende Aspekte kontrolliert und dann eine E-Mail mit einer Liste aller problematischen URLs verschickt.

  • Ungewünschte Status Codes: Zum Beispiel 404 oder 302
  • Auffällige Phrasen, die auf Probleme hinweisen: Zum Beispiel: „Ausverkauft“, „Ein Problem ist aufgetreten“ oder „nicht auf Lager“.

Wir haben eine Vorlage entworfen, die von jedem Google Ads Account Manager gänzlich ohne Programmier-Kenntnisse genutzt werden kann. Passen Sie einfach die Grundeinstellungen in den ersten Zeilen (über dem TrafficDesign-Logo) an und geben Sie im Google Ads Konto an, in welchem Rhythmus das Script ausgeführt werden soll (z.B. wöchentlich). Vergessen Sie nicht, oben im Script max@mustermann.de durch Ihre richtige E-Mail Adresse auszutauschen, damit Google weiß, wohin der Bericht geschickt werden soll.

/**
*
* Landing Page Checker
*
* Version: 1.0 (29.04.2019)
*
* Google Ads Script um Landing Pages auf bestimmte Wörter (z.B. „Ausverkauft“) und Status Codes (404) zu überprüfen.
*
* Das Script steht zur freien Verfüfung, kann kommerziell genutzt und geändert werden. Ursprüngliche Erstellung: trafficdesign.de
*
**/

function main() {

// An diese Adresse wird eine E-Mail allen problematischen Landing Pages geschickt.
// Eingabe: [„info@trafficdesign.de“] oder [„a@b.de“,“c@d.com“,“e@g.de“]
// Leer lassen um diesen Schritt zu überspringen.
var recipients = [„max@mustermann.de“];

// Nach welchen Wörtern oder Phrasen soll das Script in Quellcode der Landing Page suchen?
// Wie folgt eingeben: [„Out of stock“, „<em>0 available</em>“]
var messagesToCheckFor = [„traffic“, „design“];

// Nach welchen Fehler Codes soll das Script suchen. Mehr dazu hier: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
var bad_codes = [
300, 302, 303, 304, 305, 306, 307, 308,
400, 401, 402, 403, 404, 405, 406, 407, 408, 409,
410, 411, 412, 413, 414, 415, 416, 417, 418, 419,
421, 422, 423, 424, 426, 428, 429,
431,
451,
500, 501, 502, 503, 504, 505, 506, 507, 508, 509,
510, 511];

// Sollen Parmaeter (die z.B. für Tracking verwendet werden) aus den Urls entfernt werden?
// Engabe: true oder false
var trimAtQuestionMark = true;

// Werden die Landing Pages im Konto über Anzeigen oder Keywords definiert
// Eingabe: ads oder keywords
var type = „ads“;

// Status-Filter
// [„ENABLED“], [„PAUSED“] oder [„ENABLED“,“PAUSED“]

// Kampagnenstatus
var campaignStatus = [„ENABLED“];

// Anzeigengruppenstatus
var adGroupStatus = [„ENABLED“];

// Keyowrd/Ad-Status
var status = [„ENABLED“];

// Optionale Filter
// Eingabe: [„beispiel1“, „beispiel2″]
// Leer lassen [] zum überspringen

// Nur auf Kampagnen in deren Namen eine dieser Phrasen vorkommt anwenden.
var containsArray = [];

//  Kampagnen in deren Namen eine dieser Phrasen vorkommt werden ignoriert
var excludesArray = [];

// Nur Keyowrds/Ads mit diesen Labels checken
// Case sensitive.
var labelArray = [];

/**
*   _____         ___ ___ _     ____          _
*  |_   _|___ ___|  _|  _|_|___|    \ ___ ___|_|___ ___
*    | | |  _| .’|  _|  _| |  _|  |  | -_|_ -| | . |   |
*    |_| |_| |__,|_| |_| |_|___|____/|___|___|_|_  |_|_|
*                                              |___|
*
* www.trafficdesign.de | info@trafficdesign.de
*
**/

var urls = [];
var bad_lps = [];
var bad_statuses = [];
var urlFetchOptions = {muteHttpExceptions: true};
var countEntities = 0;

var conditions = [];
if (containsArray.length > 0) {
conditions.push(“ where the campaign name contains “ + containsArray.join(„, „));
}
if (excludesArray.length > 0) {
conditions.push(“ where the campaign name excludes “ + excludesArray.join(„, „));
}
if (labelArray.length > 0) {
conditions.push(“ where the “ + type + “ are labelled “ + labelArray.join(„, „));
}

if (containsArray.length === 0) {
containsArray.push(„“);
}

for(var i = 0; i < containsArray.length; i++){
var string = iteratorConstructor(type, containsArray[i], excludesArray, labelArray, status, campaignStatus, adGroupStatus);
eval(string);
countEntities += iterator.totalNumEntities();
excludesArray.push(containsArray[i]);
while(iterator.hasNext()){
var object = iterator.next();
var url = object.urls().getFinalUrl();

if(url == null || url == undefined){
url = object.getDestinationUrl();
}

if(url !== null && url !== undefined){
if(trimAtQuestionMark){
url = url.split(‚?‘)[0];
}
if(urls.indexOf(url) === -1) {
urls.push(url);
}
}
}
}

if (countEntities == 0) {
throw „No “ + type + “ found“ + conditions.join(„; and“);
}
Logger.log(countEntities + “ “ + type + “ found“ + conditions.join(„; and“));
Logger.log(urls.length + “ unique URLs to check.“);

for(var x in urls){
var response = UrlFetchApp.fetch(urls[x],urlFetchOptions);
var content = response.getContentText();
var code = response.getResponseCode();
for(var y = 0; y < messagesToCheckFor.length; y++){
var message = messagesToCheckFor[y];
if(bad_codes.indexOf(code) !== -1) {
bad_statuses.push(urls[x]);
break;
}
if(content.indexOf(message) !== -1){
bad_lps.push(urls[x]);
break;
}
}
}

if ((bad_lps.length === 0) && (bad_statuses.length === 0)) {
Logger.log(„No bad Landing Pages found.“);
} else {
Logger.log(bad_statuses.length + “ lps with bad statuses found:“);
Logger.log(bad_statuses.join(„\n“));
Logger.log(bad_lps.length + “ lps with bad phrases found:“);
Logger.log(bad_lps.join(„\n“));

}

if((recipients.length > 0 && bad_lps.length > 0) || (recipients.length > 0 && bad_statuses.length > 0)) {
var name = AdWordsApp.currentAccount().getName();
var subject = name + “ – Google Ads: Landing Page Checker „;
var body = ‚Folgende Zielseiten haben mit einem problematischen Status Code geantwortet oder es wurde eine der folgenden Phrasen/Keywords im Quelltext gefunden. \n\n“‚ + messagesToCheckFor.join(‚“,\n“‚) + ‚“\n\nURLs:\n‘;
body += bad_statuses.join(„\n“);
body += bad_lps.join(„\n“);
MailApp.sendEmail(recipients.join(„,“),subject,body);
Logger.log(„Email sent to “ + recipients.join(„, „));
}

function iteratorConstructor(type, containsString, excludesArray, labelArray, status, campaignStatus, adGroupStatus){

var string = „var iterator = AdWordsApp.“+type+“()“;
if (containsString != „“) {
string = string + „.withCondition(‚CampaignName CONTAINS_IGNORE_CASE “ + ‚“‚ + containsString + ‚“‚ + „‚)“;
}
for(var i = 0; i < excludesArray.length; i++){
string = string + „.withCondition(‚CampaignName DOES_NOT_CONTAIN_IGNORE_CASE “ + ‚“‚ + excludesArray[i] + ‚“‚ + „‚)“;
}
if(labelArray.length > 0){
string = string + „.withCondition(‚LabelNames CONTAINS_ANY “ + ‚[„‚ + labelArray.join(‚“,“‚) + ‚“]‘ + „‚)“;
}

string = string + „.withCondition(‚Status IN [“ + status.join(„,“) + „]‘)“;
string = string + „.withCondition(‚CampaignStatus IN [“ + campaignStatus.join(„,“) + „]‘)“;
string = string + „.withCondition(‚AdGroupStatus IN [“ + adGroupStatus.join(„,“) + „]‘)“;
string = string + „.orderBy(‚Cost DESC‘).forDateRange(‚LAST_30_DAYS‘)“;
string = string + „.withLimit(50000)“;

string = string + „.get();“;

return string;

}

}

Smart Auto-Bidder: Automatische Gebotserhöhung basierend auf Wert pro Kosten und Kosten pro Konversion

Der Smart Auto-Bidder ist so etwas, wie ein semi-automatisches Bid Management Tool. Bei der Benutzung sollte man deshalb vorsichtig sein, da bei falscher Benutzung eventuell die CPCs ungewollt maximiert werden. Der Auto-Bidder ist in der Lage, die Gebote in einem Account (oder in bestimmten Kampagnen) auf Basis der folgenden Metriken zu erhöhen:

  • Wert pro Kosten
  • Kosten pro Konversion

In den Script-Einstellungen können Sie auswählen, auf welche Metrik optimiert werden soll, wie Ihre Zielwerte definiert sind und um wie viel Prozent die Gebote pro Durchführung (z.B. einmal die Woche) erhöht werden soll. Zusätzlich labeled das Script alle modifizierten Keywords, sodass Sie diese bei Bedarf manuell kontrollieren können.

/**
*
* Google Ads Script um Google Ads Search und Shopping CPCs in der Masse anzupassen.
*
* Das Script steht zur freien Verfüfung, kann kommerziell genutzt und geändert werden. Ursprüngliche Erstellung: trafficdesign.de
*
**/

// SETTINGS

// Bei Ja/Nein-Einstellungen ist immer 1 = Ja und 0 = Nein

// Soll nach Kampagnen gefiltert werden? (1=Ja, 0=Nein)
var campaignFilter = 1;

// Wenn gefiltert werden soll, gebe hier den NAmen der Kampagne ein
var campaignFilterName = „c_1 Veranstaltungen Köln“;

// Name des Labels, welches markiert, dass etwas gemacht wurde (Standard ist td_b)
var labelName = „td_b“;

// Keywords mit Kosten von über X innerhalb der letzten 7 Tage werden nicht geändert.
// Das ist wichtig, wenn man z.B. alle Keywords über X Euro manuell bearbeiten möchte, alle anderen aber per Script
var costTreshhold = 10.00;

// Das maximale Gebot, auf welches das Script hochbietet
var maxCPC = 5.00;

// Um wieviel % der CPC pro Script-Durchfürhung erhöht werden soll (1.25 = 25%)
var perUp = 1.25;

// WK-Bidding

// Soll sollen Gebote auf CPA-Basis erhöt werden? (1=Ja, 0=Nein)
var wkBidding = 0;

// Der Ziel-CPA mit der wir arbeiten
var targetWK = 7.5;

// CPA-Bidding

// Soll sollen Gebote auf CPA-Basis erhöt werden? (1=Ja, 0=Nein)
var cpaBidding = 0;

// Der Ziel-CPA mit der wir arbeiten
var targetCPA = 2.5;

// ImpressionShare-Bidding

/**
*
* Smart Auto-Bidder
*
* Version: 1.1 (03.05.2019)
*
* Google Ads Script um Google Ads Search und Shopping CPCs in der Masse anzupassen.
*
* Das Script steht zur freien Verfüfung, kann kommerziell genutzt und geändert werden. Ursprüngliche Erstellung: trafficdesign.de
*
**/

// SETTINGS

// Bei Ja/Nein-Einstellungen ist immer 1 = Ja und 0 = Nein

// Zeitraum der Daten: Standard ist LAST_7_DAYS. Weitere Möglichkeiten: TODAY, YESTERDAY, LAST_7_DAYS, THIS_WEEK_SUN_TODAY, LAST_WEEK, LAST_14_DAYS, LAST_30_DAYS, LAST_BUSINESS_WEEK, LAST_WEEK_SUN_SAT, THIS_MONTH, LAST_MONTH, ALL_TIME.
var timespan = „LAST_7_DAYS“;

// Soll nach Kampagnen gefiltert werden? (1=Ja, 0=Nein)
var campaignFilter = 0;

// Wenn gefiltert werden soll, gebe hier den NAmen der Kampagne ein
var campaignFilterName = „“;

// Name des Labels, welches markiert, dass etwas gemacht wurde (Standard ist td_b)
var labelName = „td_b“;

// Keywords mit Kosten von über X innerhalb der letzten 7 Tage werden nicht geändert.
// Das ist wichtig, wenn man z.B. alle Keywords über X Euro manuell bearbeiten möchte, alle anderen aber per Script
var costTreshhold = 10.00;

// Das maximale Gebot, auf welches das Script hochbietet
var maxCPC = 5.00;

// Um wieviel % der CPC pro Script-Durchfürhung erhöht werden soll (1.25 = 25%)
var perUp = 1.25;

// WK-Bidding

// Soll sollen Gebote auf CPA-Basis erhöt werden? (1=Ja, 0=Nein)
var wkBidding = 1;

// Der Ziel-CPA mit der wir arbeiten
var targetWK = 7.5;

// CPA-Bidding

// Soll sollen Gebote auf CPA-Basis erhöt werden? (1=Ja, 0=Nein)
var cpaBidding = 0;

// Der Ziel-CPA mit der wir arbeiten
var targetCPA = 2.5;

/**
*   _____         ___ ___ _     ____          _
*  |_   _|___ ___|  _|  _|_|___|    \ ___ ___|_|___ ___
*    | | |  _| .’|  _|  _| |  _|  |  | -_|_ -| | . |   |
*    |_| |_| |__,|_| |_| |_|___|____/|___|___|_|_  |_|_|
*                                              |___|
*
* www.trafficdesign.de | info@trafficdesign.de
*
**/

function main() {
getdate();
updateLabel();
if (wkBidding == 1) {
wkAutoBidding();
}
if (cpaBidding == 1) {
cpaAutoBidding();
}
}

function getdate() {
var date = new Date();
printDate = Utilities.formatDate(date, ‚Europe/Berlin‘, ‚yyMMdd‘);
Logger.log(„Datum: “ + printDate + „\n\n“);
}

function updateLabel() {
var labelIterator = AdsApp.labels()
.withCondition(„Name CONTAINS ‚“+labelName+“‚“)
.get();
if (labelIterator.hasNext()) {
var label = labelIterator.next();
Logger.log(‚Cleaning up old Labels…‘ + „\n\n“);
Logger.log(‚Name: ‚ + label.getName());
Logger.log(‚Number of campaigns: ‚ +
label.campaigns().get().totalNumEntities());
Logger.log(‚Number of ad groups: ‚ +
label.adGroups().get().totalNumEntities());
Logger.log(‚Number of ads: ‚ + label.ads().get().totalNumEntities());
Logger.log(‚Number of keywords: ‚ +
label.keywords().get().totalNumEntities());
label.remove();
Logger.log(‚Label removed‘ + „\n\n“);
}

labelName = (labelName + „_“ + printDate);
Logger.log(‚Erstelle neues Label: ‚ + labelName + „\n\n“);
AdsApp.createLabel(labelName);
}

function wkAutoBidding() {
Logger.log(‚Erhöhe CPCs basierend auf WK…‘ + „\n\n“);

var query = „SELECT CampaignName, AdGroupId, Id, ConversionValue, Cost, Conversions “ +
“ FROM KEYWORDS_PERFORMANCE_REPORT “ +
“ WHERE “ +
(campaignFilter!=0 ? “ CampaignName = ‚“ + campaignFilterName + „‚ AND “ : „“) +
“ Conversions > 0 “ +
“ DURING “ + timespan;
// Logger.log(„Performed Query: “ + query + „\n“);
var report = AdsApp.report(query);
var rows = report.rows();
var keywords = [];

// Map of keyword id to WK
var keywordWK = {};
// List of all keyword ids ([AdGroupId, Id])
var keywordIds = [];

if (!rows.hasNext()) Logger.log(„No Keywords found!\n“);

Logger.log(„Ziel WK: “ + targetWK + „\n\n“);
while (rows.hasNext()) {
var row = rows.next();
var kWK = row[„ConversionValue“] / row[„Cost“];
// Logger.log(„Keyword ID: “ + row[‚Id‘] +“ – WK: “ + kWK + „\n“);
if (kWK > targetWK) {
row[„kWK“] = kWK;
keywordWK[row[„AdGroupId“],row[„Id“]] = row;
keywordIds.push([row[„AdGroupId“],row[„Id“]]);
}
}

var keywords = AdsApp.keywords().withIds(keywordIds).get();
while (keywords.hasNext()) {
var thisKeyword = keywords.next();
var kwRow = keywordWK[thisKeyword.getAdGroup().getId(),thisKeyword.getId()];
var currCPC = thisKeyword.bidding().getCpc();

var newCPC = currCPC; //just set so newCPC always has a default value;
newCPC = currCPC * perUp; //easy

thisKeyword.bidding().setCpc(newCPC);
AdsApp.createLabel(labelName + „_“ + printDate);
thisKeyword.applyLabel(labelName + „_“ + printDate);

Logger.log(„Keyword: “ + thisKeyword.getText() + „\n“ + „alter CPC: “ + currCPC + „\n“ + „neuer CPC: “ + newCPC + „\n“ + „neues Label: “ + labelName + „_“ + printDate + „\n\n“);

}
}

function cpaAutoBidding() {
var query = AdsApp.keywords()
.withCondition(„CampaignStatus = ‚ENABLED'“)
.withCondition(„AdGroupStatus = ‚ENABLED'“)
.withCondition(„Status = ‚ENABLED'“)
.withCondition(‚LabelNames CONTAINS_NONE [„‚ + labelName + ‚“]‘)
.forDateRange(timespan);

// Checks if Campaign Filter is active and applies it if necessary
if (campaignFilter != 0) {
query.withCondition(‚CampaignName = „‚ + campaignFilterName +'“‚);
}

var keywordIter = query.orderBy(„Cost DESC“).get();

Logger.log(‚Erhöhe CPCs basierend auf CPA…‘ + „\n\n“);

Logger.log(„Ziel CPA: “ + targetCPA + „\n\n“);

while (keywordIter.hasNext()) {
var thisKeyword = keywordIter.next();
// Get Stats der letzten 7 Tage
var stats = thisKeyword.getStatsFor(„LAST_7_DAYS“);
var kConv = stats.getConversions();
var kCost = stats.getCost();
var kCPA = 0;
if ((kCost / kConv) > 0){
kCPA = (kCost / kConv);
}

if(kCPA < targetCPA) { //Wenn der CPA besser ist als der Ziel CPA
if(kCost > costTreshhold) { //don’t change bids for Keywords with cost > X

kCPA = kCPA.toFixed(2); //set to two decimal places, just for clarity in logging

var currCPC = thisKeyword.getMaxCpc();
var newCPC = currCPC; //just set so newCPC always has a default value;

newCPC = currCPC * perUp; //easy

//we always want CPC below upper limit
if(newCPC > maxCPC) {newCPC = maxCPC;}

newCPC = newCPC.toFixed(2);

thisKeyword.setMaxCpc(newCPC);
AdsApp.createLabel(labelName + „_“ + printDate);
thisKeyword.applyLabel(labelName + „_“ + printDate);

Logger.log(„Keyword: “ + thisKeyword.getText() + „\n“ + „CPA: “ + kCPA + „\n“ + „alter CPC: “ + currCPC + „\n“ + „neuer CPC: “ + newCPC + „\n“ + „neues Label: “ + labelName + „_“ + printDate + „\n\n“);
}
}
}
}

CPC-Massenbearbeitung: Kontoweite Gebotsanpassungen leicht gemacht

Etwas bodenständiger, als beim Smart Auto-Bidder, geht es bei der CPC-Massenbearbietung vor: Manchmal will man ganz simpel alle Gebote in einem Konto um einen bestimmten Wert reduzieren. Möchte man zum Beispiel über die Weihnachtsfeiertage alle CPCs in einem Account während einer geplanten Zeitspanne um 50 % reduzieren, merkt man schnell, dass dies einfacher klingt, als es ist.

  • Über automatisierte Regeln lassen sich keine Shopping-Gebote anpassen
  • Über den Google Ads Editor lässt sich die Durchführung nicht schedulen
  • Manuell ist wiederum sehr aufwändig

Deshalb haben wir ein kleines Script erstellt, das wie automatisierte Regeln geplant werden kann und auch für Google Shopping CPCs funktioniert:

/**
*
* CPC-Massenbearbeitung
*
* Version: 1.0 (29.04.2019)
*
* Google Ads Script um Google Ads Search und Shopping CPCs in der Masse anzupassen.
*
* Das Script steht zur freien Verfüfung, kann kommerziell genutzt und geändert werden. Ursprüngliche Erstellung: trafficdesign.de
*
**/

// SETTINGS

// Bei Ja/Nein-Einstellungen ist immer 1 = Ja und 0 = Nein

// um wieviel % soll der Search-CPC pro Script-Durchfürhung angepasst werden? (0.6 = 60 %)
var searchChange = 0.60;

// um wieviel % soll der Shopping-CPC pro Script-Durchfürhung angepasst werden? (0.6 = 60 %)
var shoppingChange = 0.60;

// Soll der CPC erhöht oder verringert werden? (1=erhöht, 0=verringert)
var changeType = 1;

/**
*   _____         ___ ___ _     ____          _
*  |_   _|___ ___|  _|  _|_|___|    \ ___ ___|_|___ ___
*    | | |  _| .’|  _|  _| |  _|  |  | -_|_ -| | . |   |
*    |_| |_| |__,|_| |_| |_|___|____/|___|___|_|_  |_|_|
*                                              |___|
*
* www.trafficdesign.de | info@trafficdesign.de
*
**/

function main() {
setKeywordCpcBid();
setShoppingCpcBid();
}

function setKeywordCpcBid() {
var keywordsToChange = AdsApp.keywords()
.withCondition(‚CampaignStatus = ENABLED‘)
.withCondition(‚AdGroupStatus = ENABLED‘)
.get();
while (keywordsToChange.hasNext()) {
var keyword = keywordsToChange.next();
if (changeType == 1) {
keyword.setMaxCpc(keyword.getMaxCpc() * (1 + searchChange));
} else {
keyword.setMaxCpc(keyword.getMaxCpc() * (1 – searchChange));
}
}
}

function setShoppingCpcBid() {
var ProductGroupToChange = AdsApp.productGroups()
.withCondition(‚CampaignStatus = ENABLED‘)
.withCondition(‚AdGroupStatus = ENABLED‘)
.get();
while (ProductGroupToChange.hasNext()) {
var productGroup = ProductGroupToChange.next();
if (changeType == 1) {
productGroup.setMaxCpc(productGroup.getMaxCpc() * (1 + shoppingChange));
} else {
productGroup.setMaxCpc(productGroup.getMaxCpc() * (1 – shoppingChange));
}
}
}

Placement-Ausschluss nach Top-Level-Domain: Ungewollte Placements automatisch ausschließen

Google hat die Einstiegshürden bei Display-Kampagnen in den letzten Jahren immer weiter herabgesetzt. Banner-Kampagnen lassen sich mittlerweile leichter aufsetzen als zum Beispiel Google Shopping Kampagnen. Erst im Verlauf der Optimierung (oder mit ein bisschen Erfahrung) fällt einem dann auf, dass für eine gute Performance ganz schön viele Stellschrauben gedreht werden müssen. Gerade bei den Placements muss man je nach Budget besonders engmaschig kontrollieren, wo die Anzeigen ausgespielt wurden. Häufig fällt dann auf, dass im Tab „Wo Anzeigen ausgespielt wurden“ viele unpassende URLs erscheinen. Gerade unpassende Top-Level-Domains sind dabei leicht zu identifizieren und können effizient über eine Automatisierung ausgeschlossen werden.

Wollen Sie also pauschal bestimmte Länderkennungen ausschließen (z.B. .ro, .ba, .bg, .br, .cz bei einer Kampagne, deren Targeting eigentlich in anderen Ländern liegt) oder vermeiden, dass Ihre Anzeigen auf den typischen Affiliate-Domains (.top) ausgespielt werden, können wir Ihnen folgendes Script ans Herz legen. Die ursprüngliche Version stammt von Dawson Reid und Andrew Breen (outshine.com). Wir haben diese übersetzt, an die neue Google Ads Version angepasst und ein Bug bei Placements mit einem vorgestellten www. behoben:

/**
*
* Placement-Ausschluss nach Top-Level-Domain
*
* Version: 1.1 (29.04.2019)
*
* Google Ads Script, welches automatisch ungewollte Display Placements, nach TLD ausschließt (Beispiel: Alle .xyz-Domains). Das Script funktioniert auf Account und auf MCC-Level.
*
* Das Script steht zur freien Verfüfung, kann kommerziell genutzt und geändert werden. Ursprüngliche Erstellung: Dawson Reid und Andrew Breen (https://outshine.com/blog/automate-negative-placement-in-google-display-with-this-script). Überarbeitung: trafficdesign.de
*
**/

// SETTINGS

// Top Level Domains to exclude
var TLDs = ‚.ro, .ba, .bg, .br, .cz, .es, .gr, .hr, .hu, .it, .me, .nl, .pl, .rs, .ro, .ru, .su, .sk, .tr, .vd, .xyz, .space, .top, .review‘;

/**
*   _____         ___ ___ _     ____          _
*  |_   _|___ ___|  _|  _|_|___|    \ ___ ___|_|___ ___
*    | | |  _| .’|  _|  _| |  _|  |  | -_|_ -| | . |   |
*    |_| |_| |__,|_| |_| |_|___|____/|___|___|_|_  |_|_|
*                                              |___|
*
* www.trafficdesign.de | info@trafficdesign.de
*
**/

function removePlacementByDomain (domain) {
var placementSelector = AdsApp.display().placements()
.withCondition(„PlacementUrl CONTAINS ‚“ + domain + „‚“)
.withCondition(„PlacementUrl DOES_NOT_CONTAIN ‚“ + „www“ + domain + „‚“);

var placementIterator = placementSelector.get();
while (placementIterator.hasNext()) {
var placement = placementIterator.next();
var placementUrl = placement.getUrl();
Logger.log(placementUrl);

var campaign = placement.getCampaign();
if (!campaign.isRemoved()) {
var excludeOperation = campaign.display().newPlacementBuilder().withUrl(placementUrl).exclude();
if (!excludeOperation.isSuccessful()) {
Logger.log(„Konnte nicht ausschließen: “ + placementUrl);
}
}
}
}

function run () {
TLDs.split(‚,‘).map(function (tld) {
return tld.trim();
}).forEach(function (domain) {
removePlacementByDomain(domain);
});
}

function executeInSequence (sequentialIds, executeSequentiallyFunc) {
Logger.log(‚Executing in sequence : ‚ + sequentialIds);
sequentialIds.forEach(function (accountId) {
var account = MccApp.accounts().withIds([accountId]).get().next();
MccApp.select(account);
executeSequentiallyFunc();
});
}

function main () {
try {
var accountIterator = MccApp.accounts().orderBy(‚Name‘).get();
Logger.log(‚Accounts im MCC: ‚ + accountIterator.totalNumEntities());

var accountIds = [];
while (accountIterator.hasNext()) {
var account = accountIterator.next();
accountIds.push(account.getCustomerId());
}
var parallelIds = accountIds.slice(0, 50);
var sequentialIds = accountIds.slice(50);
// execute accross accounts
MccApp.accounts()
.withIds(parallelIds)
.executeInParallel(‚run‘);
if (sequentialIds.length > 0) {
executeInSequence(sequentialIds, run);
}
} catch (exception) {
// not an Mcc
Logger.log(‚Start (einzelner Account)‘);
run();
}
}

Fazit

Beim täglichen Google Ads Management kommt man häufig irgendwann an einen Punkt, an dem man sich die Frage stellt, ob man wiederkehrende Aufgaben nicht automatisieren kann. Hat man im Unternehmen jemanden der über grundlegende JavaScript-Kenntnisse verfügt, kann man über Google Ads Scripts mittelfristig häufig wertvolle Ressourcen sparen. Die erste Anlaufstelle ist dann natürlich die offizielle Dokumentation von Google. Hier finden sich auch einige nützliche Beispiele und Vorlagen. Wir haben im Laufe der Zeit unsere eigenen Lösungen implementiert und erweitert und möchten diese gerne der Öffentlichkeit zu Verfügung stellen. Des Weiteren werden wir diese Liste kontinuierlich erweitern. Welche Aufgabe würden Sie zukünftig gerne automatisieren?

Brauchen Sie Unterstützung bei diesem Thema?

Sprechen Sie uns unverbindlich an und lassen Sie sich von uns beraten.

Anfrage schicken!

  • Wie erstelle ich einen Google Shopping Feed?

    Google Shopping bezeichnet die Produktsuche von Google. Für Online Shops ist es möglich bezahlte Anzeigen (sog. Product Listing Ads) über Google Ads zu schalten. Dabei werden die einzelnen Produkte inklusive Produktinformationen und einem Bild in den Suchergebnissen angezeigt. Um Informationen…

  • Google Ads Conversion Tracking richtig einrichten

    Früher hat Google Ads seine Tracking Codes in zwei Kategorien eingeteilt: Conversion Tracking (Erfolgsmessung) und Remarketing (Zielgruppenanalyse). Seit Ende 2018 gibt es jedoch nur noch einen Tracking Code, der (mit jeweils leichten Anpassungen) für verschiedene Use Cases und Google Tools…

  • Kampagnentests in Google Ads: Eine Step-by-Step-Anleitung

    Erfolgreiches Online Marketing basiert zu einem großen Teil darauf, verschiedene Strategien, Texte und Kampagnen auszuprobieren und zu testen – auch im Google Ads Konto. Viele kennen es wahrscheinlich: Eine Änderung im Konto soll getestet werden, allerdings gibt es Bedenken, dass…