Tuesday, 2 February 2021

Create a Zoom meeting via the API

The following blog post is a continuation from the connecting to the Zoom API via OAuth one here (please familiarise yourself with it before proceeding). In addition to this post for getting your Zoom meeting settings via the API.

We have already demonstrated successfully getting an Access Token for authentication from Zoom OAuth and then getting our Zoom meeting settings. Now that we have those items we can go ahead and create a Zoom meeting, as we will do here. You may find this page on creating a meeting via the API useful.

Zoom meeting details in a Google Sheet
Zoom meeting details in a Google Sheet

Again we have a Google Sheet with the Apps Script linked to it. We have various details of the meeting that can be entered into the Sheet as well as some of the meeting settings we captured in the last blog post. The Apps Script is configured to pick-up these individual pieces of information to help show how they are being used.

One of the more difficult pieces of information to handle is the start date/time which needs to be formatted as ISO 8601 Extended format: yyyy-mm-ddThh:mm:ss.000

// get and format the Start date/time
var startDate_Time = ss.getRange(4, 2).getValue();
var startDate = new Date(startDate_Time);
var startHour = startDate.getUTCHours();
var startMin = startDate.getUTCMinutes();
var formattedStartDate = Utilities.formatDate(startDate, timeZone, "yyyy-MM-dd");
// recombine above parts to created suitably formatted date
var startTime = formattedStartDate + 'T' + startHour + ':' + startMin + ':' + '00' + '.000';

Where boolean values are required ('true', 'false') we need to convert them from text on the Google Sheet:

// get the Host video setting and convert to Boolean
var hostVideo = ss.getRange(7, 2).getValue();
if (hostVideo == "True") {
  hostVideo = true;
}
else {
  hostVideo = false;
}

Next we combine all of the values into a payload for the API:

var payload = {
 "topic": topic,
 "type": 2,
 "start_time": startTime,
 "timezone": timeZone,
 "duration": duration,
 "agenda": agenda,
 "password": password,
 "settings": {
    "host_video": hostVideo,
    "participant_video": participantsVideo,
    "join_before_host": beforeHost,
    "mute_upon_entry": entryMute,
    "waiting_room": waitingRoom
 }
};

We can then set the HTTP headers and include the Access Token as we get ready to make the API call:

// set the HTTP headers and include the Access Token for authentication
var options = {
  'method': "post",
  'contentType': "application/json",
  'headers': {
    "Authorization": "Bearer " + accessToken
    },
  'payload': JSON.stringify(payload)
};

Now we can make the call to the User Meetings API as specified by the Zoom documentation:

// make Zoom API call
var response = UrlFetchApp.fetch("https://api.zoom.us/v2/users/me/meetings", options);

Lots of information is returned so this script both puts all of that into the Google Sheet so you can see what details are available for accessing and specifically extracts the meeting ID and join URL:

// gather data from response
var resultText = response.getContentText();
var resultObj = JSON.parse(resultText);


// specifically get meeting ID and join URL
var meetingID = resultObj['id'];
saveIntoSheet(joinURL, 14);


File Download

Download the Create a Zoom meeting via the API here. Please use 'File' > 'Make a copy' for your own version. This is a Google Sheet with the Apps Script bound to it. You will need to deploy it as a Web App and create your own Zoom OAuth App.

 

/*
Function to connect to Zoom API via OAuth.
*/
function doGet(e) {
// get authorisation code from returned Url
var authCode = JSON.stringify(e.parameter.code);
// remove quotes around the code
var authCodeClean = authCode.replace(/['"]+/g, '');
// run Function to add to Spreadsheet
saveIntoSheet(authCodeClean, 1)
// run Function to get Token from AuthCode
var accessToken = getToken(authCodeClean);
// check status of Access Token and run subsequent Function
if (accessToken) {
// run Function to create a Zoom meeting via the API
createZoomMeeting(accessToken);
// return message to webpage to inform user
return HtmlService.createHtmlOutput('Success! You can close this tab.');
}
else {
// there was a problem getting Authentication Code
// return message to webpage to inform user
return HtmlService.createHtmlOutput('Failed. You can close this tab');
}
}
// use Authorisation Code to get a Token
function getToken(authCodeClean) {
// set authentication and get OAuthKeys
var clientID = "ENTER YOUR APP ID HERE";
var clientSecret = "ENTER YOUR APP SECRET HERE";
var encodedKeys = Utilities.base64Encode(clientID + ":" + clientSecret);
// set the HTTP headers
var options = {
'method': "post",
'headers': {"Authorization": "Basic " + encodedKeys},
};
// Web App URL linked to Zoom OAuth App
var returnUrl = "ENTER YOUR WEB APP URL HERE";
// make Zoom OAuth call
var response = UrlFetchApp.fetch("https://zoom.us/oauth/token?grant_type=authorization_code&code=" + authCodeClean + "&redirect_uri=" + returnUrl, options);
// run Function to add Access Token to Spreadsheet
var resultText = response.getContentText();
var resultObj = JSON.parse(resultText);
var accessToken = resultObj['access_token'];
saveIntoSheet(accessToken, 2);
// return the Access Token value to the Parent Function
return accessToken;
}
// Function to copy values into the Google Sheet.
function saveIntoSheet(value, row) {
var ss = SpreadsheetApp.getActiveSheet();
var cell = ss.getRange(row, 2);
cell.setValue(value);
return;
}
/*
Function to create a Zoom meeting via the API, using values
from the Google Sheet.
*/
function createZoomMeeting(accessToken) {
// get the Google Sheet so we can then get the values from it
var ss = SpreadsheetApp.getActiveSheet();
// get the Topic
var topic = ss.getRange(3, 2).getValue();
// get the TimeZone
var timeZone = SpreadsheetApp.getActiveSpreadsheet().getSpreadsheetTimeZone();
// get and format the Start date/time
var startDate_Time = ss.getRange(4, 2).getValue();
var startDate = new Date(startDate_Time);
var startHour = startDate.getUTCHours();
var startMin = startDate.getUTCMinutes();
var formattedStartDate = Utilities.formatDate(startDate, timeZone, "yyyy-MM-dd");
// recombine above parts to created suitably formatted date
var startTime = formattedStartDate + 'T' + startHour + ':' + startMin + ':' + '00' + '.000';
// get the Duration
var duration = ss.getRange(5, 2).getValue();
// get the Agenda (Description)
var agenda = ss.getRange(6, 2).getValue();
// generate a random string to use for password
var uniqueValue = Utilities.getUuid();
var password = uniqueValue.slice(0, 8); // get first 8 characters
// get the Host video setting and convert to Boolean
var hostVideo = ss.getRange(7, 2).getValue();
if (hostVideo == "True") {
hostVideo = true;
}
else {
hostVideo = false;
}
// get the Participants video setting and convert to Boolean
var participantsVideo = ss.getRange(8, 2).getValue();
if (participantsVideo == "True") {
participantsVideo = true;
}
else {
participantsVideo = false;
}
// get the Join before host setting and convert to Boolean
var beforeHost = ss.getRange(9, 2).getValue();
if (beforeHost == "True") {
beforeHost = true;
}
else {
beforeHost = false;
}
// get the Mute upon entry setting and convert to Boolean
var entryMute = ss.getRange(10, 2).getValue();
if (entryMute == "True") {
entryMute = true;
}
else {
entryMute = false;
}
// get the Waiting Room setting and convert to Boolean
var waitingRoom = ss.getRange(11, 2).getValue();
if (waitingRoom == "True") {
waitingRoom = true;
}
else {
waitingRoom = false;
}
// put together the meeting data
var payload = {
"topic": topic,
"type": 2,
"start_time": startTime,
"timezone": timeZone,
"duration": duration,
"agenda": agenda,
"password": password,
"settings": {
"host_video": hostVideo,
"participant_video": participantsVideo,
"join_before_host": beforeHost,
"mute_upon_entry": entryMute,
"waiting_room": waitingRoom
}
};
// set the HTTP headers and include the Access Token for authentication
var options = {
'method': "post",
'contentType': "application/json",
'headers': {
"Authorization": "Bearer " + accessToken
},
'payload': JSON.stringify(payload)
};
// make Zoom API call
var response = UrlFetchApp.fetch("https://api.zoom.us/v2/users/me/meetings", options);
// gather data from response
var resultText = response.getContentText();
var resultObj = JSON.parse(resultText);
// run Function to copy all returned data into Google Sheet
saveIntoSheet(resultObj,12);
// gather some relevant meeting details and log in Google Sheet *****************
var meetingID = resultObj['id'];
saveIntoSheet(meetingID, 13);
var joinURL = resultObj['join_url'];
saveIntoSheet(joinURL, 14);
// gather some relevant meeting details and log in Google Sheet *****************
return;
}

4 comments:

  1. Hello, Mr. Bainbridge.
    Great blog and article.
    I'm new to the apps-script world so thanks in advance and i'll keep going :). just one thing, in the first paragraph the link to the 'connecting to the Zoom API via OAuth one here' leads to blogger.com so after using the search tool i've found the other article. Thanks again. :)

    ReplyDelete
    Replies
    1. Hi

      Thank you for your feedback and for highlighting that broken link - I have now fixed it.

      Kind regards
      Phil

      Delete
  2. Thanks for the examples. I worked thought the last Oauth post, and got it working.

    These scripts are bound a particular sheet. To attach to a new sheet, as I understand it, I would have to copy/paste the code into a new sheet.

    I guess what I want is an add-on that would have access to the sheet (for meeting info) and to Zoom to create the meetings.

    But it's unclear how an add-on could also be deployed as an WebApp to allow for the OAuth flow to complete.

    ReplyDelete
    Replies
    1. Hi Bob

      Glad you got it working.

      Yes these are bound scripts. An alternative is to make a copy of the Google Sheet itself and the Apps Script code will come along with it.

      I have been exploring Add-ons last week but I'm yet to figure a way to overcome the 30 second execution time-out/limit with Functions that use the Card Service. Which means for bulk processes such as this it is not possible.

      Kind regards
      Phil

      Delete