追蹤 YouTube 影片觀看次數和留言

程式設計層級:新手
時間長度:20 分鐘
專案類型:透過時間導向的觸發條件自動化

目標

  • 瞭解解決方案的功能。
  • 瞭解 Apps Script 服務在解決方案中的功能。
  • 設定指令碼。
  • 執行指令碼。

認識這項解決方案

這項解決方案會追蹤 Google 試算表中的公開 YouTube 影片成效,包括觀看次數、喜歡次數和留言數。觸發條件會每天檢查最新資訊,並在影片有新的留言活動時傳送電子郵件,以便您回答問題或留言。

Google 試算表中 YouTube 資料的螢幕截圖

運作方式

這段指令碼會使用進階 YouTube 服務,取得 YouTube 影片的詳細資料,以及每份工作表「影片連結」欄內所列的影片網址統計資料。如果所列影片的留言數上升,指令碼會傳送電子郵件通知到工作表所命名的電子郵件地址。

Apps Script 服務

這項解決方案會使用以下服務:

必要條件

如要使用這個範例,您必須具備以下先決條件:

  • Google 帳戶 (Google Workspace 帳戶可能需要管理員核准)。
  • 可連上網際網路的網路瀏覽器。

設定指令碼

建立 Apps Script 專案

  1. 點選下方按鈕即可複製「追蹤 YouTube 影片觀看次數和註解」試算表的副本。這個解決方案的 Apps Script 專案已附加到試算表。
    建立副本
  2. 在複製的試算表中,將「Your_Email_Address」Your_Email_Address工作表的名稱變更為您的電子郵件地址。
  3. 新增您要追蹤的 YouTube 影片網址,或使用所提供的網址進行測試。網址的開頭必須是 www.youtube.com/watch?v=
  4. 依序按一下「Extensions」>「Apps Script」。如果「Service」(服務) 下方已列出 YouTube,您可以直接跳到接下來的 2 個步驟。
  5. 按一下「Service」旁邊的「新增服務」圖示
  6. 從清單中選取「YouTube Data API」,然後按一下「新增」

建立觸發條件

  1. 在 Apps Script 專案中,依序按一下「觸發條件」 >「新增觸發條件」
  2. 在「選擇要執行的函式」部分,選取「markVideos」
  3. 在「選取事件來源」部分,選取「時間導向」
  4. 在「選取以時間為準的觸發條件類型」部分,選取「日計時器」
  5. 在「選取時間」部分,選擇您偏好的時間。
  6. 出現提示訊息時,請授權指令碼。如果 OAuth 同意畫面顯示警告,請依序選取「Advanced」>「Go to {Project Name} (unsafe)」繼續操作。

執行指令碼

您設定的觸發條件每天會執行一次指令碼。您可以手動執行指令碼進行測試。

  1. 在 Apps Script 專案中,按一下「Editor」圖示
  2. 在函式下拉式選單中選取「markVideos」markVideos
  3. 按一下「執行」
  4. 切換回試算表,查看指令碼新增至工作表的資訊。
  5. 請開啟電子郵件,查看電子郵件清單,並會列出留言數量超過零的影片。日後執行指令碼時,只會傳送電子郵件,內含自上次執行指令碼以來,影片留言數有所增加的影片。

檢查程式碼

如要查看這個解決方案的 Apps Script 程式碼,請點選下方的「查看原始碼」

查看原始碼

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>

貢獻者

這個範例由 Google 開發人員專家協助維護。

後續步驟