Battle for adults: how to exclude children's channels from advertising on Youtube 24/7?
Background
Many people remember the recent scandal about the refusal of large advertisers to post on YouTube due to the fact that their prerolls (paid videos before the video, which can be skipped after 5 seconds) were shown in the video with inappropriate content. However, in our article we will talk about another problem - children's content. The fact is that even with the correct targeting settings for an adult audience, a huge number (up to 90%) of impressions are received by children's channels. This is due to the fact that parents from their "adult" accounts on their devices, both mobile and desktop, put cartoons for children. Of course, advertisers do not want to spend an advertising budget on children who are just watching prerolls, because it has practically no effect. Such videos and channels can be excluded using negative keywords or excluding whole topics, but it’s a long time, it’s difficult and will exclude far from all channels and videos - children's content is quite diverse. Many little-known children's channels and videos continue to show ads in them due to the fact that they have common, uncharacteristic children's names or an insufficient description, but they are still watched in large numbers by children. I decided to find a way to automate the search and exclusion of such channels using AdWords scripts.

Solution 1
So, I started creating my first script to search for children's channels. AdWords allows you to create your own JS scripts to manage your advertising account. They are based on Google Apps Scripts and their main advantage is integration with other Google services, such as Google Drive, Spreadsheets, YouTube, Analytics, BigQuery, etc., as well as the ability to connect third-party APIs. Before that, I had to work with the YouTube Data API v3 to search for videos as a placement. I will try to talk about this in another article. So, it was experimentally possible to establish that children's videos do not combine the names, but their tags . Having slightly modified the script for searching YouTube videos, I found similar tags for various requests of children's cartoons and saved them in Google Spreadsheetfor further use in a new script. The file is public, but I recommend you copy it to your Google Drive before setting up the script and replace the file id in the script with a new one.
Key points for understanding the script:
- From URL_PERFORMANCE_REPORT we get all the links to YouTube placements and get the videoId for yesterday.
var report = AdWordsApp.report( 'SELECT Url ' + 'FROM URL_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]); } - In a cycle, we send youtube requests with each video id. From the response we get the tags and ID of the video channel and check all the tags for intersection with our library of 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("Добавить в библиотеку исключений - " + channelId); break; } else { continue; }; } } } } catch (e) { Logger.log(e); } }
If any of the video tags matches the tags from the library, the video channel id is sent to the array for exclusion if it has not already been added through another video from the same channel. - After all the videos have been verified, we’ll start a cycle to add all channels to the list of excluded sites in your AdWords account. A list with a name identical to that in the script (I just have “Video Channels”) needs to be created in advance. The limit for the list of excluded sites in the list is 65,000, there should not be any problems with its overflow.
var excludedPlacementList = AdWordsApp.excludedPlacementLists().withCondition('Name = "Видеоканалы"').get().next(); for (var d = 0; d < channels.length; d++) { excludedPlacementList.addExcludedPlacement("youtube.com/channel/"+channels[d].toString()); };
Problems using the first script option
A fairly simple and effective solution, but as it turned out, not everything is so simple. When using this script, I had the following problem: when launching reach video campaigns, the script did not manage to process all the videos yesterday - it ran into the time limit of 30 minutes (AdWords internal limitation), and did not add new exceptions. In addition, it’s best to add videos as often and quickly as possible to save maximum money. Unfortunately, even after adding a video to the exclusion list, they, in experience, do not immediately begin to act. Google tech support says up to 2 days (according to observations, usually earlier).
Therefore, in a file on a separate page, there is already a list of channels accumulated during the operation of the script, it is better to add them to exceptions in advance.
Decision 2
After testing the first version of the script with a friend, a fan of automation, I realized that I need to check every hour and not check the videos that have already been checked before, otherwise the script started to run into the 30 minute limit by noon. The decision was taken from another script to change rates from hour to hour, who cares, here is a link to such a solution. Everything turned out a bit more complicated compared to the first version, but the result was excellent. We added functionality to save already verified videos to Google Drive in a txt-file, all the id for today are recorded there in order to compare them with a new report every hour. Comparison is made using the difference method from the free Underscore.js library.
var videoList = _.difference(videoIdList, data);At the output, we get an array of exclusively new videoId for the last hour, which we check according to the scheme of the first script for the occurrence of tags. And at the end of the script, we add to the same txt file all the videos for the current day.
Script setup
- Enter the name of the file to create in Google Drive
var dataFile = "videoIds.txt";
If there is no such file yet, then it will be created automatically. - Select the campaigns you want to test.
'WHERE CampaignName CONTAINS "(Video)"
The AWQL syntax is in AdWords Help. - Replace the id of the Google Spreadsheet file with yours
var spreadsheet = SpreadsheetApp.openById('11PMGc70yLE88Npi47Hwb6W36Y8yjw2N2CdXXLgdK12o'); - In the AdWords interface, create a general list of excluded placements
var excludedPlacementList = AdWordsApp.excludedPlacementLists().withCondition('Name = "Видеоканалы"').get().next();
and paste its name instead of "Video Channels." - Enable in YouTube’s Advanced APIs.
- After the first views, enable the YouTube API in the Google Developers Console. The link will be in the error log.
- Set the schedule for the script "Every hour."
Done!
The final
As a result, we got a script that checks children's channels every hour and does not run into a time limit. From other usefulnesses, you can customize the script on any subject by adding new tags to the spreadsheet file. The code for the updated script posted here . I will be happy to answer questions and suggestions.
Sometimes adult channels also fall into exceptions, but this happens quite rarely. There can be two reasons - either the owner of the channel places not only adults, but also children's videos in it, or intentionally uses children's tags to cheat and expand the audience. According to observations, after you start using the script, the view-through rate (VTR) will significantly decrease, as adults press the skip button much more often than children.
Use and post on the right channels!