Skip to content

Instantly share code, notes, and snippets.

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 Xyborg/2d7c1fe5204f022efd619f447b2c5158 to your computer and use it in GitHub Desktop.
Save Xyborg/2d7c1fe5204f022efd619f447b2c5158 to your computer and use it in GitHub Desktop.
/***********************************************************************************
* @name: Google Shopping Pure Brand Campaigns - Negative Keywords List Generator
* @version: 1.3
* @author: Martin Aberastegue (https://www.linkedin.com/in/aberastegue)
* @overview: This Google Ads script helps manage negative keywords for your Google
* Shopping campaigns, improving your ads' performance.
*
* 2. It begins by reading your configurations: a list of branded keywords, the
* name of your negative keyword list, the negative match type (either 'BROAD',
* 'EXACT', or 'PHRASE'), the time range for considering search queries
* ('LAST_7_DAYS', 'LAST_30_DAYS', or a custom date range), and the name or part
* of the name of the campaigns you wish to apply this script on.
*
* 3. The script fetches all active Shopping campaigns whose names contain the
* text you specified. For each, it generates a report of search queries that
* resulted in ad displays and cost during the specified time range.
*
* 4. For each query, the script checks whether it matches or contains any of the
* branded keywords you specified. If a query does not contain a branded
* keyword, it's considered a non-branded keyword.
*
* 5. Non-branded keywords are added to a negative keyword list with the specified
* negative match type. If the list doesn't exist, the script creates it.
*
* 6. By periodically running this script, you automate the process of identifying
* and adding non-branded keywords to your negative list. This helps focus your
* ads on queries related to your brand, reducing irrelevant clicks and
* potentially improving your Google Shopping campaigns' ROI.
*
* It's important to keep in mind you can only have up to 20 negative keywords list,
* and each one is limited to 5000 keywords.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
***********************************************************************************/
// Configuration
const CONFIG = {
BRANDKWDS: ['brand name', 'brandname', 'braname'],
LISTNAME: 'MY_SUPER_NEG_LIST',
NEGMATCHTYPE: 'EXACT',
TIMERANGE: 'LAST_7_DAYS',
CAMPNAME: 'MY_CAMPAIGN_NAME',
};
function main() {
var campaigns = AdsApp.shoppingCampaigns()
.withCondition("Status = ENABLED")
.withCondition("Name CONTAINS_IGNORE_CASE '" + CONFIG.CAMPNAME + "'")
.get();
var negativeKeywordList = getOrCreateNegativeKeywordList(CONFIG.LISTNAME);
while (campaigns.hasNext()) {
var campaign = campaigns.next();
Logger.log("Getting Search Terms report for campaign: " + campaign.getName());
var report = AdsApp.report(
"SELECT Query " +
"FROM SEARCH_QUERY_PERFORMANCE_REPORT " +
"WHERE CampaignId = " + campaign.getId() +
" AND Cost > 0 " +
" DURING " + CONFIG.TIMERANGE
);
var rows = report.rows();
while (rows.hasNext()) {
var row = rows.next();
var query = row['Query'];
if (!isBranded(query, CONFIG.BRANDKWDS)) {
addNegativeKeyword(negativeKeywordList, query, CONFIG.NEGMATCHTYPE);
}
}
}
}
function getOrCreateNegativeKeywordList(ListName) {
var negativeKeywordLists = AdsApp.negativeKeywordLists()
.withCondition("Name = '" + ListName + "'")
.get();
if (negativeKeywordLists.hasNext()) {
return negativeKeywordLists.next();
} else {
Logger.log("Creating new negative keyword list: " + CONFIG.LISTNAME);
return AdsApp.newNegativeKeywordListBuilder()
.withName(CONFIG.LISTNAME)
.build()
.getResult();
}
}
function isBranded(query) {
for (var i = 0; i < CONFIG.BRANDKWDS.length; i++) {
if (query.toLowerCase().indexOf(CONFIG.BRANDKWDS[i].toLowerCase()) > -1) {
return true;
}
}
return false;
}
function addNegativeKeyword(negativeKeywordList, keyword, NegMatchType) {
if(NegMatchType === 'EXACT') {
negativeKeywordList.addNegativeKeyword('[' + keyword + ']');
}
else if(NegMatchType === 'BROAD') {
negativeKeywordList.addNegativeKeyword(keyword);
}
else if(NegMatchType === 'PHRASE') {
negativeKeywordList.addNegativeKeyword('"' + keyword + '"');
}
else {
Logger.log("Invalid NegMatchType. Choose either EXACT, BROAD, or PHRASE.");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment