BUG downloading cloud recordings with access token set results in an invalid response

Thanks @zoom-test, we will post here when this feature is available.

If you ever miss a webhook event, you can use the GET /users/{userId}/recordings or GET /meetings/{meetingId}/recordings to get them, then use the JWT token to download as mentioned above.

Thanks,
Tommy

Tommy,

Thanks for all the replies. Unfortunately I can’t use a JWT app because the app needs to be used by multiple accounts/customers, not just my own account so that solution does not work for my scenario since JWT apps are not publishable on the marketplace.

What is your route to filling this hole for OAuth app developers?

  • Add the download_token to those api responses? ( GET /users/{userId}/recordings or GET /meetings/{meetingId}/recordings) They are authenticated requests and would seem to be trustworthy.
  • Allow us to download the files by including a valid OAuth token in the Authorization header as part of the download request?
  • Or something else?

Hey @zoom-test,

We are working on allowing OAuth apps to be able to download private and password protected recordings. (Jira: DEVELOPERS-286)

In the meantime, to download recordings via OAuth, the recordings need to not be set to private or password protected.

User Level Settings:

Account Level Settings: (can override user level to ensure recordings can be downloaded for all OAuth users)

Thanks,
Tommy

1 Like

Hey @tommy,

Is there any update on this Jira ticket? (Jira: DEVELOPERS-286)

Thanks!

Hey @zoom-test,

Our goal is to release this in our next release cycle in March.

Updated: ZOOM-111314

Thanks for your patience,
Tommy

Any update on this @tommy ?

Hey @stephen.tallamy,

Unfortunately this release has been delayed.

Thanks,
Tommy

Hey @tommy,

Sorry to bother, do you know when can we expect this release ?

Thank you.

Hey @tommy,

Sorry to bother, do you know when can we expect this release ?

Thank you.
[/quote]

Hey @das, @baohanhai,

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

Thanks,
Tommy

1 Like

Woah I just came across this.

I’ve been working on an integration and now find that it won’t work because the Zoom API is broken, and is taking a year and a half to fix? This is pretty extreme IMO. Can we please have a manager chime in here, to re-assess the urgency of this bug?

The bug is obviously much more problematic now that all meetings are password-protected by default.

At least thank you @tommy for the tip that this can be worked around with a user setting. However, it’s worth noting that 1) This workaround is a security nightmare (undermining the recent change to require password protection, and 2) It doesn’t work for previous recordings. Users are likely to enable this setting only after a download fails, so it won’t help for the task they were looking to actually accomplish

In the meantime, I can think of two possible dirty workarounds:

  1. If we know the meeting/recording password, is it possible to add that as a URL param? e.g., http://zoomdownloadurl?password=fq4oijf!!ef
  2. If not, we can use the API to remove the password, download the video, and then re-add the password. Only problem with this is that we need to also request the scope “recordings:write”. You’re shit out of luck if you’ve already got users and they don’t have this scope.

Here’s JS example code for workaround number 2. I’ve tested it and it works. But you need the scope “recording:write”

const axios = require('axios');

(async () => {
  try {
    const meetingUuid = YOUR_MEETING_ID;
    const meetingUuidEncoded = encodeURIComponent(encodeURIComponent(meetingUuid));
    const jwt = OAUTH_JWT;

    // Get meeting password
    const meetingPassword = (await axios.get(`https://api.zoom.us/v2/meetings/${meetingUuidEncoded}/recordings/settings?access_token=${jwt}`)).data.password;

    // Remove meeting password
    await axios.patch(`https://api.zoom.us/v2/meetings/${meetingUuidEncoded}/recordings/settings?access_token=${jwt}`, { password: '' });

    // Download recording
    const recording = (await axios.get(DOWNLOAD_URL)).data;

    // Add meeting password back
    await axios.patch(`https://api.zoom.us/v2/meetings/${meetingUuidEncoded}/recordings/settings?access_token=${jwt}`, { password: meetingPassword });
  }
  catch (err) {
    console.error(err);
  }
})();

So gross haha. Note that there may be other restrictions on your user’s meeting recordings, so you might have to patch more than just the password (e.g., expiry), but I’ve kept the example short for demonstration purposes.

Hey @james2,

In the release this weekend, you will now be able to download password protected cloud recordings with OAuth apps. :slight_smile:

Thanks,
Tommy

3 Likes

That’s a big turnaround! Thanks for listening - glad Zoom upped the priority of this bug.

I’m interested to see that you still need the “recording.write” scope in order to download a password protected recording. That’s a bit odd, isn’t it, to need to “write” to the recording just to download? Funnily enough, it’s actually the same scope needed for my workaround above - is the new zoom update doing a similar thing under the hood?

I finally submitted our Zoom Marketplace Oauth app for my startup Videohop just yesterday, and had to include the “recording.write” scope for the workaround. Interesting to see that I will still need it even after the bug is fixed.

Thanks again for the quick communication, Tommy

1 Like

Really glad to see you are shipping this soon. One question:

Do we need all three of those scopes to be able to download or a least one of them?

Hey @zoom-test, @james2,

You just need one of those listed scopes. :slight_smile:

CC @Michael_Purnell can you update the docs to say one of these scopes.

Apologies again for the delays for this feature, but I am glad we were able to fit it in during our 90 day plan.

Thanks,
Tommy

Has this been included in the documentation yet? Looking for an example.

I’m getting a Forbidden error when authenticating using the Bearer authentication header.

Hey @JoshSTL,

Can you try adding it just as a query param:

download_url?access_token=OAUTH_ACCESS_TOKEN_HERE

Thanks,
Tommy

@tommy

Thanks for the reply!

I tried this method using curl, wget and just putting the url directly into a browser address bar. All fail with various messages returned:

wget:

HTTP request sent, awaiting response… 401

Username/Password Authentication Failed.

curl:

{“status”:false,“errorCode”:401,“errorMessage”:“Forbidden”}

I tried also including http authentication and a bearer token header, neither worked. The token is not expired as I can use it for other calls.