หน้านี้จะอธิบายขั้นตอนการสร้างแอปพลิเคชันที่ใช้ API หลายรายการเพื่อสร้างแผนภูมิสถิติการดูวิดีโอ YouTube ของผู้ใช้ แอปพลิเคชันจะทํางานต่อไปนี้
- โดยจะใช้ YouTube Data API เพื่อดึงข้อมูลรายการวิดีโอที่ผู้ใช้ที่ผ่านการตรวจสอบสิทธิ์ในปัจจุบันอัปโหลด จากนั้นจะแสดงรายการชื่อวิดีโอ
- เมื่อผู้ใช้คลิกวิดีโอหนึ่งๆ แอปพลิเคชันจะเรียกใช้ YouTube Analytics API เพื่อดึงข้อมูลวิเคราะห์ของวิดีโอนั้น
- แอปพลิเคชันใช้ Google Visualization API เพื่อแสดงข้อมูลวิเคราะห์เป็นแผนภูมิ
ขั้นตอนต่อไปนี้อธิบายกระบวนการสร้างแอปพลิเคชัน ในขั้นตอนที่ 1 คุณสร้างไฟล์ HTML และ CSS ของแอปพลิเคชัน ขั้นตอนที่ 2-5 อธิบายส่วนต่างๆ ของ JavaScript ที่แอปพลิเคชันใช้ นอกจากนี้ยังมีโค้ดตัวอย่างที่สมบูรณ์อยู่ท้ายเอกสารด้วย
- ขั้นตอนที่ 1: สร้างหน้า HTML และไฟล์ CSS
- ขั้นตอนที่ 2: เปิดใช้การตรวจสอบสิทธิ์ OAuth 2.0
- ขั้นตอนที่ 3: ดึงข้อมูลสําหรับผู้ใช้ที่เข้าสู่ระบบอยู่ในขณะนี้
- ขั้นตอนที่ 4: ขอข้อมูล Analytics สําหรับวิดีโอ
- ขั้นตอนที่ 5: แสดงข้อมูล Analytics ในแผนภูมิ
สำคัญ: คุณต้องลงทะเบียนแอปพลิเคชันกับ Google เพื่อรับรหัสไคลเอ็นต์ OAuth 2.0 สําหรับแอปพลิเคชัน
ขั้นตอนที่ 1: สร้างหน้า HTML และไฟล์ CSS
ในขั้นตอนนี้ คุณจะได้สร้างหน้า HTML ที่โหลดไลบรารี JavaScript ที่แอปพลิเคชันจะใช้ HTML ด้านล่างแสดงโค้ดของหน้าเว็บ
<!doctype html> <html> <head> <title>Google I/O YouTube Codelab</title> <link type="text/css" rel="stylesheet" href="index.css"> <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript" src="//www.google.com/jsapi"></script> <script type="text/javascript" src="index.js"></script> <script type="text/javascript" src="https://apis.google.com/js/client.js?onload=onJSClientLoad"></script> </head> <body> <div id="login-container" class="pre-auth">This application requires access to your YouTube account. Please <a href="#" id="login-link">authorize</a> to continue. </div> <div class="post-auth"> <div id="message"></div> <div id="chart"></div> <div>Choose a Video:</div> <ul id="video-list"></ul> </div> </body> </html>
ดังที่แสดงในแท็ก <head>
ของหน้าตัวอย่าง แอปพลิเคชันใช้ไลบรารีต่อไปนี้
- jQuery มีเมธอดตัวช่วยเพื่อลดความซับซ้อนในการไปยังส่วนต่างๆ ของเอกสาร HTML, การจัดการเหตุการณ์, การสร้างภาพเคลื่อนไหว และการโต้ตอบกับ Ajax
- เครื่องมือโหลด Google API (
www.google.com/jsapi
) ช่วยให้คุณนําเข้า Google API อย่างน้อย 1 รายการได้อย่างง่ายดาย แอปพลิเคชันตัวอย่างนี้ใช้โปรแกรมโหลด API เพื่อโหลด Google Visualization API ซึ่งใช้ในการสร้างแผนภูมิจากข้อมูล Analytics ที่ดึงมา - คลัง index.js มีฟังก์ชันเฉพาะสำหรับแอปพลิเคชันตัวอย่าง บทแนะนํานี้จะอธิบายขั้นตอนการสร้างฟังก์ชันเหล่านั้น
- ไลบรารีของไคลเอ็นต์ Google APIs สําหรับ JavaScript ช่วยให้คุณใช้การตรวจสอบสิทธิ์ OAuth 2.0 และเรียกใช้ YouTube Analytics API ได้
แอปพลิเคชันตัวอย่างยังมีไฟล์ index.css ด้วย ตัวอย่างไฟล์ CSS ซึ่งคุณสามารถบันทึกไว้ในไดเรกทอรีเดียวกับหน้า HTML แสดงอยู่ด้านล่าง
body { font-family: Helvetica, sans-serif; } .pre-auth { display: none; } .post-auth { display: none; } #chart { width: 500px; height: 300px; margin-bottom: 1em; } #video-list { padding-left: 1em; list-style-type: none; } #video-list > li { cursor: pointer; } #video-list > li:hover { color: blue; }
ขั้นตอนที่ 2: เปิดใช้การตรวจสอบสิทธิ์ OAuth 2.0
ในขั้นตอนนี้ คุณจะเริ่มสร้างไฟล์ index.js ที่หน้า HTML เรียกใช้ ด้วยเหตุนี้ ให้สร้างไฟล์ชื่อ index.js ในไดเรกทอรีเดียวกับหน้า HTML และแทรกโค้ดต่อไปนี้ในไฟล์นั้น แทนที่สตริง YOUR_CLIENT_ID ด้วยรหัสไคลเอ็นต์สําหรับแอปพลิเคชันที่ลงทะเบียน
(function() { // Retrieve your client ID from the Google API Console at // https://console.cloud.google.com/. var OAUTH2_CLIENT_ID = 'YOUR_CLIENT_ID'; var OAUTH2_SCOPES = [ 'https://www.googleapis.com/auth/yt-analytics.readonly', 'https://www.googleapis.com/auth/youtube.readonly' ]; // Upon loading, the Google APIs JS client automatically invokes this callback. // See https://developers.google.com/api-client-library/javascript/features/authentication window.onJSClientLoad = function() { gapi.auth.init(function() { window.setTimeout(checkAuth, 1); }); }; // Attempt the immediate OAuth 2.0 client flow as soon as the page loads. // If the currently logged-in Google Account has previously authorized // the client specified as the OAUTH2_CLIENT_ID, then the authorization // succeeds with no user intervention. Otherwise, it fails and the // user interface that prompts for authorization needs to display. function checkAuth() { gapi.auth.authorize({ client_id: OAUTH2_CLIENT_ID, scope: OAUTH2_SCOPES, immediate: true }, handleAuthResult); } // Handle the result of a gapi.auth.authorize() call. function handleAuthResult(authResult) { if (authResult) { // Authorization was successful. Hide authorization prompts and show // content that should be visible after authorization succeeds. $('.pre-auth').hide(); $('.post-auth').show(); loadAPIClientInterfaces(); } else { // Authorization was unsuccessful. Show content related to prompting for // authorization and hide content that should be visible if authorization // succeeds. $('.post-auth').hide(); $('.pre-auth').show(); // Make the #login-link clickable. Attempt a non-immediate OAuth 2.0 // client flow. The current function is called when that flow completes. $('#login-link').click(function() { gapi.auth.authorize({ client_id: OAUTH2_CLIENT_ID, scope: OAUTH2_SCOPES, immediate: false }, handleAuthResult); }); } } // This helper method displays a message on the page. function displayMessage(message) { $('#message').text(message).show(); } // This helper method hides a previously displayed message on the page. function hideMessage() { $('#message').hide(); } /* In later steps, add additional functions above this line. */ })();
ขั้นตอนที่ 3: ดึงข้อมูลของผู้ใช้ที่เข้าสู่ระบบอยู่ในปัจจุบัน
ในขั้นตอนนี้ คุณจะต้องเพิ่มฟังก์ชันลงในไฟล์ index.js ซึ่งจะดึงข้อมูลฟีดวิดีโอที่อัปโหลดของผู้ใช้ที่เข้าสู่ระบบอยู่ในขณะนี้โดยใช้ YouTube Data API (v2.0) ฟีดนั้นจะระบุรหัสช่อง YouTube ของผู้ใช้ ซึ่งคุณต้องใช้เมื่อเรียกใช้ YouTube Analytics API นอกจากนี้ แอปตัวอย่างจะแสดงวิดีโอที่ผู้ใช้อัปโหลดเพื่อให้ผู้ใช้เรียกข้อมูล Analytics ของวิดีโอแต่ละรายการได้
ทําการเปลี่ยนแปลงต่อไปนี้ในไฟล์ index.js
-
เพิ่มฟังก์ชันที่โหลดอินเทอร์เฟซไคลเอ็นต์สําหรับ YouTube Analytics และ Data API ขั้นตอนนี้เป็นข้อกําหนดเบื้องต้นในการใช้ไคลเอ็นต์ JavaScript ของ Google APIs
เมื่อโหลดอินเทอร์เฟซไคลเอ็นต์ API ทั้ง 2 รายการแล้ว ฟังก์ชันจะเรียกใช้ฟังก์ชัน
getUserChannel
// Load the client interfaces for the YouTube Analytics and Data APIs, which // are required to use the Google APIs JS client. More info is available at // https://developers.google.com/api-client-library/javascript/dev/dev_jscript#loading-the-client-library-and-the-api function loadAPIClientInterfaces() { gapi.client.load('youtube', 'v3', function() { gapi.client.load('youtubeAnalytics', 'v1', function() { // After both client interfaces load, use the Data API to request // information about the authenticated user's channel. getUserChannel(); }); }); }
-
เพิ่มตัวแปร
channelId
และฟังก์ชันgetUserChannel
ฟังก์ชันนี้จะเรียกใช้ YouTube Data API (v3) และมีพารามิเตอร์mine
ซึ่งระบุว่าคำขอนี้มีไว้สำหรับข้อมูลช่องของผู้ใช้ที่ตรวจสอบสิทธิ์ในปัจจุบัน ระบบจะส่งchannelId
ไปยัง Analytics API เพื่อระบุช่องที่คุณดึงข้อมูล Analytics อยู่// Keep track of the currently authenticated user's YouTube channel ID. var channelId; // Call the Data API to retrieve information about the currently // authenticated user's YouTube channel. function getUserChannel() { // Also see: https://developers.google.com/youtube/v3/docs/channels/list var request = gapi.client.youtube.channels.list({ // Setting the "mine" request parameter's value to "true" indicates that // you want to retrieve the currently authenticated user's channel. mine: true, part: 'id,contentDetails' }); request.execute(function(response) { if ('error' in response) { displayMessage(response.error.message); } else { // We need the channel's channel ID to make calls to the Analytics API. // The channel ID value has the form "UCdLFeWKpkLhkguiMZUp8lWA". channelId = response.items[0].id; // Retrieve the playlist ID that uniquely identifies the playlist of // videos uploaded to the authenticated user's channel. This value has // the form "UUdLFeWKpkLhkguiMZUp8lWA". var uploadsListId = response.items[0].contentDetails.relatedPlaylists.uploads; // Use the playlist ID to retrieve the list of uploaded videos. getPlaylistItems(uploadsListId); } }); }
-
เพิ่มฟังก์ชัน
getPlaylistItems
ซึ่งดึงข้อมูลรายการในเพลย์ลิสต์ที่ระบุ ในกรณีนี้ เพลย์ลิสต์จะแสดงวิดีโอที่อัปโหลดไปยังช่องของผู้ใช้ (โปรดทราบว่าฟังก์ชันตัวอย่างด้านล่างจะดึงข้อมูลเฉพาะ 50 รายการแรกในฟีดนั้น และคุณจะต้องแบ่งหน้าเพื่อดึงข้อมูลรายการเพิ่มเติม)หลังจากดึงข้อมูลรายการเพลย์ลิสต์แล้ว ฟังก์ชันจะเรียกใช้ฟังก์ชัน
getVideoMetadata()
จากนั้นฟังก์ชันดังกล่าวจะรับข้อมูลเมตาเกี่ยวกับวิดีโอแต่ละรายการในรายการ และเพิ่มวิดีโอแต่ละรายการลงในรายการที่ผู้ใช้เห็น// Call the Data API to retrieve the items in a particular playlist. In this // example, we are retrieving a playlist of the currently authenticated user's // uploaded videos. By default, the list returns the most recent videos first. function getPlaylistItems(listId) { // See https://developers.google.com/youtube/v3/docs/playlistitems/list var request = gapi.client.youtube.playlistItems.list({ playlistId: listId, part: 'snippet' }); request.execute(function(response) { if ('error' in response) { displayMessage(response.error.message); } else { if ('items' in response) { // The jQuery.map() function iterates through all of the items in // the response and creates a new array that only contains the // specific property we're looking for: videoId. var videoIds = $.map(response.items, function(item) { return item.snippet.resourceId.videoId; }); // Now that we know the IDs of all the videos in the uploads list, // we can retrieve information about each video. getVideoMetadata(videoIds); } else { displayMessage('There are no videos in your channel.'); } } }); } // Given an array of video IDs, this function obtains metadata about each // video and then uses that metadata to display a list of videos. function getVideoMetadata(videoIds) { // https://developers.google.com/youtube/v3/docs/videos/list var request = gapi.client.youtube.videos.list({ // The 'id' property's value is a comma-separated string of video IDs. id: videoIds.join(','), part: 'id,snippet,statistics' }); request.execute(function(response) { if ('error' in response) { displayMessage(response.error.message); } else { // Get the jQuery wrapper for the #video-list element before starting // the loop. var videoList = $('#video-list'); $.each(response.items, function() { // Exclude videos that do not have any views, since those videos // will not have any interesting viewcount Analytics data. if (this.statistics.viewCount == 0) { return; } var title = this.snippet.title; var videoId = this.id; // Create a new <li> element that contains an <a> element. // Set the <a> element's text content to the video's title, and // add a click handler that will display Analytics data when invoked. var liElement = $('<li>'); var aElement = $('<a>'); // Setting the href value to '#' ensures that the browser renders the // <a> element as a clickable link. aElement.attr('href', '#'); aElement.text(title); aElement.click(function() { displayVideoAnalytics(videoId); }); // Call the jQuery.append() method to add the new <a> element to // the <li> element, and the <li> element to the parent // list, which is identified by the 'videoList' variable. liElement.append(aElement); videoList.append(liElement); }); if (videoList.children().length == 0) { // Display a message if the channel does not have any viewed videos. displayMessage('Your channel does not have any videos that have been viewed.'); } } }); }
ขั้นตอนที่ 4: ขอข้อมูล Analytics สําหรับวิดีโอ
ในขั้นตอนนี้ คุณจะแก้ไขแอปพลิเคชันตัวอย่างเพื่อให้เมื่อคลิกชื่อวิดีโอ แอปพลิเคชันเรียกใช้ YouTube Analytics API เพื่อดึงข้อมูล Analytics ของวิดีโอนั้น โดยทําการเปลี่ยนแปลงต่อไปนี้ในแอปพลิเคชันตัวอย่าง
-
เพิ่มตัวแปรที่ระบุช่วงวันที่เริ่มต้นสําหรับข้อมูลรายงาน Analytics ที่ดึงข้อมูล
var ONE_MONTH_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 30;
-
เพิ่มโค้ดที่สร้างสตริง
YYYY-MM-DD
สําหรับออบเจ็กต์วันที่ และเพิ่มตัวเลขวันและเดือนในวันที่เป็น 2 หลัก// This boilerplate code takes a Date object and returns a YYYY-MM-DD string. function formatDateString(date) { var yyyy = date.getFullYear().toString(); var mm = padToTwoCharacters(date.getMonth() + 1); var dd = padToTwoCharacters(date.getDate()); return yyyy + '-' + mm + '-' + dd; } // If number is a single digit, prepend a '0'. Otherwise, return the number // as a string. function padToTwoCharacters(number) { if (number < 10) { return '0' + number; } else { return number.toString(); } }
-
กำหนดฟังก์ชัน
displayVideoAnalytics
ซึ่งดึงข้อมูล YouTube Analytics ของวิดีโอ ฟังก์ชันนี้จะทำงานเมื่อผู้ใช้คลิกวิดีโอในรายการ ฟังก์ชันgetVideoMetadata
ซึ่งแสดงรายการวิดีโอและกำหนดไว้ในขั้นตอนที่ 3 จะกำหนดตัวแฮนเดิลเหตุการณ์การคลิก// This function requests YouTube Analytics data for a video and displays // the results in a chart. function displayVideoAnalytics(videoId) { if (channelId) { // To use a different date range, modify the ONE_MONTH_IN_MILLISECONDS // variable to a different millisecond delta as desired. var today = new Date(); var lastMonth = new Date(today.getTime() - ONE_MONTH_IN_MILLISECONDS); var request = gapi.client.youtubeAnalytics.reports.query({ // The start-date and end-date parameters must be YYYY-MM-DD strings. 'start-date': formatDateString(lastMonth), 'end-date': formatDateString(today), // At this time, you need to explicitly specify channel==channelId. // See https://developers.google.com/youtube/analytics/v1/#ids ids: 'channel==' + channelId, dimensions: 'day', sort: 'day', // See https://developers.google.com/youtube/analytics/v1/available_reports // for details about the different filters and metrics you can request // if the "dimensions" parameter value is "day". metrics: 'views', filters: 'video==' + videoId }); request.execute(function(response) { // This function is called regardless of whether the request succeeds. // The response contains YouTube Analytics data or an error message. if ('error' in response) { displayMessage(response.error.message); } else { displayChart(videoId, response); } }); } else { // The currently authenticated user's channel ID is not available. displayMessage('The YouTube channel ID for the current user is not available.'); } }
ดูข้อมูลเพิ่มเติมเกี่ยวกับข้อมูลที่ดึงมาได้และชุดค่าผสมที่ถูกต้องสำหรับพารามิเตอร์
metrics
,dimensions
และfilters
ได้ในหน้ารายงานที่ใช้ได้ของเอกสารประกอบ API
ขั้นตอนที่ 5: แสดงข้อมูล Analytics ในแผนภูมิ
ในขั้นตอนนี้ คุณจะเพิ่มฟังก์ชัน displayChart
ซึ่งจะส่งข้อมูลวิเคราะห์ YouTube ไปยัง Google Visualization API จากนั้น API ดังกล่าวจะสร้างแผนภูมิข้อมูล
-
โหลด Google Visualization API ซึ่งจะแสดงข้อมูลเป็นแผนภูมิ ดูรายละเอียดเพิ่มเติมเกี่ยวกับตัวเลือกแผนภูมิได้ในเอกสารประกอบของ Visualisation API
google.load('visualization', '1.0', {'packages': ['corechart']});
-
กําหนดฟังก์ชันใหม่ชื่อ
displayChart
ที่ใช้ Google Visualization API เพื่อสร้างแผนภูมิที่แสดงข้อมูล Analytics แบบไดนามิก// Call the Google Chart Tools API to generate a chart of Analytics data. function displayChart(videoId, response) { if ('rows' in response) { hideMessage(); // The columnHeaders property contains an array of objects representing // each column's title -- e.g.: [{name:"day"},{name:"views"}] // We need these column titles as a simple array, so we call jQuery.map() // to get each element's "name" property and create a new array that only // contains those values. var columns = $.map(response.columnHeaders, function(item) { return item.name; }); // The google.visualization.arrayToDataTable() function wants an array // of arrays. The first element is an array of column titles, calculated // above as "columns". The remaining elements are arrays that each // represent a row of data. Fortunately, response.rows is already in // this format, so it can just be concatenated. // See https://developers.google.com/chart/interactive/docs/datatables_dataviews#arraytodatatable var chartDataArray = [columns].concat(response.rows); var chartDataTable = google.visualization.arrayToDataTable(chartDataArray); var chart = new google.visualization.LineChart(document.getElementById('chart')); chart.draw(chartDataTable, { // Additional options can be set if desired as described at: // https://developers.google.com/chart/interactive/docs/reference#visdraw title: 'Views per Day of Video ' + videoId }); } else { displayMessage('No data available for video ' + videoId); } }
ดูไฟล์ index.js ฉบับเต็ม
ไฟล์ index.js ด้านล่างรวมการเปลี่ยนแปลงทั้งหมดจากขั้นตอนที่แสดงด้านบน โปรดทราบว่าคุณต้องแทนที่สตริง YOUR_CLIENT_ID ด้วยรหัสไคลเอ็นต์ของแอปพลิเคชันที่ลงทะเบียน
(function() { // Retrieve your client ID from the Google API Console at // https://console.cloud.google.com/. var OAUTH2_CLIENT_ID = 'YOUR_CLIENT_ID'; var OAUTH2_SCOPES = [ 'https://www.googleapis.com/auth/yt-analytics.readonly', 'https://www.googleapis.com/auth/youtube.readonly' ]; var ONE_MONTH_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 30; // Keep track of the currently authenticated user's YouTube channel ID. var channelId; // For information about the Google Chart Tools API, see: // https://developers.google.com/chart/interactive/docs/quick_start google.load('visualization', '1.0', {'packages': ['corechart']}); // Upon loading, the Google APIs JS client automatically invokes this callback. // See https://developers.google.com/api-client-library/javascript/features/authentication window.onJSClientLoad = function() { gapi.auth.init(function() { window.setTimeout(checkAuth, 1); }); }; // Attempt the immediate OAuth 2.0 client flow as soon as the page loads. // If the currently logged-in Google Account has previously authorized // the client specified as the OAUTH2_CLIENT_ID, then the authorization // succeeds with no user intervention. Otherwise, it fails and the // user interface that prompts for authorization needs to display. function checkAuth() { gapi.auth.authorize({ client_id: OAUTH2_CLIENT_ID, scope: OAUTH2_SCOPES, immediate: true }, handleAuthResult); } // Handle the result of a gapi.auth.authorize() call. function handleAuthResult(authResult) { if (authResult) { // Authorization was successful. Hide authorization prompts and show // content that should be visible after authorization succeeds. $('.pre-auth').hide(); $('.post-auth').show(); loadAPIClientInterfaces(); } else { // Authorization was unsuccessful. Show content related to prompting for // authorization and hide content that should be visible if authorization // succeeds. $('.post-auth').hide(); $('.pre-auth').show(); // Make the #login-link clickable. Attempt a non-immediate OAuth 2.0 // client flow. The current function is called when that flow completes. $('#login-link').click(function() { gapi.auth.authorize({ client_id: OAUTH2_CLIENT_ID, scope: OAUTH2_SCOPES, immediate: false }, handleAuthResult); }); } } // Load the client interfaces for the YouTube Analytics and Data APIs, which // are required to use the Google APIs JS client. More info is available at // https://developers.google.com/api-client-library/javascript/dev/dev_jscript#loading-the-client-library-and-the-api function loadAPIClientInterfaces() { gapi.client.load('youtube', 'v3', function() { gapi.client.load('youtubeAnalytics', 'v1', function() { // After both client interfaces load, use the Data API to request // information about the authenticated user's channel. getUserChannel(); }); }); } // Call the Data API to retrieve information about the currently // authenticated user's YouTube channel. function getUserChannel() { // Also see: https://developers.google.com/youtube/v3/docs/channels/list var request = gapi.client.youtube.channels.list({ // Setting the "mine" request parameter's value to "true" indicates that // you want to retrieve the currently authenticated user's channel. mine: true, part: 'id,contentDetails' }); request.execute(function(response) { if ('error' in response) { displayMessage(response.error.message); } else { // We need the channel's channel ID to make calls to the Analytics API. // The channel ID value has the form "UCdLFeWKpkLhkguiMZUp8lWA". channelId = response.items[0].id; // Retrieve the playlist ID that uniquely identifies the playlist of // videos uploaded to the authenticated user's channel. This value has // the form "UUdLFeWKpkLhkguiMZUp8lWA". var uploadsListId = response.items[0].contentDetails.relatedPlaylists.uploads; // Use the playlist ID to retrieve the list of uploaded videos. getPlaylistItems(uploadsListId); } }); } // Call the Data API to retrieve the items in a particular playlist. In this // example, we are retrieving a playlist of the currently authenticated user's // uploaded videos. By default, the list returns the most recent videos first. function getPlaylistItems(listId) { // See https://developers.google.com/youtube/v3/docs/playlistitems/list var request = gapi.client.youtube.playlistItems.list({ playlistId: listId, part: 'snippet' }); request.execute(function(response) { if ('error' in response) { displayMessage(response.error.message); } else { if ('items' in response) { // The jQuery.map() function iterates through all of the items in // the response and creates a new array that only contains the // specific property we're looking for: videoId. var videoIds = $.map(response.items, function(item) { return item.snippet.resourceId.videoId; }); // Now that we know the IDs of all the videos in the uploads list, // we can retrieve information about each video. getVideoMetadata(videoIds); } else { displayMessage('There are no videos in your channel.'); } } }); } // Given an array of video IDs, this function obtains metadata about each // video and then uses that metadata to display a list of videos. function getVideoMetadata(videoIds) { // https://developers.google.com/youtube/v3/docs/videos/list var request = gapi.client.youtube.videos.list({ // The 'id' property's value is a comma-separated string of video IDs. id: videoIds.join(','), part: 'id,snippet,statistics' }); request.execute(function(response) { if ('error' in response) { displayMessage(response.error.message); } else { // Get the jQuery wrapper for the #video-list element before starting // the loop. var videoList = $('#video-list'); $.each(response.items, function() { // Exclude videos that do not have any views, since those videos // will not have any interesting viewcount Analytics data. if (this.statistics.viewCount == 0) { return; } var title = this.snippet.title; var videoId = this.id; // Create a new <li> element that contains an <a> element. // Set the <a> element's text content to the video's title, and // add a click handler that will display Analytics data when invoked. var liElement = $('<li>'); var aElement = $('<a>'); // Setting the href value to '#' ensures that the browser renders the // <a> element as a clickable link. aElement.attr('href', '#'); aElement.text(title); aElement.click(function() { displayVideoAnalytics(videoId); }); // Call the jQuery.append() method to add the new <a> element to // the <li> element, and the <li> element to the parent // list, which is identified by the 'videoList' variable. liElement.append(aElement); videoList.append(liElement); }); if (videoList.children().length == 0) { // Display a message if the channel does not have any viewed videos. displayMessage('Your channel does not have any videos that have been viewed.'); } } }); } // This function requests YouTube Analytics data for a video and displays // the results in a chart. function displayVideoAnalytics(videoId) { if (channelId) { // To use a different date range, modify the ONE_MONTH_IN_MILLISECONDS // variable to a different millisecond delta as desired. var today = new Date(); var lastMonth = new Date(today.getTime() - ONE_MONTH_IN_MILLISECONDS); var request = gapi.client.youtubeAnalytics.reports.query({ // The start-date and end-date parameters must be YYYY-MM-DD strings. 'start-date': formatDateString(lastMonth), 'end-date': formatDateString(today), // At this time, you need to explicitly specify channel==channelId. // See https://developers.google.com/youtube/analytics/v1/#ids ids: 'channel==' + channelId, dimensions: 'day', sort: 'day', // See https://developers.google.com/youtube/analytics/v1/available_reports // for details about the different filters and metrics you can request // if the "dimensions" parameter value is "day". metrics: 'views', filters: 'video==' + videoId }); request.execute(function(response) { // This function is called regardless of whether the request succeeds. // The response contains YouTube Analytics data or an error message. if ('error' in response) { displayMessage(response.error.message); } else { displayChart(videoId, response); } }); } else { // The currently authenticated user's channel ID is not available. displayMessage('The YouTube channel ID for the current user is not available.'); } } // This boilerplate code takes a Date object and returns a YYYY-MM-DD string. function formatDateString(date) { var yyyy = date.getFullYear().toString(); var mm = padToTwoCharacters(date.getMonth() + 1); var dd = padToTwoCharacters(date.getDate()); return yyyy + '-' + mm + '-' + dd; } // If number is a single digit, prepend a '0'. Otherwise, return the number // as a string. function padToTwoCharacters(number) { if (number < 10) { return '0' + number; } else { return number.toString(); } } // Call the Google Chart Tools API to generate a chart of Analytics data. function displayChart(videoId, response) { if ('rows' in response) { hideMessage(); // The columnHeaders property contains an array of objects representing // each column's title -- e.g.: [{name:"day"},{name:"views"}] // We need these column titles as a simple array, so we call jQuery.map() // to get each element's "name" property and create a new array that only // contains those values. var columns = $.map(response.columnHeaders, function(item) { return item.name; }); // The google.visualization.arrayToDataTable() function wants an array // of arrays. The first element is an array of column titles, calculated // above as "columns". The remaining elements are arrays that each // represent a row of data. Fortunately, response.rows is already in // this format, so it can just be concatenated. // See https://developers.google.com/chart/interactive/docs/datatables_dataviews#arraytodatatable var chartDataArray = [columns].concat(response.rows); var chartDataTable = google.visualization.arrayToDataTable(chartDataArray); var chart = new google.visualization.LineChart(document.getElementById('chart')); chart.draw(chartDataTable, { // Additional options can be set if desired as described at: // https://developers.google.com/chart/interactive/docs/reference#visdraw title: 'Views per Day of Video ' + videoId }); } else { displayMessage('No data available for video ' + videoId); } } // This helper method displays a message on the page. function displayMessage(message) { $('#message').text(message).show(); } // This helper method hides a previously displayed message on the page. function hideMessage() { $('#message').hide(); } })();