Best way to download recording_files programmatically

Description
I am building an app that will allow customers to connect their zoom account to my service. My service will import their recording transcripts and do some machine learning on them. I’m trying to figure out the best way to provide this. I’m specifically struggling with auth right now.

Option 1: JWT App

If a cloud recording is not set to public, then the only way I can download the files programmatically is to use JWT auth (I think). However, I can’t get JWT auth to work. I am getting the JWT from the App Marketplace for my JWT app. I set it to be good for 1 week and I generated it today so it should be valid for sure. Then from the API documentation page for getaccountcloudrecording I am using the easy form on the page to test the request. I enter the JWT token where it asks for the oauth token. For the account ID I am entering the “Account No.” which I am retrieving from zoom.us/profile. Result is 401 status with body {“code”: 124, “message”: “Invalid access token.”}.

So first I need to figure out what I’m doing wrong with auth. However, even if I can get this to work, it is not ideal because it requires the user sharing their data to have high privileges in zoom and also they have to create their own JWT App and share the JWT with us. Much better would be to use OAuth.

Option 2: OAuth (preferred, but has problems)

With OAuth, I can download recording transcripts just fine for a single user. This is okay, actually preferable, for my use case. However, when my script tries to actually download the VTT or TIMELINE files, I run into an auth problem. OAuth token is insufficient for downloading these files if they are private or password protected. The only way I can get this to work is to set the recording sharing settings to public. Is there any way around this? It seems like the oauth token should be okay because it is for a specific user and I’m only accessing that user’s own recordings. I’m guessing this is a dead end because I’ve read in two places in your docs/forum that this limitation is real.

FYI for this option, this is an OAuth app (obviously). I’m using /v2/users/me/recordings to get recordings. That is working fine. In that response, I grabe the recording_files that are of type TRANSCRIPT or TIMELINE. From those, I grab the download_url and try to download. With setting bearer token to oauth token, I am rejected. If it set recording to public and omit auth header, it works. But I can’t expect my users to make all their recordings public. :stuck_out_tongue:

Option 3: Any ideas? Any other approaches I am missing?

Join the club! BUG downloading cloud recordings with access token set results in an invalid response

Thanks @matt. Your post covers ALL the issues I’m facing so I’ll hop on board!

Hey @dustin-mcquay / @dmcquay, thanks for posting and using Zoom!

Option 1:

Please share your request URL you are using to download the recording so I can debug.

Option 2:

We are working to make OAuth access_tokens work with downloading all private and password protected recording files.

Option 3:

(@matt check this out)

There is another way! :slight_smile: The Recording Completed webhook for a User Level OAuth app includes a download token which you can use to download the recording programmatically.

Let me know if you have any luck with option 3.

Thanks,
Tommy

Hi @tommy the link I posted already mentioned the download token. #3 is what we use, but as demonstrated by Webhook events stopped suddenly and `recording.*` events not being sent, the zoom developer platform sometimes stops sending for large periods of time, which is still not communicated on status.zoom.us.

This means that if oauth apps miss the webhook for any reason and the recording is password protected. That recording is inaccessible to the app.

Hey @matt,

We are working to have the status page finished in Q2 and accessing the recordings with an OAuth access_token in March.

We appreciate all the feedback you have given to help improve the Zoom Developer Platform ! :slight_smile:

Thanks,
Tommy

Thanks all. Regarding option 1, I was doing something wrong and figured it out.
I’m greatly looking forward to using option 2 (OAuth) in March!

I am aware of Option 3, but my primary use case right now is backfill, plus async comms generally need to ability to heal missed records anyway so I agree with @matt that webhook only is really not a suitable solution.

Thanks all!

Hey @dmcquay,

Happy to hear you figured out Option 1! :slight_smile:

Thanks for the feedback,
-Tommy

@tommy

This is still on track for March, right?

Do we have a read on what the new behavior will be? Will we need to just add the OAuth token as a bearer authentication token header as in how the rest of the api is interacted with?

Yes, and yes @zoom-test!

-Tommy

1 Like

Was this shipped with the March 2nd API update?

Hey @zoom-test,

This will be included in the March 22nd release.

Thanks,
Tommy

1 Like

I did some testing on this now and it looks like if we add the bearer token now, before release then we get a nice little error:

{
    "status": false,
    "errorCode": 401,
    "errorMessage": "java.lang.IllegalArgumentException: urn:zoom:connect:clientid:REDACTED not support",
    "result": null
}

So I am guessing that if we implement this now then we should have it turned off until the support is released on March 22nd. Is this correct?

1 Like

Hey @zoom-test,

Correct.

Thanks,
Tommy

Did this ship on the 22nd? It no longer gives the illegalArgumentException, but still returns a login page.

Hey @zoom-test,

Our March release has been delayed due to our focus shifting on keeping the platform running smoothly with the huge increase in usage.

We don’t have a new date set in stone, but it will be included in the next release.

Stay updated here: https://marketplace.zoom.us/docs/changelog

Thanks for your patience,
Tommy