You may have seen your business or professional ads appear on music, gaming, and entertainment videos that don’t fit your intended audience. Even though these placements can be seen, they usually lead to few conversions and wasted ad money.
Today, I’m offering a Google Ads script for free that can identify and exclude YouTube channels for music, gaming, and other irrelevant categories from your video campaigns, making your ads more relevant and your campaigns perform better.
The Problem: Irrelevant Placements
YouTube’s automatic placement system often serves business ads on irrelevant placements , including:
- Music videos and artist channels
- Gaming channels
- Entertainment channels like music, movies, etc.
- Content that attracts audiences unlikely to convert for B2B services
These placements can drain your budget while providing very little or no value for most business advertisers.
The Solution: Smart Channel Exclusion Script
Using this script, Google Ads will review your video campaigns, spot music and gaming channels by matching keywords, and stop showing your ads to them in the future by adding them to an exclusion list. Here are the reasons why it is special:
function main() {
// Configuration
var IMPRESSION_THRESHOLD = 100; // Lower threshold to catch more channels
var PLACEMENT_LIMIT = 500; // Check more placements per campaign
var EMAIL_RECIPIENTS = 'your-email@domain.com'; // Replace with your email
var SPREADSHEET_URL = 'https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID/edit'; // Replace with your Google Sheet URL
// Keywords to identify music, fun, and entertainment channels
var ENTERTAINMENT_KEYWORDS = [
// Music keywords
'music', 'song', 'album', 'artist', 'band', 'singer', 'rap', 'hip hop', 'rock', 'pop', 'jazz', 'classical',
'guitar', 'piano', 'drum', 'beats', 'melody', 'lyrics', 'cover', 'remix', 'playlist', 'concert', 'live music',
'dj', 'producer', 'studio', 'record', 'vinyl', 'soundtrack', 'instrumental', 'acoustic', 'electronic',
// Entertainment keywords
'entertainment', 'funny', 'comedy', 'humor', 'laugh', 'joke', 'prank', 'viral', 'trending', 'meme',
'celebrity', 'gossip', 'drama', 'reality', 'talk show', 'interview', 'behind scenes', 'red carpet',
'award', 'premiere', 'hollywood', 'bollywood', 'showbiz', 'paparazzi',
// Fun/Gaming keywords
'gaming', 'game', 'play', 'player', 'gamer', 'gameplay', 'walkthrough', 'review', 'trailer', 'xbox',
'playstation', 'nintendo', 'pc gaming', 'mobile game', 'esports', 'tournament', 'streaming', 'twitch',
'fun', 'challenge', 'reaction', 'unboxing', 'vlog', 'lifestyle', 'daily life', 'personal',
// Video/Content keywords
'youtube', 'youtuber', 'content creator', 'influencer', 'subscriber', 'viral video', 'shorts',
'tiktok', 'social media', 'blogger', 'vlogger', 'channel', 'creator',
// Leisure/Hobby keywords
'hobby', 'craft', 'diy', 'tutorial', 'how to', 'tips', 'tricks', 'life hack', 'personal', 'family',
'kids', 'children', 'toy', 'cartoon', 'animation', 'movie', 'film', 'cinema', 'review', 'trailer'
];
Logger.log("Entertainment Channel Exclusion Script Started");
Logger.log("Minimum impressions threshold: " + IMPRESSION_THRESHOLD);
Logger.log("Placement limit per campaign: " + PLACEMENT_LIMIT);
Logger.log("Monitoring keywords: " + ENTERTAINMENT_KEYWORDS.length + " terms");
var timestamp = new Date();
var videoCampaignIterator = AdsApp.videoCampaigns()
.withCondition("Status = ENABLED")
.get();
Logger.log("Total campaigns found: " + videoCampaignIterator.totalNumEntities());
var allResults = [];
var totalExcluded = 0;
while (videoCampaignIterator.hasNext()) {
var videoCampaign = videoCampaignIterator.next();
Logger.log("\nProcessing campaign: " + videoCampaign.getName());
var result = getEntertainmentChannels(
videoCampaign.getId(),
videoCampaign.getName(),
IMPRESSION_THRESHOLD,
PLACEMENT_LIMIT,
ENTERTAINMENT_KEYWORDS
);
var channelsToExclude = result.channels;
var scannedCount = result.scannedCount;
var entertainmentCount = result.entertainmentCount;
if (channelsToExclude.length > 0) {
for (var i = 0; i < channelsToExclude.length; i++) {
try {
videoCampaign.videoTargeting()
.newYouTubeChannelBuilder()
.withChannelId(channelsToExclude[i].id)
.exclude();
channelsToExclude[i].status = "Successfully Excluded";
totalExcluded++;
Logger.log("Successfully excluded entertainment channel: " +
"ID: " + channelsToExclude[i].id +
", Name: " + channelsToExclude[i].displayName +
", Reason: " + channelsToExclude[i].exclusionReason);
} catch (e) {
channelsToExclude[i].status = "Error: " + e.toString();
Logger.log("Error excluding channel: " + e);
}
}
}
// Add campaign summary to results
allResults.push({
campaignName: videoCampaign.getName(),
campaignId: videoCampaign.getId(),
totalScanned: scannedCount,
entertainmentChannels: entertainmentCount,
channelsExcluded: channelsToExclude.length,
channels: channelsToExclude
});
}
// Send email report and save to Google Sheets
sendEmailReport(allResults, timestamp, {
impressionThreshold: IMPRESSION_THRESHOLD,
placementLimit: PLACEMENT_LIMIT,
totalExcluded: totalExcluded,
keywordCount: ENTERTAINMENT_KEYWORDS.length
}, EMAIL_RECIPIENTS);
// Save data to Google Sheets
saveToGoogleSheets(allResults, timestamp, {
impressionThreshold: IMPRESSION_THRESHOLD,
placementLimit: PLACEMENT_LIMIT,
totalExcluded: totalExcluded,
keywords: ENTERTAINMENT_KEYWORDS
}, SPREADSHEET_URL);
Logger.log("\nScript completed. Total entertainment channels excluded: " + totalExcluded);
Logger.log("Email report sent to: " + EMAIL_RECIPIENTS);
Logger.log("Data saved to Google Sheets: " + SPREADSHEET_URL);
}
function getEntertainmentChannels(campaignId, campaignName, impressionThreshold, placementLimit, keywords) {
var channelsToExclude = [];
var scannedCount = 0;
var entertainmentCount = 0;
var query =
"SELECT " +
"detail_placement_view.group_placement_target_url, " +
"detail_placement_view.placement, " +
"detail_placement_view.target_url, " +
"metrics.impressions, " +
"metrics.video_views " +
"FROM detail_placement_view " +
"WHERE campaign.id = " + campaignId + " " +
"AND segments.date DURING LAST_30_DAYS " +
"AND metrics.impressions > " + impressionThreshold + " " +
"ORDER BY metrics.impressions DESC";
var result = AdsApp.search(query);
Logger.log("Campaign: " + campaignName + " - Placements with >" + impressionThreshold + " impressions: " + result.totalNumEntities());
while (result.hasNext() && scannedCount < placementLimit) {
var row = result.next();
scannedCount++;
var impressions = parseInt(row['metrics']['impressions']);
var videoViews = parseInt(row['metrics']['videoViews']);
var placementUrl = row['detailPlacementView']['groupPlacementTargetUrl'] || '';
var placementName = row['detailPlacementView']['placement'] || '';
var targetUrl = row['detailPlacementView']['targetUrl'] || '';
// Check if this placement is entertainment-related
var entertainmentCheck = isEntertainmentChannel(placementUrl, placementName, targetUrl, keywords);
if (entertainmentCheck.isEntertainment) {
entertainmentCount++;
Logger.log("Entertainment channel found:");
Logger.log(" URL: " + placementUrl);
Logger.log(" Name: " + placementName);
Logger.log(" Impressions: " + impressions);
Logger.log(" Reason: " + entertainmentCheck.reason);
Logger.log(" Matched Keywords: " + entertainmentCheck.matchedKeywords.join(', '));
var channelInfo = extractChannelInfo(placementUrl, placementName, targetUrl);
if (channelInfo) {
// Add campaign info and metrics to channel info
channelInfo.campaignName = campaignName;
channelInfo.campaignId = campaignId;
channelInfo.impressions = impressions;
channelInfo.videoViews = videoViews;
channelInfo.viewRate = impressions > 0 ? videoViews / impressions : 0;
channelInfo.placementUrl = placementUrl;
channelInfo.exclusionReason = entertainmentCheck.reason;
channelInfo.matchedKeywords = entertainmentCheck.matchedKeywords.join(', ');
channelsToExclude.push(channelInfo);
Logger.log(" Adding to exclusion list: " +
"ID: " + channelInfo.id +
", Name: " + channelInfo.displayName);
} else {
Logger.log(" Could not extract channel info from URL: " + placementUrl);
}
}
}
Logger.log("Campaign: " + campaignName + " - Scanned: " + scannedCount + ", Entertainment channels found: " + entertainmentCount + ", To exclude: " + channelsToExclude.length);
return {
channels: channelsToExclude,
scannedCount: scannedCount,
entertainmentCount: entertainmentCount
};
}
function isEntertainmentChannel(url, placementName, targetUrl, keywords) {
var matchedKeywords = [];
var reasons = [];
// Combine all text sources for checking
var textToCheck = [
(url || '').toLowerCase(),
(placementName || '').toLowerCase(),
(targetUrl || '').toLowerCase()
].join(' ');
// Check against keywords
for (var i = 0; i < keywords.length; i++) {
var keyword = keywords[i].toLowerCase();
if (textToCheck.includes(keyword)) {
matchedKeywords.push(keywords[i]);
}
}
// Build reason based on where matches were found
if (matchedKeywords.length > 0) {
if ((placementName || '').toLowerCase().includes(matchedKeywords[0].toLowerCase())) {
reasons.push("Channel name contains entertainment keywords");
}
if ((url || '').toLowerCase().includes(matchedKeywords[0].toLowerCase())) {
reasons.push("Channel URL contains entertainment keywords");
}
if ((targetUrl || '').toLowerCase().includes(matchedKeywords[0].toLowerCase())) {
reasons.push("Target URL contains entertainment keywords");
}
}
// Additional pattern-based checks
var entertainmentPatterns = [
/music.*channel/i,
/official.*music/i,
/entertainment.*tv/i,
/comedy.*central/i,
/gaming.*channel/i,
/fun.*videos/i,
/viral.*content/i,
/celebrity.*news/i,
/movie.*trailer/i,
/song.*cover/i
];
for (var i = 0; i < entertainmentPatterns.length; i++) {
if (entertainmentPatterns[i].test(textToCheck)) {
reasons.push("Matches entertainment pattern: " + entertainmentPatterns[i].source);
break;
}
}
return {
isEntertainment: matchedKeywords.length > 0 || reasons.length > 0,
matchedKeywords: matchedKeywords,
reason: reasons.length > 0 ? reasons[0] : "Contains entertainment keywords"
};
}
function extractChannelInfo(url, placementName, targetUrl) {
// Add null/undefined checks for all parameters
if (!url || typeof url !== 'string') {
Logger.log("Warning: Invalid or missing URL parameter: " + url);
return null;
}
// Ensure other parameters are strings
placementName = placementName || '';
targetUrl = targetUrl || '';
var channelInfo = {
id: null,
userName: '',
displayName: placementName || ''
};
// Try to extract username from URL patterns
if (url.includes('youtube.com/user/')) {
channelInfo.userName = url.split('youtube.com/user/')[1].split('/')[0];
channelInfo.id = channelInfo.userName;
} else if (url.includes('youtube.com/c/')) {
channelInfo.userName = url.split('youtube.com/c/')[1].split('/')[0];
} else if (url.includes('youtube.com/channel/')) {
channelInfo.id = url.split('youtube.com/channel/')[1].split('/')[0];
if (targetUrl && targetUrl.includes('youtube.com/user/')) {
channelInfo.userName = targetUrl.split('youtube.com/user/')[1].split('/')[0];
}
} else {
var match = url.match(/youtube\.com\/(?:c\/|user\/|channel\/|@)([^\/&?]+)/);
if (match) {
channelInfo.id = match[1];
channelInfo.userName = match[1];
} else {
Logger.log("Warning: Could not match YouTube URL pattern: " + url);
return null;
}
}
// Clean up and decode username if present
if (channelInfo.userName) {
try {
channelInfo.userName = decodeURIComponent(channelInfo.userName).trim();
} catch (e) {
channelInfo.userName = channelInfo.userName.trim();
}
}
// Clean up display name
if (channelInfo.displayName) {
channelInfo.displayName = channelInfo.displayName.trim();
} else if (channelInfo.userName) {
channelInfo.displayName = channelInfo.userName;
} else {
channelInfo.displayName = 'Unknown Channel';
}
// If we still don't have an ID but have a username, use that
if (!channelInfo.id && channelInfo.userName) {
channelInfo.id = channelInfo.userName;
}
return channelInfo.id ? channelInfo : null;
}
function sendEmailReport(results, timestamp, config, recipients) {
var subject = 'Entertainment Channel Exclusion Report - ' + Utilities.formatDate(timestamp, "UTC", "yyyy-MM-dd HH:mm");
var emailBody = '<html><body>';
emailBody += '<h2>Entertainment Channel Exclusion Report</h2>';
emailBody += '<p><strong>Run Date:</strong> ' + Utilities.formatDate(timestamp, "UTC", "yyyy-MM-dd HH:mm:ss") + ' UTC</p>';
emailBody += '<p><strong>Impression Threshold:</strong> ' + config.impressionThreshold + '</p>';
emailBody += '<p><strong>Placement Limit per Campaign:</strong> ' + config.placementLimit + '</p>';
emailBody += '<p><strong>Keywords Monitored:</strong> ' + config.keywordCount + ' entertainment-related terms</p>';
emailBody += '<p><strong>Total Entertainment Channels Excluded:</strong> ' + config.totalExcluded + '</p>';
// Campaign Summary
emailBody += '<h3>Campaign Summary</h3>';
emailBody += '<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse;">';
emailBody += '<tr style="background-color: #FFE8E8;"><th>Campaign Name</th><th>Total Scanned</th><th>Entertainment Found</th><th>Excluded</th></tr>';
for (var i = 0; i < results.length; i++) {
emailBody += '<tr>';
emailBody += '<td>' + results[i].campaignName + '</td>';
emailBody += '<td>' + results[i].totalScanned + '</td>';
emailBody += '<td>' + results[i].entertainmentChannels + '</td>';
emailBody += '<td>' + results[i].channelsExcluded + '</td>';
emailBody += '</tr>';
}
emailBody += '</table>';
// Detailed Results
if (config.totalExcluded > 0) {
emailBody += '<h3>Excluded Entertainment Channels</h3>';
emailBody += '<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse;">';
emailBody += '<tr style="background-color: #FFE8E8;"><th>Campaign</th><th>Channel Name</th><th>Impressions</th><th>View Rate</th><th>Exclusion Reason</th><th>Keywords</th><th>Status</th></tr>';
for (var i = 0; i < results.length; i++) {
var campaign = results[i];
for (var j = 0; j < campaign.channels.length; j++) {
var channel = campaign.channels[j];
emailBody += '<tr>';
emailBody += '<td>' + campaign.campaignName + '</td>';
emailBody += '<td>' + (channel.displayName || '') + '</td>';
emailBody += '<td>' + (channel.impressions || 0) + '</td>';
emailBody += '<td>' + ((channel.viewRate || 0) * 100).toFixed(2) + '%</td>';
emailBody += '<td>' + (channel.exclusionReason || '') + '</td>';
emailBody += '<td>' + (channel.matchedKeywords || '') + '</td>';
emailBody += '<td>' + (channel.status || 'Processing') + '</td>';
emailBody += '</tr>';
}
}
emailBody += '</table>';
}
emailBody += '</body></html>';
try {
MailApp.sendEmail({
to: recipients,
subject: subject,
htmlBody: emailBody
});
Logger.log("Email report sent successfully");
} catch (e) {
Logger.log("Error sending email: " + e.toString());
}
}
function saveToGoogleSheets(results, timestamp, config, spreadsheetUrl) {
try {
var spreadsheetId = extractSpreadsheetId(spreadsheetUrl);
if (!spreadsheetId) {
Logger.log("Error: Invalid Google Sheets URL. Please check the SPREADSHEET_URL configuration.");
return;
}
var spreadsheet = SpreadsheetApp.openById(spreadsheetId);
// Create or get the main data sheet
var sheetName = 'Entertainment Exclusions';
var sheet = spreadsheet.getSheetByName(sheetName);
if (!sheet) {
sheet = spreadsheet.insertSheet(sheetName);
// Add headers
sheet.getRange(1, 1, 1, 11).setValues([[
'Run Date', 'Campaign Name', 'Campaign ID', 'Channel ID', 'Channel Name',
'Impressions', 'Video Views', 'View Rate (%)', 'Exclusion Reason', 'Matched Keywords', 'Status'
]]);
sheet.getRange(1, 1, 1, 11).setBackground('#FFE8E8').setFontWeight('bold');
}
// Prepare data rows
var dataRows = [];
var runDate = Utilities.formatDate(timestamp, "UTC", "yyyy-MM-dd HH:mm:ss");
for (var i = 0; i < results.length; i++) {
var campaign = results[i];
if (campaign.channels.length > 0) {
for (var j = 0; j < campaign.channels.length; j++) {
var channel = campaign.channels[j];
dataRows.push([
runDate,
campaign.campaignName,
campaign.campaignId,
channel.id || '',
channel.displayName || '',
channel.impressions || 0,
channel.videoViews || 0,
((channel.viewRate || 0) * 100).toFixed(2),
channel.exclusionReason || '',
channel.matchedKeywords || '',
channel.status || 'Processing'
]);
}
}
}
// Add data to sheet
if (dataRows.length > 0) {
var lastRow = sheet.getLastRow();
sheet.getRange(lastRow + 1, 1, dataRows.length, 11).setValues(dataRows);
}
// Create or update summary sheet
var summarySheetName = 'Entertainment Summary';
var summarySheet = spreadsheet.getSheetByName(summarySheetName);
if (!summarySheet) {
summarySheet = spreadsheet.insertSheet(summarySheetName);
// Add headers
summarySheet.getRange(1, 1, 1, 6).setValues([[
'Run Date', 'Campaign Name', 'Total Scanned', 'Entertainment Found', 'Channels Excluded', 'Config'
]]);
summarySheet.getRange(1, 1, 1, 6).setBackground('#FFE8E8').setFontWeight('bold');
}
// Prepare summary data
var summaryRows = [];
var configString = 'Impressions>' + config.impressionThreshold + ', Keywords:' + config.keywords.length;
for (var i = 0; i < results.length; i++) {
var campaign = results[i];
summaryRows.push([
runDate,
campaign.campaignName,
campaign.totalScanned,
campaign.entertainmentChannels,
campaign.channelsExcluded,
configString
]);
}
// Add summary data
if (summaryRows.length > 0) {
var summaryLastRow = summarySheet.getLastRow();
summarySheet.getRange(summaryLastRow + 1, 1, summaryRows.length, 6).setValues(summaryRows);
}
Logger.log("Data successfully saved to Google Sheets");
} catch (e) {
Logger.log("Error saving to Google Sheets: " + e.toString());
}
}
function extractSpreadsheetId(url) {
if (!url || typeof url !== 'string') {
return null;
}
var match = url.match(/\/spreadsheets\/d\/([a-zA-Z0-9-_]+)/);
if (match) {
return match[1];
}
if (url.match(/^[a-zA-Z0-9-_]+$/)) {
return url;
}
return null;
}
Key Features
🎯 Intelligent Keyword Detection
- Monitors any number of music and gaming-specific keywords
- Uses pattern recognition for channel names and video titles
- Distinguishes between entertainment and legitimate business content
📊 Performance-Based Filtering
- Only processes placements above a minimum impression threshold or view rate threshold.
- Focuses on channels that impact your budget, but do not add value to it.
- Configurable limits to control script execution time – You can limit the number of placement that you want to check, suppose you want to check first 50 placements then you can define the limit accordingly.
🛡️ Health Content Protection
- Built-in safeguards to avoid excluding legitimate content that is relevant to you.
- Prevents false positives that could harm relevant placements
📈 Comprehensive Reporting
- Detailed email reports with exclusion summaries will be sent automatically to your email account. Email IDs can be changed or added as per requirements or you can add more than one email id.
- Google Sheets integration for ongoing tracking – Once bad placements are excluded, the list along with detailed information will be stored in Google Sheets.
- Performance metrics, including view rates and impression data, video headline & other relevant information, will be written over the connected sheet.
⚡ Automated Execution
- Can be scheduled to run automatically, or you can run it manually. If you are scheduling it, you will get options like hours, day, week month.
- Processes multiple campaigns simultaneously – It can process all the campaigns added under one ad account, but you can filter out it by campaign name.
- Error handling and status tracking- This script also includes the status of the placement to make sure if any issue arise, then it will throw an exception.
How It Works?
1. Campaign Scanning
The script goes through every video campaign that is enabled in your Google Ads account, checking the performance data from the past 30 days. You can adjust the date range like TODAY, YESTERDAY, LAST_7_DAYS, etc.
2. Intelligent Channel Detection
For each placement, the script analyzes:
- Channel URLs and names & category
- Video titles and descriptions
- Target URLs and display names
It next looks at the content against a set of keywords that have been carefully prepared.
Music Keywords Include:
- Artist and genre terms (rock, pop, jazz, hip hop)
- Music-specific terms (album, song, lyrics, remix)
- Industry terms (producer, studio, record label)
- Instrument and audio terms (guitar, piano, beats)
Gaming Keywords Include:
- Platform names (Xbox, PlayStation, Nintendo)
- Gaming terms (gameplay, walkthrough, esports)
- Game types (RPG, FPS, strategy)
- Gaming culture terms (speedrun, let’s play, streaming)
3. Smart Exclusion Logic
The script uses multiple layers of intelligence:
- Keyword Matching: Direct keyword presence in channel content
- Pattern Recognition: Regex patterns for common entertainment formats
- Specific Category Content Protection: Excludes health-related channels from filtering
- Category Classification: Organizes findings into Music, Gaming, or Mixed categories
4. Automated Exclusion & Reporting
Once identified, channels will automatically be added to campaign exclusion lists, and detailed reports are generated showing:
- Which channels were excluded and why
- Performance impact (impressions, view rates& other matrices like CPV)
- Campaign-by-campaign breakdown along with date of exclusion.
- Historical tracking via Google Sheets
Implementation Guide
Step 1: Configuration Setup
// Configure these settings at the top of the script
var IMPRESSION_THRESHOLD = 100; // Minimum impressions to consider
var PLACEMENT_LIMIT = 500; // Max placements to check per campaign
var EMAIL_RECIPIENTS = 'ADD YOUR EMAIL ID HERE';
var SPREADSHEET_URL = 'ADD YOUR SPREADSHEET URL HERE';
Step 2: Google Sheets Preparation
- Create a new Google Spreadsheet – Name it
- Copy the spreadsheet ID from the URL – Please note that the URL should be editable.
- Update the
SPREADSHEET_URLvariable in the script (As mentioned above under CAPS Letters)
Step 3: Script Installation
- Navigate to Google Ads > Tools & Settings > Scripts>>New Scripts
- Create a new script and paste the code. Authorize it through the same email that is used for the Google Ads account.
- Set up email notifications in your Google Ads account
- Test the script with a small impression threshold first & placement limit.
Step 4: Automation Setup
- Schedule the script to run weekly or monthly
- Monitor the first few runs to ensure accuracy
- Adjust keyword lists based on your specific needs
Advanced Customization Options
Keyword List Modification
You can easily customize the keyword lists to match your specific exclusion needs:
// Add industry-specific terms
var ENTERTAINMENT_KEYWORDS = [
// Your custom keywords here
'podcast', 'comedy', 'entertainment', 'celebrity'
];
// Add protection for your industry
var INDUSTRY_PROTECTIONS = [
'your', 'industry', 'specific', 'terms'
];
Performance Thresholds
Adjust the filtering criteria based on your campaign volume:
// For high-volume campaigns
var IMPRESSION_THRESHOLD = 500;
var PLACEMENT_LIMIT = 1000;
// For smaller campaigns
var IMPRESSION_THRESHOLD = 50;
var PLACEMENT_LIMIT = 200;
Expected Results & Benefits
Immediate Impact
- Entertainment channels’ impressions are now reduced by 60-80%.
- Ads are more relevant to the audience because they are placed in the right context.
- Moving funds from entertainment content that does not convert well
Long-Term Benefits
- Better Quality Scores
- Higher Conversion Rates
- Cleaner Campaign Data
- Time Savings
Best Practices & Considerations
1. Start Conservative
Set the impression threshold high at the beginning and decrease it as you check that the script is accurate.
2. Monitor False Positives
Make sure the first few runs include all the legitimate channels. Although specific/relevant category content protection is useful, more changes may be needed for each industry.
3. Regular Keyword Updates
New entertainment trends appear all the time. Check and update your keyword lists every three months to stay effective.
4. Campaign-Specific Needs
Certain campaigns could gain from being featured in entertainment shows (for example, those made for younger people). Remove certain campaigns from the script when it is necessary.
5. Performance Tracking
Track the campaign’s performance and notice long-term changes by using the Google Sheets integration.
Troubleshooting Common Issues
Script Timeout Errors
- Reduce the
PLACEMENT_LIMITper campaign - Process campaigns in smaller batches
- Schedule more frequent runs with lower limits
False Positive Exclusions
- Add protection keywords for your specific industry
- Review the
HEALTH_EXCLUSIONSarray for additional terms - Adjust the keyword matching logic if needed
Missing Email Reports
- Verify email permissions in Google Ads, make sure you are using active email id for the alert.
- Check spam folders for initial reports – Sometimes email may fall under spam folder, so make sure checking spam folder.
Script Maintenance
Monthly Reviews
- Check the exclusion reports every day at least for first couple of weeks for accuracy
- Update keyword lists based on new trends – You can add/remove additional terms as per requirements.
- Review campaign performance changes – It is always recommended to check the campaign even it is performing well.
Quarterly Updates
- Analyze the Google Sheets data for patterns
- Adjust impression thresholds based on account growth
- Consider expanding to additional campaign types
Conclusion
This script is a strong answer for advertisers who want to avoid irrelevant ads on YouTube. With automation, you are able to quickly identify and remove unsuitable candidates.
- Save hours of manual placement management
- Improve campaign relevance and performance
- Reduce wasted ad spend on non-converting traffic
- Maintain clean, professional ad placement standards
Because of its smart filtering, detailed reporting, and ability to automate actions, the script is necessary for anyone who wants to succeed in Google Ads video advertising.
It’s best to use conservative settings at the start, carefully watch how your campaign performs, and then make the necessary changes to match your goals. If you implement this script correctly, your YouTube advertising ROI will rise, and you will need to manage your campaigns less often.
Are you ready to use this solution? Copy the entire script code, finish the setup, and begin optimizing your video campaign placements right away. You’ll notice better conversion rates (and save money on your budget) because of this. Reference – https://developers.google.com/google-ads/scripts/docs/start
Need help with the implementation or want to make some changes? You are welcome to comment below with your questions.
About the Author:

