Skip to content

Instantly share code, notes, and snippets.

@alewolf
Last active November 28, 2017 11:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alewolf/91bc532014453ec2eac801bf342ee1f9 to your computer and use it in GitHub Desktop.
Save alewolf/91bc532014453ec2eac801bf342ee1f9 to your computer and use it in GitHub Desktop.
AdWords MCC Script: Switch all broad match keywords to modified broad match
/*
* Title: Modified Broad Match MCC
* Descritpion: Switch all broad match keywords to modified broad match
* Author: Wolf+Bär Agency, Aleksandar Vucenovic
* License: GNU GPLv3
* Version: 0.4
* URL: https://gist.github.com/alewolf/91bc532014453ec2eac801bf342ee1f9
* URL:
*/
/********* START Description ************************************************
*
* This script goes through all broad match keywords and changes them into
* modified broad match keywords. For performance reasons the script
* will label all processed keywords in order to omit them in later runs.
*
* Mark each account that you want to be processed with the
* ACCOUNTS_TO_PROCESS label from the settings below.
********** END Description **************************************************/
/********* START Settings **************************************************/
var ACCOUNTS_TO_PROCESS = 'do_modified_broad_match_fix';
// Add this label to every account you want to be processed
var PLUS_BROAD_MATCH_LABEL = 'plus_broad_match_done';
// This label is added to each keyword that has been processed
// in order to omit it in later runs.
var PLUS_BROAD_MATCH_CAMPAIGN_OMIT_LABEL = 'omit_campaign_plus_broad_match_fix';
// Tag the campaigns, that you want to omit, with this label.
/********* END Settings **************************************************/
function main() {
getAccountsByLabel();
}
function getAccountsByLabel() {
var accountSelector = MccApp.accounts()
.withCondition("LabelNames CONTAINS '" + ACCOUNTS_TO_PROCESS + "'");
accountSelector.executeInParallel('processAccount', 'allFinished');
}
function processAccount(){
// select the account to process
var account = AdWordsApp.currentAccount();
Logger.log('account name = ' + account.getName());
// Check if the label for this script already exists in the account.
// If not create it.
if( checkLabel(PLUS_BROAD_MATCH_LABEL) == false ){
Logger.log('creating PLUS_BROAD_MATCH_LABEL');
createLabel(PLUS_BROAD_MATCH_LABEL);
}
// Run the Plus Broad Match function
transformPlusBroadMatch();
}
function allFinished(){
Logger.log('finished processing all accounts');
}
// Transform all common broad match keywords into plus broad match
function transformPlusBroadMatch(){
// A list of all campaigns to omit
var campaignsToOmit = [];
// Get all campaigns that will be omitted
if( checkLabel(PLUS_BROAD_MATCH_CAMPAIGN_OMIT_LABEL) == true ){
var campaignIterator = AdWordsApp
.campaigns()
.withCondition("LabelNames CONTAINS_ANY [ '" + PLUS_BROAD_MATCH_CAMPAIGN_OMIT_LABEL + "' ]")
.get();
// Push all campaign IDs, that will be omitted, into an array
while( campaignIterator.hasNext() ){
var campaignIdToOmit = campaignIterator.next().getId();
campaignsToOmit.push(campaignIdToOmit);
}
}
// Select all broad match keywords that have not been processed in an earlier run
if(campaignsToOmit.length == 0){
var keywordIterator = AdWordsApp
.keywords()
.withCondition("CampaignStatus = ENABLED")
.withCondition("AdvertisingChannelType = SEARCH")
.withCondition("AdGroupStatus = ENABLED")
.withCondition("Status = ENABLED")
.withCondition("KeywordMatchType = BROAD")
.withCondition("LabelNames CONTAINS_NONE [ " + PLUS_BROAD_MATCH_LABEL + " ]")
.forDateRange("ALL_TIME")
.get();
} else {
var keywordIterator = AdWordsApp
.keywords()
.withCondition("CampaignStatus = ENABLED")
.withCondition("CampaignId NOT_IN [" + campaignsToOmit.join(",") + "]")
.withCondition("AdvertisingChannelType = SEARCH")
.withCondition("AdGroupStatus = ENABLED")
.withCondition("Status = ENABLED")
.withCondition("KeywordMatchType = BROAD")
.withCondition("LabelNames CONTAINS_NONE [ " + PLUS_BROAD_MATCH_LABEL + " ]")
.forDateRange("ALL_TIME")
.get();
}
// Create a list for of applyLabel operations to be executed after the new keywords have been build
// (for performance reasons)
var operations = [];
// Create a list of all keywords that are being created
var newKeywordArray = [];
// Iterate through the keyword list
while (keywordIterator.hasNext()) {
// Get the next keyword
var keyword = keywordIterator.next();
//Get the keyword text
var originalKeywordText = keyword.getText();
// Apply the Plus Broad Match fix to the keyword
var newKeywordText = applyMBMfix(originalKeywordText);
// Logger.log("Original Keyword = " + originalKeywordText);
// Check if the old and the new keyword are the same
// If they are equal, continue with next keyword, if not, fix
if( (originalKeywordText != newKeywordText) ){
// Logger.log("New Keyword = " + newKeywordText);
// Pause the old keyword
keyword.pause();
// Logger.log('building new keyword');
// Logger.log('old keyword text = ' + originalKeywordText);
// Logger.log('new keyword text = ' + newKeywordText);
// Logger.log('ad group name = ' + keyword.getAdGroup().getName());
// Logger.log('campaign name = ' + keyword.getCampaign().getName());
// Logger.log(' ');
// We want to check if the new keyword maybe already exists in the ad group
// and has been processed in an earlier run.
var newKeywordSelector = AdWordsApp
.keywords()
.withCondition('CampaignName="' + keyword.getCampaign().getName() + '"')
.withCondition('AdGroupName="' + keyword.getAdGroup().getName() + '"')
.withCondition('Text="' + newKeywordText + '"');
// Get the iterator for this new selection
var newKeywordIterator = newKeywordSelector.get();
// Only continue building the new keyword if we don't find the new keyword in the iterator (keyword exists in that ad group)
// and only continue if the keyword has not been created earlier in the while loop.
// (That can happen if we process '++example' and '+++example'.
if (! newKeywordIterator.hasNext() && (newKeywordArray.indexOf(newKeywordText) == -1)){
// we now know that this keyword doesn't exists and act accordingly
// Logger.log('creating keyword: ' + newKeywordText);
// create new keyword in same ad group with newKeywordText
var keywordOperation = keyword.getAdGroup()
.newKeywordBuilder()
.withText(newKeywordText)
.build();
operations.push( keywordOperation );
// Push the new keyword into an array,
// so that we can check later in the loop if we already created this keyword.
newKeywordArray.push(newKeywordText);
} else {
// Logger.log('omitting keyword as it already exists');
}
} else {
// If the keyword does not need to be fixed apply a label in order to omit it in the next run
keyword.applyLabel(PLUS_BROAD_MATCH_LABEL);
} // end if
} // end while
//Logger.log( 'operations length = ' + operations.length);
// Check in the keyword operations list if the keywords have been created and apply the label
for (var i = 0; i < operations.length; i++) {
var newKeyword = operations[i].getResult();
newKeyword.applyLabel(PLUS_BROAD_MATCH_LABEL);
}
}
// Take the input keyword and transform it into a modified broad match keyword
function applyMBMfix(TextToFix){
//Logger.log("TextToFix = " + TextToFix);
// Create variable for the new keyword
var fixedText;
// replace all pluses with spaces
fixedText = TextToFix.replace(/\+/g, " ");
// replace all multiple spaces with a single space
fixedText = fixedText.replace(/\s\s+/g, ' ');;
// remove all spaces in front of the keyword
fixedText = fixedText.replace(/^ /g, "");
// add a plus at the beginning of the keyword
fixedText = "+" + fixedText;
// change all spaces into space_pluses
fixedText = fixedText.replace(/ /g, " +");
// Logger.log("fixedText = " + fixedText);
// Return the new keyword
return fixedText;
}
// Check if the label exists in the account.
// If not, create it
function checkLabel(label_to_check) {
// Logger.log("check if label exists");
// Get a list of all labels with the set label name
var labelIterator = AdWordsApp.labels()
.withCondition('Name = ' + label_to_check)
.get();
// Logger.log( "labelIterator.int = " + labelIterator.totalNumEntities());
// Check if the label name is in the list
if ( labelIterator.totalNumEntities() == 0 ) {
return false;
} else {
return true;
}
}
// Create the label
function createLabel(label_to_create){
// Logger.log("creating label: " + label_to_create);
AdWordsApp.createLabel(label_to_create);
// Logger.log("label created");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment