Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
/*******************************
* Automatically adds any new keywords in your
* Alpha campaigns as exact match negatives in
* the corresponding Beta campaign. Also handles
* pausing or removing keywords in your Alpha campaign
* and removing the corresponding negative in your Beta.
*******************************/
// Just as before, these strings will be
// used to identify your Alpha and Beta campaigns.
// This script assumes that your Alpha campaigns are
// named "Campaign Name | Alpha" with the corresponding
// Beta campaign named "Campaign Name | Beta"
var ALPHA_SUFFIX = '| Alpha';
var BETA_SUFFIX = '| Beta';
function main() {
var results = getKeywordReport();
var negativesToAddMap = {};
var negativesToRemoveMap = {};
for(var key in results) {
var campData = results[key];
for(var i in campData.alpha.keywords) {
var kw = campData.alpha.keywords[i];
if(campData.beta.negatives.indexOf(kw) == -1) {
if(!negativesToAddMap[campData.beta.campName]) {
negativesToAddMap[campData.beta.campName] = [];
}
negativesToAddMap[campData.beta.campName].push(kw);
}
}
for(var i in campData.beta.negatives) {
var kw = campData.beta.negatives[i];
if(campData.alpha.keywords.indexOf(kw) == -1) {
if(!negativesToRemoveMap[campData.beta.campName]) {
negativesToRemoveMap[campData.beta.campName] = [];
}
negativesToRemoveMap[campData.beta.campName].push('['+kw+']');
}
}
}
var campIter = AdWordsApp.campaigns().withCondition("Name CONTAINS '"+BETA_SUFFIX+"'").get();
while(campIter.hasNext()) {
var betaCamp = campIter.next();
var betaCampName = betaCamp.getName();
if(negativesToAddMap[betaCampName]) {
var negativesToAdd = negativesToAddMap[betaCampName];
for(var i in negativesToAdd) {
betaCamp.createNegativeKeyword('['+negativesToAdd[i]+']');
}
}
if(negativesToRemoveMap[betaCampName]) {
var negativesToRemove = negativesToRemoveMap[betaCampName];
var negKeywordIter = betaCamp.negativeKeywords().get();
while(negKeywordIter.hasNext()) {
var negKeyword = negKeywordIter.next();
if(negativesToRemove.indexOf(negKeyword.getText()) >= 0) {
negKeyword.remove();
}
}
}
}
}
// This function uses the Keywords report and
// the campaign negatives report to build a list
// of the keywords and negatives in each campaign.
function getKeywordReport() {
var columns = ['CampaignName','Criteria','IsNegative'];
var alphaReportQueryTemplate = "SELECT %s FROM %s "+
"WHERE IsNegative IN [true,false] "+
"AND CampaignName CONTAINS '%s' "+
"AND CampaignStatus = ENABLED " +
"AND AdGroupStatus = ENABLED " +
"AND Status = ENABLED ";
var betaReportQueryTemplate = "SELECT %s FROM %s "+
"WHERE IsNegative IN [true,false] "+
"AND CampaignName CONTAINS '%s' ";
var alphaReportQuery = Utilities.formatString(alphaReportQueryTemplate,
columns.join(','),
'KEYWORDS_PERFORMANCE_REPORT',
ALPHA_SUFFIX);
var betaReportQuery = Utilities.formatString(betaReportQueryTemplate,
columns.join(','),
'CAMPAIGN_NEGATIVE_KEYWORDS_PERFORMANCE_REPORT',
BETA_SUFFIX);
var queries = [alphaReportQuery,betaReportQuery];
var results = {};
for(var i in queries) {
var reportIter = AdWordsApp.report(queries[i],{
includeZeroImpressions: true
}).rows();
while(reportIter.hasNext()) {
var row = reportIter.next();
if(row.CampaignName.indexOf(ALPHA_SUFFIX) == -1 &&
row.CampaignName.indexOf(BETA_SUFFIX) == -1) {
continue;
}
var campType = (row.CampaignName.indexOf(ALPHA_SUFFIX) >= 0) ? 'alpha' : 'beta';
var cleanCampName = row.CampaignName.split(ALPHA_SUFFIX)[0];
cleanCampName = cleanCampName.split(BETA_SUFFIX)[0];
if(!results[cleanCampName]) {
results[cleanCampName] = {
alpha: { keywords: [], negatives: [], campName: '' },
beta: { keywords: [], negatives: [], campName: '' }
};
}
results[cleanCampName][campType].campName = row.CampaignName;
if(row.IsNegative == 'true') {
results[cleanCampName][campType].negatives.push(row.Criteria);
} else {
results[cleanCampName][campType].keywords.push(row.Criteria);
}
}
}
return results;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment