Last active
November 28, 2017 11:00
-
-
Save alewolf/91bc532014453ec2eac801bf342ee1f9 to your computer and use it in GitHub Desktop.
AdWords MCC Script: Switch all broad match keywords to modified broad match
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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