Additional Response Details Proposal
This is not a bug but an RFC.
Problem
There are strict rate limits for several actions. For example, meeting write operations are limited to 100 requests per day per user. The Zoom API contains response headers which let the caller know how many requests remain. This information is helpful and should be available via the Zoom gem.
Example Session
Observe what happens when a meeting update rate limit is exceeded:
> for i in {1..101}; do curl -i --request PATCH --header "authorization: Bearer $JWT" --header 'content-type: application/json' --url "https://api.zoom.us/v2/meetings/$meeting_id" -d "{ \"topic\": \"my update $i\" }"; done
HTTP/2 204
date: Tue, 26 Oct 2021 02:27:48 GMT
x-zm-trackingid: v=2.0;clid=us02;rid=WEB_596ca498838a64cf86185261bcfc5a63
x-content-type-options: nosniff
cache-control: no-cache, no-store, must-revalidate, no-transform
pragma: no-cache
expires: Thu, 01 Jan 1970 00:00:00 GMT
set-cookie: zm_aid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_haid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_tmaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_htmaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: cred=7FEE3662BDDDBE392A2ADB57E4E3E68E; Path=/; Secure; HttpOnly
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
x-ratelimit-category: Light
x-ratelimit-limit: 100
x-ratelimit-remaining: 99
set-cookie: _zm_ctaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: _zm_chtaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
x-zm-zoneid: VA
strict-transport-security: max-age=31536000; includeSubDomains
x-xss-protection: 1; mode=block
referrer-policy: strict-origin-when-cross-origin
And so on until the final two iterations. Observe the x-ratelimit-remaining response header count down:
HTTP/2 204
date: Tue, 26 Oct 2021 02:27:48 GMT
x-zm-trackingid: v=2.0;clid=us02;rid=WEB_0102974fa9c8da2687b2375d1a77d1d1
x-content-type-options: nosniff
cache-control: no-cache, no-store, must-revalidate, no-transform
pragma: no-cache
expires: Thu, 01 Jan 1970 00:00:00 GMT
set-cookie: zm_aid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_haid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_tmaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_htmaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: cred=878CE20C3062E7F4E0A24D4370A08C30; Path=/; Secure; HttpOnly
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
x-ratelimit-category: Light
x-ratelimit-limit: 100
x-ratelimit-remaining: 0
set-cookie: _zm_ctaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: _zm_chtaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
x-zm-zoneid: VA
retry-after: 2021-10-27T00:00:00Z
strict-transport-security: max-age=31536000; includeSubDomains
x-xss-protection: 1; mode=block
referrer-policy: strict-origin-when-cross-origin
HTTP/2 429
date: Tue, 26 Oct 2021 02:27:48 GMT
content-type: application/json;charset=UTF-8
content-length: 190
x-zm-trackingid: v=2.0;clid=us02;rid=WEB_0b8fe6a9dd55d7955bd1dab3d1db8251
x-content-type-options: nosniff
cache-control: no-cache, no-store, must-revalidate, no-transform
pragma: no-cache
expires: Thu, 01 Jan 1970 00:00:00 GMT
set-cookie: zm_aid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_haid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_tmaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: zm_htmaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: cred=F53584C4704E4CBE7A3D77AABAB94027; Path=/; Secure; HttpOnly
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
x-ratelimit-category: Light
x-ratelimit-limit: 100
x-ratelimit-remaining: 0
set-cookie: _zm_ctaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: _zm_chtaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
x-zm-zoneid: VA
x-ratelimit-type: Daily-limit
retry-after: 2021-10-27T00:00:00Z
set-cookie: _zm_ctaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
set-cookie: _zm_chtaid=""; Domain=.zoom.us; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly
{"code":429,"message":"You have exceeded the daily rate limit (100) of Meeting Create/Update API requests permitted for this particular user. You may resume these requests at GMT 00:00:00."}
Proposal
Currently, responses from this gem are instances of Hash containing the parsed JSON of the HTTP response body from Zoom or integers of the HTTP response code if the body is empty. If configured to do so, a new Zoom::Response object could be returned instead. This will contain three rate limit informational methods: ratelimit_category, ratelimit_limit, and ratelimit_remaining. These will return values corresponding to the response headers. Here is an example usage:
Zoom.configure do |c|
c.api_key = 'my_key'
c.api_secret = 'my_secret'
c.object_responses = true # new option
end
meeting_id = 88888888888
client = Zoom.new
response = client.meeting_update(meeting_id: meeting_id, topic: 'my update')
response.code # 204
response.body # nil or the empty string (open to suggestion here)
response.ratelimit_category # 'Light'
response.ratelimit_limit # 100
response.ratelimit_remaining # 99
response2 = client.meeting_get(meeting_id: meeting_id)
response2.code # 200
response2.body # {"uuid"=>"dfasdfasdfasfdsdf=", "id"=>88888888888, "host_id"=>""232easdfh203, ... }
response2.ratelimit_category # 'Light'
response2.ratelimit_limit # 999999999
response2.ratelimit_remaining # 999999998
This does require an optional new response class while maintaining backward compatibility for more simplistic clients who just want the body or response code. The new response class also opens up new possibilities for features such as enhanced error information like including the HTTP response code (see #388).
I am very interested in feedback on this proposal. Additionally, I am interested submitting a pull request to add such functionality.
Additional Response Details Proposal
This is not a bug but an RFC.
Problem
There are strict rate limits for several actions. For example, meeting write operations are limited to 100 requests per day per user. The Zoom API contains response headers which let the caller know how many requests remain. This information is helpful and should be available via the Zoom gem.
Example Session
Observe what happens when a meeting update rate limit is exceeded:
And so on until the final two iterations. Observe the
x-ratelimit-remainingresponse header count down:Proposal
Currently, responses from this gem are instances of Hash containing the parsed JSON of the HTTP response body from Zoom or integers of the HTTP response code if the body is empty. If configured to do so, a new
Zoom::Responseobject could be returned instead. This will contain three rate limit informational methods:ratelimit_category,ratelimit_limit, andratelimit_remaining. These will return values corresponding to the response headers. Here is an example usage:This does require an optional new response class while maintaining backward compatibility for more simplistic clients who just want the body or response code. The new response class also opens up new possibilities for features such as enhanced error information like including the HTTP response code (see #388).
I am very interested in feedback on this proposal. Additionally, I am interested submitting a pull request to add such functionality.