In the middle of March, a number of major advertisers left YouTube because their pre-roll ads (paid videos shown before the main content is played and can be skipped after 5 seconds) were placed in videos with offensive content. However, in this article, we would like to talk about another important topic – unintended demonstrating pre-rolls in children's content.
The problem is that even with correct targeting settings for an adult audience, a huge amount (up to 90% in some cases) of impressions is given to children's channels. This is due to the fact that parents use the "adult" accounts on their devices, both mobile and desktop, to show cartoons and educational videos to their kids.
Naturally, advertisers do not want to spend their budgets on children who simply watch pre-rolls, because this has almost no effect on sales. Such videos and channels can be excluded using negative keywords, but it is time-consuming and difficult and will not exclude all the channels and videos.
Many non-popular children's channels and videos continue to show pre-roll ads because they share a common, childish name or have an inadequate description, but they are still watched by many children. There is a way to automate the search and exclusion of such channels using AdWords scripts, which is provided below.
Problem Solution
Google AdWords allows you to create your own scripts on JS to manage your advertising account. They are based on Google Apps Scripts and their main advantage is an integration with other Google services, such as Google Drive, Spreadsheets, YouTube, Analytics, BigQuery, etc., as well as the ability to work with third-party APIs. For example, you can use YouTube Data API v3 to find the video for an ad placement.
It turned out that children videos are combined not by names, but by their tags. After modifying the script for YouTube video search, similar tags for various children videos in English, Russian, and Ukrainian were found and saved in Google Spreadsheet for further use. The file is public, but it is recommended to make a copy of this file and save it on your Google Drive before setting up the script and replace the file id in the script with a new one.
Important Details
-
We get all the links with YouTube placements and videoId from the previous date from URL_PERFORMANCE_REPORT:
var report = AdWordsApp.report(
'SELECT Url ' +
'FROMURL_PERFORMANCE_REPORT ' +
'WHERE CampaignName CONTAINS "Video" ' +
'DURING YESTERDAY');
var rows = report.rows();
while (rows.hasNext()) {
var row = rows.next();
var videoId = row['Url'].toString().replace('www.youtube.com/video/','');
videoIdList.push([videoId]);
}
-
Requests are sent to YouTube with each video id in the loop. Tags and video channel IDs got in response are checked whether they match anything from the collected library with the children's tags:
for (var i = 0; i < videoList.length; i++) {
var results = YouTube.Videos.list('snippet', {id: videoList[i]});
try {
if (results.items[0].snippet !== undefined) {
var channelId = results.items[0].snippet.channelId;
var tags = results.items[0].snippet.tags;
if (uniqueChannel[channelId] !== true){
for (var k = 0; k < tags.length; k++) {
if (tagsObj[tags[k]] !== undefined) {
channels.push([channelId]);
uniqueChannel[channelId] = true;
Logger.log("Add to the library with extensions - " + channelId);
break;
} else {
continue;
};
}
}
}
} catch (e) {
Logger.log(e);
}
}
If any of the video tags matches the tags in the library, the ID of the video channel will be sent to the array for exclusion (if it has not already been added via another video from the same channel).
Once all the videos have been checked, run the loop to add all the channels to the list of excluded sites to your AdWords account. A list with a name identical to the one in the script (here – "Video_channels") needs to be created in advance. The limit for the list of excluded sites is 65,000, so there should not be any overflow problem.
var excludedPlacementList = AdWordsApp.excludedPlacementLists().withCondition('Name = "Video_Channels"').get().next();
for (var d = 0; d < channels.length; d++) {
excludedPlacementList.addExcludedPlacement("youtube.com/channel/"+channels[d].toString());
};
Issues Occurred
The solution provided above seemed to work correctly, but some issues still occurred. When using this script, we faced the following problem. The script did not manage to process all the videos from the previous day since there was a 30-minute limitation by AdWords. So, the new exceptions were not added.
In addition, it was necessary to add videos as often as possible to save the budget by targeting the right audience. Unfortunately, even after adding a video to the list of exceptions, they, according to our experience, did not start working immediately. Google technical support estimated that it would take up to 2 days, usually less. Therefore, if you have a list of channels collected by the script, it is recommended to add them to the exception list in advance.
Solution
It seems reasonable to run the script every hour and does not check the videos that have been previously checked or else the script will reach the 30-minute limit in the middle of the day. The solution was designed using this script. It was a bit more complicated as compared with the first version of the script, but the results were excellent.
We added the functionality to save txt-files with the checked content to Google Drive. The IDs for checked content were enrolled in the file and later they were compared with the new IDs. The comparison was made using a difference method from the open-source Undercode.js library.
As the output, we got an array of exclusively new videoId for the last hour, which we checked according to the scheme developed in the first version of the script for the occurrence of tags. And after the script was completed, we added all the videos for the current day to the same txt-file.
Setting Up the Script
-
Specify the name of the file to be created on Google Drive:
var dataFile = "videoIds.txt";
If there is no such a file, it will be created automatically. -
Select the campaigns you want to check:
'WHERE CampaignName CONTAINS "(Video)"
AWQL syntax is provided in the AdWords Help. -
Replace the file id in Google Spreadsheet:
var spreadsheet = SpreadsheetApp.openById('11PMGc70yLE88Npi47Hwb6W36Y8yjw2N2CdXXLgdK12o'); -
In the AdWords interface, create the general list of excluded placements:
var excludedPlacementList = AdWordsApp.excludedPlacementLists().withCondition('Name = "Video_channels"').get().next();
and insert its name instead of "Video_channels". -
Enable YouTube in extended APIs.
After the first views, enable YouTube API in Google Developers Console. The link will be in the error log. -
Set an "Every Hour" schedule for script operation.
And voila!
Final Comments
As a result, we created a script that checked YouTube channels with children's video content every hour without reaching the time limit. You can also customize the script to any topic by adding new tags to the Spreadsheet file. The code for the updated script was posted here. Your questions and suggestions are kindly appreciated.
Keep in mind that sometimes video channels with other content also falls in the exception list, but this happens rarely. There are two main reasons for that. The channel owners share content for children as well as other types of content. And sometimes, video channels may also use the wrong tags to expand their audience.
According to our observations, after you start using the script, the viewing rate (VTR, view-through rate) will significantly decrease, as adults press the "skip" button more often than children, but this way, your ad will be shown to the relevant audience.
Use the script and place your ads on the right channels!