Track YouTube video views & comments

Coding level: Beginner
Duration: 20 minutes
Project type: Automation with a time-driven trigger

Objectives

  • Understand what the solution does.
  • Understand what the Apps Script services do within the solution.
  • Set up the script.
  • Run the script.

About this solution

This solution tracks the performance of public YouTube videos, including views, likes, and comments, in a Google Sheets spreadsheet. The trigger checks for updated information each day and sends an email if videos have new comment activity so that you can engage with questions and comments.

Screenshot of YouTube data in a Google Sheet

How it works

The script uses the advanced YouTube service to get YouTube video details and statistics for the video URLs listed in the Video Linkcolumn in each sheet. If the number of comments for a listed video has gone up, the script sends an email notification to the email address that the sheet is named after.

Apps Script services

This solution uses the following services:

Prerequisites

To use this sample, you need the following prerequisites:

  • A Google Account (Google Workspace accounts might require administrator approval).
  • A web browser with access to the internet.

Set up the script

Create the Apps Script project

  1. Click the following button to make a copy of the Track YouTube video views and commentsspreadsheet. The Apps Script project for this solution is attached to the spreadsheet.
    Make a copy
  2. In your copied spreadsheet, change the name of the Your_Email_Addresssheet to your email address.
  3. Add the YouTube video URLs you want to track or use the provided URLs for testing. The URLs must start with the format www.youtube.com/watch?v= .
  4. Click Extensions > Apps Script. If YouTubeis already listed under Services, you can skip to the next 2 steps.
  5. Next to Services, click Add a service .
  6. From the list, select YouTube Data APIand click Add.

Create a trigger

  1. In the Apps Script project, click Triggers > Add trigger.
  2. For Choose which function to run, select markVideos.
  3. For Select event source, select Time-driven.
  4. For Select type of time based trigger, select Day timer.
  5. For Select time of day, choose your preferred time.
  6. When prompted, authorize the script. If the OAuth consent screen displays the warning, This app isn't verified, continue by selecting Advanced > Go to {Project Name} (unsafe).

Run the script

The trigger you set up runs the script once daily. You can run the script manually to test it.

  1. In the Apps Script project, click Editor .
  2. In the function dropdown, select markVideos.
  3. Click Run.
  4. Switch back to the spreadsheet to review the information the script added to the sheet.
  5. Open your email to review the email with the list of videos that have more than zero comments. When the script runs in the future, it only sends an email with videos whose comment count has increased since the last time the script ran.

Review the code

To review the Apps Script code for this solution, click View source codebelow:

View source code

Code.gs

solutions/automations/youtube-tracker/Code.js
 // To learn how to use this script, refer to the documentation: 
 // https://developers.google.com/apps-script/samples/automations/youtube-tracker 
 /* 
 Copyright 2022 Google LLC 
 Licensed under the Apache License, Version 2.0 (the "License"); 
 you may not use this file except in compliance with the License. 
 You may obtain a copy of the License at 
 https://www.apache.org/licenses/LICENSE-2.0 
 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. 
 See the License for the specific language governing permissions and 
 limitations under the License. 
 */ 
 // Sets preferences for email notification. Choose 'Y' to send emails, 'N' to skip emails. 
 const 
  
 EMAIL_ON 
  
 = 
  
 'Y' 
 ; 
 // Matches column names in Video sheet to variables. If the column names change, update these variables. 
 const 
  
 COLUMN_NAME 
  
 = 
  
 { 
  
 VIDEO 
 : 
  
 'Video Link' 
 , 
  
 TITLE 
 : 
  
 'Video Title' 
 , 
 }; 
 /** 
 * Gets YouTube video details and statistics for all 
 * video URLs listed in 'Video Link' column in each 
 * sheet. Sends email summary, based on preferences above, 
 * when videos have new comments or replies. 
 */ 
 function 
  
 markVideos 
 () 
  
 { 
  
 let 
  
 ss 
  
 = 
  
 SpreadsheetApp 
 . 
 getActiveSpreadsheet 
 (); 
  
 let 
  
 sheets 
  
 = 
  
 SpreadsheetApp 
 . 
 getActiveSpreadsheet 
 (). 
 getSheets 
 (); 
  
 // Runs through process for each tab in Spreadsheet. 
  
 sheets 
 . 
 forEach 
 ( 
 function 
 ( 
 dataSheet 
 ) 
  
 { 
  
 let 
  
 tabName 
  
 = 
  
 dataSheet 
 . 
 getName 
 (); 
  
 let 
  
 range 
  
 = 
  
 dataSheet 
 . 
 getDataRange 
 (); 
  
 let 
  
 numRows 
  
 = 
  
 range 
 . 
 getNumRows 
 (); 
  
 let 
  
 rows 
  
 = 
  
 range 
 . 
 getValues 
 (); 
  
 let 
  
 headerRow 
  
 = 
  
 rows 
 [ 
 0 
 ]; 
  
 // Finds the column indices. 
  
 let 
  
 videoColumnIdx 
  
 = 
  
 headerRow 
 . 
 indexOf 
 ( 
 COLUMN_NAME 
 . 
 VIDEO 
 ); 
  
 let 
  
 titleColumnIdx 
  
 = 
  
 headerRow 
 . 
 indexOf 
 ( 
 COLUMN_NAME 
 . 
 TITLE 
 ); 
  
 // Creates empty array to collect data for email table. 
  
 let 
  
 emailContent 
  
 = 
  
 []; 
  
 // Processes each row in spreadsheet. 
  
 for 
  
 ( 
 let 
  
 i 
  
 = 
  
 1 
 ; 
  
 i 
 < 
 numRows 
 ; 
  
 ++ 
 i 
 ) 
  
 { 
  
 let 
  
 row 
  
 = 
  
 rows 
 [ 
 i 
 ]; 
  
 // Extracts video ID. 
  
 let 
  
 videoId 
  
 = 
  
 extractVideoIdFromUrl 
 ( 
 row 
 [ 
 videoColumnIdx 
 ]) 
  
 // Processes each row that contains a video ID. 
  
 if 
 ( 
 ! 
 videoId 
 ) 
  
 { 
  
  
 continue 
 ; 
  
 } 
  
 // Calls getVideoDetails function and extracts target data for the video. 
  
 let 
  
 detailsResponse 
  
 = 
  
 getVideoDetails 
 ( 
 videoId 
 ); 
  
 let 
  
 title 
  
 = 
  
 detailsResponse 
 . 
 items 
 [ 
 0 
 ]. 
 snippet 
 . 
 title 
 ; 
  
 let 
  
 publishDate 
  
 = 
  
 detailsResponse 
 . 
 items 
 [ 
 0 
 ]. 
 snippet 
 . 
 publishedAt 
 ; 
  
 let 
  
 publishDateFormatted 
  
 = 
  
 new 
  
 Date 
 ( 
 publishDate 
 ); 
  
 let 
  
 views 
  
 = 
  
 detailsResponse 
 . 
 items 
 [ 
 0 
 ]. 
 statistics 
 . 
 viewCount 
 ; 
  
 let 
  
 likes 
  
 = 
  
 detailsResponse 
 . 
 items 
 [ 
 0 
 ]. 
 statistics 
 . 
 likeCount 
 ; 
  
 let 
  
 comments 
  
 = 
  
 detailsResponse 
 . 
 items 
 [ 
 0 
 ]. 
 statistics 
 . 
 commentCount 
 ; 
  
 let 
  
 channel 
  
 = 
  
 detailsResponse 
 . 
 items 
 [ 
 0 
 ]. 
 snippet 
 . 
 channelTitle 
 ; 
  
 // Collects title, publish date, channel, views, comments, likes details and pastes into tab. 
  
 let 
  
 detailsRow 
  
 = 
  
 [ 
 title 
 , 
 publishDateFormatted 
 , 
 channel 
 , 
 views 
 , 
 comments 
 , 
 likes 
 ]; 
  
 dataSheet 
 . 
 getRange 
 ( 
 i 
 + 
 1 
 , 
 titleColumnIdx 
 + 
 1 
 , 
 1 
 , 
 6 
 ). 
 setValues 
 ([ 
 detailsRow 
 ]); 
  
 // Determines if new count of comments/replies is greater than old count of comments/replies. 
  
 let 
  
 addlCommentCount 
  
 = 
  
 comments 
  
 - 
  
 row 
 [ 
 titleColumnIdx 
 + 
 4 
 ]; 
  
 // Adds video title, link, and additional comment count to table if new counts > old counts. 
  
 if 
  
 ( 
 addlCommentCount 
 > 
 0 
 ) 
  
 { 
  
 let 
  
 emailRow 
  
 = 
  
 [ 
 title 
 , 
 row 
 [ 
 videoColumnIdx 
 ], 
 addlCommentCount 
 ] 
  
 emailContent 
 . 
 push 
 ( 
 emailRow 
 ); 
  
 } 
  
 } 
  
 // Sends notification email if Content is not empty. 
  
 if 
  
 ( 
 emailContent 
 . 
 length 
 > 
 0 
 && 
 EMAIL_ON 
  
 == 
  
 'Y' 
 ) 
  
 { 
  
 sendEmailNotificationTemplate 
 ( 
 emailContent 
 , 
  
 tabName 
 ); 
  
 } 
  
 }); 
 } 
 /** 
 * Gets video details for YouTube videos 
 * using YouTube advanced service. 
 */ 
 function 
  
 getVideoDetails 
 ( 
 videoId 
 ) 
  
 { 
  
 let 
  
 part 
  
 = 
  
 "snippet,statistics" 
 ; 
  
 let 
  
 response 
  
 = 
  
 YouTube 
 . 
 Videos 
 . 
 list 
 ( 
 part 
 , 
  
 { 
 'id' 
 : 
  
 videoId 
 }); 
  
 return 
  
 response 
 ; 
 } 
 /** 
 * Extracts YouTube video ID from url. 
 * (h/t https://stackoverflow.com/a/3452617) 
 */ 
 function 
  
 extractVideoIdFromUrl 
 ( 
 url 
 ) 
  
 { 
  
 let 
  
 videoId 
  
 = 
  
 url 
 . 
 split 
 ( 
 'v=' 
 )[ 
 1 
 ]; 
  
 let 
  
 ampersandPosition 
  
 = 
  
 videoId 
 . 
 indexOf 
 ( 
 '&' 
 ); 
  
 if 
  
 ( 
 ampersandPosition 
  
 != 
  
 - 
 1 
 ) 
  
 { 
  
 videoId 
  
 = 
  
 videoId 
 . 
 substring 
 ( 
 0 
 , 
  
 ampersandPosition 
 ); 
  
 } 
  
  
 return 
  
 videoId 
 ; 
 } 
 /** 
 * Assembles notification email with table of video details. 
 * (h/t https://stackoverflow.com/questions/37863392/making-table-in-google-apps-script-from-array) 
 */ 
 function 
  
 sendEmailNotificationTemplate 
 ( 
 content 
 , 
  
 emailAddress 
 ) 
  
 { 
  
 let 
  
 template 
  
 = 
  
 HtmlService 
 . 
 createTemplateFromFile 
 ( 
 'email' 
 ); 
  
 template 
 . 
 content 
  
 = 
  
 content 
 ; 
  
 let 
  
 msg 
  
 = 
  
 template 
 . 
 evaluate 
 (); 
  
  
 MailApp 
 . 
 sendEmail 
 ( 
 emailAddress 
 , 
 'New comments or replies on YouTube' 
 , 
 msg 
 . 
 getContent 
 (),{ 
 htmlBody 
 : 
 msg 
 . 
 getContent 
 ()}); 
 } 

email.html

solutions/automations/youtube-tracker/email.html
<!--
 Copyright 2022 Google LLC

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 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.
 See the License for the specific language governing permissions and
 limitations under the License.
-->

<body>
  Hello,<br><br>You have new comments and/or replies on videos: <br><br>
  <table border="1">
    <tr>
      <th>Video Title</th>
      <th>Link</th>
      <th>Number of new replies and comments</th>
    </tr>
    <? for (var i = 0; i < content.length; i++) { ?>
    <tr>
      <? for (var j = 0; j < content[i].length; j++) { ?>
      <td align="center"><?= content[i][j] ?></td>
      <? } ?>
    </tr>
    <? } ?>
  </table>
</body>

Contributors

This sample is maintained by Google with the help of Google Developer Experts.

Next steps

Create a Mobile Website
View Site in Mobile | Classic
Share by: