Skip to content
This repository was archived by the owner on Aug 12, 2025. It is now read-only.

Commit 767d553

Browse files
committed
"Added sample: apps-script/youtube.gs"
1 parent 2b3cc1f commit 767d553

1 file changed

Lines changed: 307 additions & 0 deletions

File tree

apps-script/youtube.gs

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
/** START SECTION searchByTopic **/
2+
// TITLE: Search by topic
3+
// DESCRIPTION: use_function_comment
4+
// API_METHOD: youtube.search.list
5+
/**
6+
* This function searches for videos that are associated with a particular Freebase
7+
* topic, logging their video IDs and titles to the Apps Script log. This example uses
8+
* the topic ID for Google Apps Script.
9+
*
10+
* Note that this sample limits the results to 25. To return more results, pass
11+
* additional parameters as documented here:
12+
* https://developers.google.com/youtube/v3/docs/search/list
13+
*/
14+
function searchByTopic() {
15+
var mid = '/m/0gjf126';
16+
var results = YouTube.Search.list('id,snippet', {topicId: mid, maxResults: 25});
17+
18+
for(var i in results.items) {
19+
var item = results.items[i];
20+
Logger.log('[%s] Title: %s', item.id.videoId, item.snippet.title);
21+
}
22+
}
23+
/** END SECTION searchByTopic **/
24+
25+
/** START SECTION searchByKeyword **/
26+
// TITLE: Search by keyword
27+
// DESCRIPTION: use_function_comment
28+
// API_METHOD: youtube.search.list
29+
/**
30+
* This function searches for videos related to the keyword 'dogs'. The video IDs and titles
31+
* of the search results are logged to Apps Script's log.
32+
*
33+
* Note that this sample limits the results to 25. To return more results, pass
34+
* additional parameters as documented here:
35+
* https://developers.google.com/youtube/v3/docs/search/list
36+
*/
37+
function searchByKeyword() {
38+
var results = YouTube.Search.list('id,snippet', {q: 'dogs', maxResults: 25});
39+
40+
for(var i in results.items) {
41+
var item = results.items[i];
42+
Logger.log('[%s] Title: %s', item.id.videoId, item.snippet.title);
43+
}
44+
}
45+
/** END SECTION searchByKeyword **/
46+
47+
48+
/** START SECTION retrieveMyUploads **/
49+
// TITLE: Retrieve my uploads
50+
// DESCRIPTION: use_function_comment
51+
// API_METHOD: youtube.channels.list
52+
/**
53+
* This function retrieves the current script user's uploaded videos. To execute,
54+
* it requires the OAuth read/write scope for YouTube as well as user authorization.
55+
* In Apps Script's runtime environment, the first time a user runs a script, Apps
56+
* Script will prompt the user for permission to access the services called by the
57+
* script. After permissions are granted, they are cached for some periodF of time.
58+
* The user running the script will be prompted for permission again once the
59+
* permissions required change, or when they are invalidated by the
60+
* ScriptApp.invalidateAuth() function.
61+
*
62+
* This script takes the following steps to retrieve the active user's uploaded videos:
63+
* 1. Fetches the user's channels
64+
* 2. Fetches the user's 'uploads' playlist
65+
* 3. Iterates through this playlist and logs the video IDs and titles
66+
* 4. Fetches a next page token (if any). If there is one, fetches the next page. GOTO Step 3
67+
*/
68+
function retrieveMyUploads() {
69+
var results = YouTube.Channels.list('contentDetails', {mine: true});
70+
71+
for(var i in results.items) {
72+
var item = results.items[i];
73+
// Get the playlist ID, which is nested in contentDetails, as described in the
74+
// Channel resource: https://developers.google.com/youtube/v3/docs/channels
75+
var playlistId = item.contentDetails.relatedPlaylists.uploads;
76+
77+
var nextPageToken = '';
78+
79+
// This loop retrieves a set of playlist items and checks the nextPageToken in the
80+
// response to determine whether the list contains additional items. It repeats that process
81+
// until it has retrieved all of the items in the list.
82+
while (nextPageToken != null) {
83+
var playlistResponse = YouTube.PlaylistItems.list('snippet', {
84+
playlistId: playlistId,
85+
maxResults: 25,
86+
pageToken: nextPageToken
87+
});
88+
89+
for (var j = 0; j < playlistResponse.items.length; j++) {
90+
var playlistItem = playlistResponse.items[j];
91+
Logger.log('[%s] Title: %s',
92+
playlistItem.snippet.resourceId.videoId,
93+
playlistItem.snippet.title);
94+
95+
}
96+
nextPageToken = playlistResponse.nextPageToken;
97+
}
98+
}
99+
}
100+
/** END SECTION retrieveMyUploads **/
101+
102+
/** START SECTION updateVideo **/
103+
// TITLE: Update video
104+
// DESCRIPTION: use_function_comment
105+
// API_METHOD: youtube.videos.update
106+
/**
107+
* This sample finds the active user's uploads, then updates the most recent
108+
* upload's description by appending a string.
109+
*/
110+
function updateVideo() {
111+
// 1. Fetch all the channels owned by active user
112+
var myChannels = YouTube.Channels.list('contentDetails', {mine: true});
113+
114+
// 2. Iterate through the channels and get the uploads playlist ID
115+
for (var i = 0; i < myChannels.items.length; i++) {
116+
var item = myChannels.items[i];
117+
var uploadsPlaylistId = item.contentDetails.relatedPlaylists.uploads;
118+
119+
var playlistResponse = YouTube.PlaylistItems.list('snippet', {
120+
playlistId: uploadsPlaylistId,
121+
maxResults: 1
122+
});
123+
124+
// Get the videoID of the first video in the list
125+
var video = playlistResponse.items[0];
126+
var originalDescription = video.snippet.description;
127+
var updatedDescription = originalDescription + ' Description updated via Google Apps Script';
128+
129+
video.snippet.description = updatedDescription;
130+
131+
var resource = {
132+
snippet: {
133+
title: video.snippet.title,
134+
description: updatedDescription,
135+
categoryId: '22'
136+
},
137+
id: video.snippet.resourceId.videoId
138+
};
139+
YouTube.Videos.update(resource, 'id,snippet');
140+
}
141+
}
142+
/** END SECTION updateVideo **/
143+
144+
/** START SECTION addSubscription **/
145+
// TITLE: Subscribe to channel
146+
// DESCRIPTION: use_function_comment
147+
// API_METHOD: youtube.subscriptions.insert
148+
/**
149+
* This sample subscribes the active user to the GoogleDevelopers
150+
* YouTube channel, specified by the channelId.
151+
*/
152+
function addSubscription() {
153+
// Replace this channel ID with the channel ID you want to subscribe to
154+
var channelId = 'UC9gFih9rw0zNCK3ZtoKQQyA';
155+
156+
var resource = {
157+
snippet: {
158+
resourceId: {
159+
kind: 'youtube#channel',
160+
channelId: channelId
161+
}
162+
}
163+
};
164+
165+
try {
166+
var response = YouTube.Subscriptions.insert(resource, 'snippet');
167+
Logger.log(response);
168+
} catch (e) {
169+
if(e.message.match('subscriptionDuplicate')) {
170+
Logger.log('Cannot subscribe; already subscribed to channel: ' + channelId);
171+
} else {
172+
Logger.log('Error adding subscription: ' + e.message);
173+
}
174+
}
175+
}
176+
/** END SECTION addSubscription **/
177+
178+
/** START SECTION postChannelBulletin **/
179+
// TITLE: Post channel bulletin
180+
// DESCRIPTION: use_function_comment
181+
// API_METHOD: youtube.activities.insert
182+
/**
183+
* This function creates and posts a new channel bulletin, adding a video and message. Note that this
184+
* will also accept a playlist ID. After completing the API call, logs the output to the log.
185+
*/
186+
function postChannelBulletin() {
187+
var message = 'Thanks for subscribing to my channel! This posting is from Google Apps Script';
188+
var videoId = 'qZRsVqOIWms';
189+
190+
var resource = {
191+
snippet: {
192+
description: message
193+
},
194+
contentDetails: {
195+
bulletin: {
196+
resourceId: {
197+
kind: 'youtube#video',
198+
videoId: videoId
199+
}
200+
}
201+
}
202+
};
203+
204+
var response = YouTube.Activities.insert(resource, 'snippet,contentDetails');
205+
Logger.log(response);
206+
}
207+
/** END SECTION postChannelBulletin **/
208+
209+
/** START SECTION spreadsheetAnalytics **/
210+
// TITLE: YouTube Analytics export Google Sheets
211+
// DESCRIPTION: use_function_comment
212+
// API_METHOD: youtubeanalytics.reports.query
213+
/**
214+
* This function uses the YouTube Analytics API to fetch data about our channel, creating
215+
* a new Google Sheet in our Drive with the data.
216+
*
217+
* The first part of this sample demonstrates a simple YouTube Analytics API call. This function
218+
* first fetches the active user's channel ID. Using this channel ID, the function makes an
219+
* analytics API call to retrieve view, likes, dislike and share data for the last 30 days. This
220+
* is returned in a response object containing a 2D array.
221+
*
222+
* The second part of the sample constructs a Spreadsheet. This spreadsheet is placed in the active
223+
* user's Google Drive with the name 'YouTube Report' and date range in the title. The function
224+
* populates the spreadsheet with the API response, then locks columns and rows that will define
225+
* a chart axes. A stacked column chart is added for the spreadsheet.
226+
*/
227+
function spreadsheetAnalytics() {
228+
// Get the channel ID
229+
var myChannels = YouTube.Channels.list('id', {mine: true});
230+
var channel = myChannels.items[0];
231+
var channelId = channel.id;
232+
233+
// Set the dates for our report
234+
var today = new Date();
235+
var oneMonthAgo = new Date();
236+
oneMonthAgo.setMonth(today.getMonth() - 1);
237+
var todayFormatted = Utilities.formatDate(today, 'UTC', 'yyyy-MM-dd')
238+
var oneMonthAgoFormatted = Utilities.formatDate(oneMonthAgo, 'UTC', 'yyyy-MM-dd');
239+
240+
// The YouTubeAnalytics.Reports.query() function has four required parameters and one optional
241+
// parameter. The first parameter identifies the channel or content owner for which you are
242+
// retrieving data. The second and third parameters specify the start and end dates for the
243+
// report, respectively. The fourth parameter identifies the metrics that you are retrieving.
244+
// The fifth parameter is an object that contains any additional optional parameters
245+
// (dimensions, filters, sort, etc.) that you want to set.
246+
var analyticsResponse = YouTubeAnalytics.Reports.query(
247+
'channel==' + channelId,
248+
oneMonthAgoFormatted,
249+
todayFormatted,
250+
'views,likes,dislikes,shares',
251+
{
252+
dimensions: 'day',
253+
sort: '-day'
254+
});
255+
256+
// Create a new Spreadsheet with rows and columns corresponding to our dates
257+
var ssName = 'YouTube channel report ' + oneMonthAgoFormatted + ' - ' + todayFormatted;
258+
var numRows = analyticsResponse.rows.length;
259+
var numCols = analyticsResponse.columnHeaders.length;
260+
261+
// Add an extra row for column headers
262+
var ssNew = SpreadsheetApp.create(ssName, numRows + 1, numCols);
263+
264+
// Get the first sheet
265+
var sheet = ssNew.getSheets()[0];
266+
267+
// Get the range for the title columns
268+
// Remember, spreadsheets are 1-indexed, whereas arrays are 0-indexed
269+
var headersRange = sheet.getRange(1, 1, 1, numCols);
270+
var headers = [];
271+
272+
// These column headers will correspond with the metrics requested
273+
// in the initial call: views, likes, dislikes, shares
274+
for(var i in analyticsResponse.columnHeaders) {
275+
var columnHeader = analyticsResponse.columnHeaders[i];
276+
var columnName = columnHeader.name;
277+
headers[i] = columnName;
278+
}
279+
// This takes a 2 dimensional array
280+
headersRange.setValues([headers]);
281+
282+
// Bold and freeze the column names
283+
headersRange.setFontWeight('bold');
284+
sheet.setFrozenRows(1);
285+
286+
// Get the data range and set the values
287+
var dataRange = sheet.getRange(2, 1, numRows, numCols);
288+
dataRange.setValues(analyticsResponse.rows);
289+
290+
// Bold and freeze the dates
291+
var dateHeaders = sheet.getRange(1, 1, numRows, 1);
292+
dateHeaders.setFontWeight('bold');
293+
sheet.setFrozenColumns(1);
294+
295+
// Include the headers in our range. The headers are used
296+
// to label the axes
297+
var range = sheet.getRange(1, 1, numRows, numCols);
298+
var chart = sheet.newChart()
299+
.asColumnChart()
300+
.setStacked()
301+
.addRange(range)
302+
.setPosition(4, 2, 10, 10)
303+
.build();
304+
sheet.insertChart(chart);
305+
306+
}
307+
/** END SECTION spreadsheetAnalytics **/

0 commit comments

Comments
 (0)