이 페이지에서는 여러 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단계: 동영상의 분석 데이터 요청하기
- 5단계: 차트에 애널리틱스 데이터 표시하기
중요: 애플리케이션의 OAuth 2.0 클라이언트 ID를 가져오려면 Google에 애플리케이션을 등록해야 합니다.
1단계: HTML 페이지와 CSS 파일 빌드
이 단계에서는 애플리케이션에서 사용할 JavaScript 라이브러리를 로드하는 HTML 페이지를 만듭니다. 다음은 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를 쉽게 가져올 수 있습니다. 이 샘플 애플리케이션은 API 로더를 사용하여 가져온 애널리틱스 데이터를 차트로 표시하는 데 사용되는 Google Visualization API를 로드합니다. - index.js 라이브러리에는 샘플 애플리케이션과 관련된 함수가 포함되어 있습니다. 이 가이드에서는 이 전용 함수를 만드는 단계를 설명합니다.
- JavaScript용 Google API 클라이언트 라이브러리를 사용하여 OAuth 2.0 인증을 구현하고 YouTube Analytics API를 호출합니다.
샘플 애플리케이션에는 index.css 파일도 포함되어 있습니다. HTML 페이지와 같은 디렉토리에 저장할 수 있는 샘플 CSS 파일은 다음과 같습니다.
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 인증 사용
이 단계에서는 HTML 페이지에서 호출되는 index.js 파일을 빌드하기 시작합니다. 이를 염두에 두고 HTML 페이지와 동일한 디렉터리에 index.js라는 파일을 만들고 이 파일에 다음 코드를 삽입합니다. YOUR_CLIENT_ID 문자열을 등록된 애플리케이션의 클라이언트 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단계: 현재 로그인한 사용자의 데이터 검색
이 단계에서는 YouTube Data API (v2.0)를 사용하여 현재 로그인한 사용자의 업로드된 동영상 피드를 가져오는 함수를 index.js 파일에 추가합니다. 이 피드에는 YouTube 분석 API를 호출할 때 필요한 사용자의 YouTube 채널 ID가 지정됩니다. 또한 샘플 앱은 사용자가 개별 동영상의 분석 데이터를 검색할 수 있도록 사용자가 업로드한 동영상을 표시합니다.
index.js 파일을 다음과 같이 변경합니다.
-
YouTube 애널리틱스 및 Data API의 클라이언트 인터페이스를 로드하는 함수를 추가합니다. 이는 Google API JavaScript 클라이언트를 사용하기 위한 기본 요건입니다.
두 API 클라이언트 인터페이스가 모두 로드되면 함수가
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
는 애널리틱스 데이터를 가져오는 채널을 식별하기 위해 애널리틱스 API로 전송됩니다.
// 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단계: 동영상의 분석 데이터 요청
이 단계에서는 동영상 제목을 클릭하면 애플리케이션이 YouTube Analytics API를 호출하여 해당 동영상의 애널리틱스 데이터를 가져오도록 샘플 애플리케이션을 수정합니다. 샘플 애플리케이션을 다음과 같이 변경합니다.
-
가져온 애널리틱스 보고서 데이터의 기본 기간을 지정하는 변수를 추가합니다.
var ONE_MONTH_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 30; -
날짜 객체의
YYYY-MM-DD
문자열을 만들고 날짜의 일과 월 번호를 두 자리로 채우는 코드를 추가합니다.
// 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();
}
} -
동영상의 YouTube 분석 데이터를 가져오는
displayVideoAnalytics
함수를 정의합니다. 이 함수는 사용자가 목록에서 동영상을 클릭할 때 실행됩니다. 동영상 목록을 출력하고 3단계에서 정의된getVideoMetadata
함수는 클릭 이벤트 핸들러를 정의합니다.
// 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단계: 차트에 애널리틱스 데이터 표시
이 단계에서는 YouTube 분석 데이터를 Google Visualization API로 전송하는 displayChart
함수를 추가합니다. 그러면 해당 API가 정보를 차트로 표시합니다.
-
Google Visualization API를 로드하면 차트에 데이터가 표시됩니다. 차트 옵션에 관한 자세한 내용은 Visualization API 문서를 참고하세요.
google.load('visualization', '1.0', {'packages': ['corechart']});
-
Google Visualization API를 사용하여 애널리틱스 데이터를 보여주는 차트를 동적으로 생성하는
displayChart
라는 새 함수를 정의합니다.
// 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 문자열을 등록된 애플리케이션의 클라이언트 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();
}
})();