FileMaker, ZoomAPI, OAuth2, and JWT

The journey to downloading a link from Zoom using Zoom API's

On a new project recently, I needed to capture information from Zoom phones using their API's. The use case was simple: A client wants to use the Zoom Phone service to record calls and Zoom sessions, and be able to easily download and review either event. This turned out to be more complex than it looked.

Zoom Services

Zoom.us offers a very robust set of meeting solutions, including video meetings, video webinars, conference rooms, phone systems, and business instant messaging,

On the phone side, Zoom offers complete phone service, and the rates and capabilities are very competitive. Features include assignable phone numbers extension, voice mail, audio recording, and much more. A phone call can be started and ended in the cloud, or on a physical internet capable phone sitting on a desk an option, too.

Zoom API's

Zoom offers a suite of API commands for managing not only Zoom sessions, but Zoom rooms, phones, auto receptionist, meetings, IM chats, users, webinars, and a lot more. For developers, there is more good news: the API suite can be easily loaded into PostMan from a Github repository. And details for setting it up, including importing the Zoom API collection, are available via this Medium article, which I highly recommend that you read. The process is not intuitive nor straight forward.

The Zoom API

Zoom actually offers two methods of connecting with the API:

  • OAuth2
  • Jason Web Tokens (JWT)

Let's start with OAuth2. The first thing to understand for FileMaker developers is that OAuth2 is not used in the context of controlling user login to an FM database. For a great explanation of using OAuth for login, see this post from last week. Instead, Zoom uses OAuth2 to authorize access to data via the Zoom API, using Access tokens, Refresh tokens, Roles, and Grants. The process for setting that up and making it work in FileMaker is difficult...difficult enough that I spent hours on Zoom sessions with Zoom support, and finally found a solution using JWT (the other method) with help from the robust Zoom Developer Forum.

JWT. JWT turned out to be the best solution for my needs. This information from the Zoom API web page explains why JWT was a better fit for this project:

If your app is meant to be used only by yourself or by users that are in your Zoom account, it is recommended that you use JWT for authentication. To do this, register a JWT app in the Zoom App Marketplace. Use the token generated from the JWT app and start making API requests to the Zoom APIs. To learn more about JWT, read the JWT with Zoom guide, followed by the Quickstart - JWT tutorial.

JSON Web Token (JWT) offer a method to generate tokens that provide secure data transmission using a neat and compact JSON object. JWTs contain signed payload that helps establish server to server authentication.

Sample JWT using Insert from URL (cURL)

Once you have a JWT Token, use FileMaker's Insert from URL to make your connection to the Zoom API. I saved the results from all commands (the target) to a variable ($$Result) and reset the variable after each use. In case you are wondering, I often use global variables when developing or troubleshooting. I find it easer to proceed if I can access the data after the script is run. I usually change it to a local variable before going live.

Remember, my goal is to grab a link to users recording right after the zoom session is started. Zoom makes that link right away, but I need the Zoom user ID before I can grab that link.

To get a list of the user id's, use the "Get phone/users" function: https://api.zoom.us/v2/phone/users. Using the Insert from URL command, place the following command in the "Specify URL" option (there is no need to specify any settings for "Verify SSL Certificate nor Specify cURL Options):

"https://api.zoom.us/v2/users?access_token={JWT_TOKEN_HERE}&status=active&page_size=30&page_number=1"

$$Result contains a JSON object with a list of all users:

{
	"page_count" : 1,
	"page_number" : 1,
	"page_size" : 30,
	"total_records" : 2,
	"users" : 
	[
		{
			"created_at" : "2019-12-19T00:59:00Z",
			"email" : "[email protected]",
			"first_name" : "Robert",
			"id" : "PnldjmFVTDasu8",
			"language" : "en-US",
			"last_login_time" : "2020-01-06T23:06:21Z",
			"last_name" : "Kwasny",
			"phone_number" : "",
			"pmi" : 5055053333,
			"status" : "active",
			"timezone" : "America/Los_Angeles",
			"type" : 2,
			"verified" : 1
		},
		{
			"created_at" : "2019-12-23T18:27:18Z",
			"dept" : "",
			"email" : "[email protected]",
			"first_name" : "Donald",
			"id" : "KHdoZ_MKT8DtgWsd",
			"language" : "en-US",
			"last_client_version" : "4.6.13603.1201(ipad)",
			"last_login_time" : "2020-01-13T18:47:45Z",
			"last_name" : "Clark",
			"pmi" : 5055051112,
			"status" : "active",
			"timezone" : "America/Denver",
			"type" : 2,
			"verified" : 1
		}
	]
}

Use FileMaker JSON commands to grab the user id – "id" : "KHdoZ_MKT8DtgWsd" – for the next step.

Get the Recording ID from a List

Next, get a list of all the recordings for the user using the "Get /phone/users/[userId/recordings" command:

https://api.zoom.us/v2/phone/users/KHdoZ_MKT8DtgWsd/recordings?access_token={JWT_TOKEN_HERE}

The resulting JSON object will look like this:

{
	"page_count" : 1,
	"page_number" : 1,
	"page_size" : 30,
	"recordings" : 
	[
		{
			"callee_name" : "15059080000,
			"callee_number" : "15059080899",
			"callee_number_type" : 1,
			"caller_name" : "Donald Clark",
			"caller_number" : "xxx",
			"caller_number_type" : 1,
			"date_time" : "2019-12-30T18:05:51Z",
			"direction" : "outbound",
			"download_url" : "https://zoom.us/v2/phone/recording/download/VoLP_7WBTFml2aW7yWf",
			"duration" : 919,
			"id" : "28302f6c2b3111e"
		}
	],
	"total_records" : 1
}

Use JSON commands to the "download_url" value from the JSON object for the next (and last) step: downloading the actual recording to your download folder. This step is a bit different: We'll use FileMaker WebViewer to do the actual download. There is no need to display the WebViewer to the user. Instead, simply updating the WebViewer with the new, current information will cause the file to be downloaded. The content of the WebViewer looks like this:

"https://zoom.us/v2/phone/recording/download/VoLP_7WBTFml2aW7yWwhGw/{JWT_TOKEN_HERE}"

I had to write a script to force a refresh of the WebViewer in order to force a download each time it was displayed. Here is the code that worked:

Other things

You'll want to do some things to automate a this process, like storing the token and the download in a variable, preference table, or a field. I find it makes for a more easily readable post to use the data instead of variables, fields, and the like.


Quote of the Day

If stupidity got us into this mess, then why can't it get us out?

Will Rodgers
Thanks! You've already liked this
Need FileMaker Development Help? Or to purchase FileMaker Software?
Contact FM Pro Gurus for help