Search code examples
javascriptjsongoogle-apps-scriptyoutube-data-apigoogle-apps-script-api

Updating the default broadcast's stream title via YouTube API


Using the link below, the title can be easily updated:

https://developers.google.com/youtube/v3/live/docs/liveStreams/update?apix=true.

I wish to implement the same using the YouTube API in Google Apps Script. The code below works successfully, but rather than updating it creates a new stream.

The difference is the link above did not require scheduledStartTime. But the API requires it. And when scheduledStartTime is given, it creates a new broadcast rather than updating the original one. If scheduledStartTime is assigned 1970-01-01T00:00:00Z it acts as if scheduledStartTime is not taken into account.

What value to be assigned so that it updates the default broadcast stream rather than updating one. Or there is there anything else I am missing to complete the update process?

Here is my code:

Logger.log('Starting');
service = getService();
if (service.hasAccess()) {

//Fetch the LiveBroadcast Title and Description Details
var url = "https://www.googleapis.com/youtube/v3/liveBroadcasts?broadcastStatus=upcoming&broadcastType=all";
var parameters = {'headers' : {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + service.getAccessToken()}};

var response = UrlFetchApp.fetch(url,parameters);
var result = JSON.parse(response.getContentText());
//Logger.log(result);
var resource = result.items[0];

//Edit the LiveBroadcast Title and Description Details scheduledStartTime
var title = "as per today";
var description = "new desc check";
var scheduledStartTime ='1970-01-01T00:00:00Z';
var privacyStatus = 'public';
    
//var privacyStatus = 'unlisted';
//var scheduledStartTime = '2020-10-26T04:08:00Z';

data = { 
  'id' : 'MDaEvnSioI', 
  'status' : { 'privacyStatus' : 'public' , 'selfDeclaredMadeForKids' : false},
  'snippet' : { 'title' : title , 'description' : description , 'scheduledStartTime' : scheduledStartTime }
};
    
//Update the LiveBroadcast 
Logger.log("--");
var jsondata = JSON.stringify(data);
Logger.log(jsondata);
    
    
var options =  {
  'headers': {
    'Authorization': 'Bearer ' + service.getAccessToken()        
  },
  'contentType': 'application/json',
  'method' : 'post',
  'payload': jsondata,
  'muteHttpExceptions':true
};

var response = UrlFetchApp.fetch(url2, options);
Logger.log(response.getContentText());
Logger.log('service has access...!!');

Solution

  • If you only what to update a broadcast's title and description properties, then according to the official docs you may simply use the Videos.update API endpoint:

    snippet.title (string)
    The broadcast's title. Note that the broadcast represents exactly one YouTube video. You can set this field by modifying the broadcast resource or by setting the title field of the corresponding video resource.

    snippet.description (string)
    The broadcast's description. As with the title, you can set this field by modifying the broadcast resource or by setting the description field of the corresponding video resource.

    For to achieve that, do modify your code as follows:

    // First step: obtain the video's 'categoryId'
    
    var url = "https://www.googleapis.com/youtube/v3/videos?part=id,snippet&fields=items/snippet/categoryId&id=MDaEvnSioI";
    
    var options = {
      'headers': {
        'Authorization': 'Bearer ' + service.getAccessToken()
      }
    };
    
    var response = UrlFetchApp.fetch(url, options);
    var result = JSON.parse(response.getContentText());
    var categoryId = result.items[0].snippet.categoryId;
    
    // Second step: update the video's 'title' and 'description',
    // using its 'categoryId' obtained above
    
    var url2 = "https://www.googleapis.com/youtube/v3/videos?part=id,snippet";
    
    var data2 = {
      'id': 'MDaEvnSioI',
      'snippet': {
        'title': title,
        'description': description,
        'categoryId': categoryId
      }
    };
    
    var options2 =  {
      'headers': {
        'Authorization': 'Bearer ' + service.getAccessToken()        
      },
      'contentType': 'application/json',
      'payload': JSON.stringify(data2),
      'method': 'put'
    };
    
    var response2 = UrlFetchApp.fetch(url2, options2);
    

    Please note that updating a video's title and description is a two-step process, because, as per the official docs, when invoking the Videos.update endpoint on the video's snippet object, one need to pass that video's categoryId property to the endpoint as well.

    Thus, first query the video's current categoryId property using the Videos.list API endpoint, and only after that invoke Videos.update.

    Also note that the code above is simplified quite much, since it does not handle the errors that may be returned by these API calls.


    For what concerns your issue (quote):

    [...] And when scheduledStartTime is given, it creates a new broadcast rather than updating the original one.

    please acknowledge that calling for the API on the URL:

    https://www.googleapis.com/youtube/v3/liveBroadcasts

    as you do with your code, you're actually invoking the LiveBroadcasts.insert API endpoint instead of the LiveBroadcasts.update, as you actually expect.

    This happens to be so because both these API endpoints have the same URL; the thing that differentiates the two is the HTTP method that invokes each: POST for the former and PUT for the latter.

    Since your second call to UrlFetchApp.fetch does specify explicitly the method to be POST, you're really calling for LiveBroadcasts.insert endpoint and not for LiveBroadcasts.update.