class: middle, center, inverse [
](https://github.com/grokify/ringcentral-slides/tree/master/office/polling-and-syncing)
[
](https://developer.ringcentral.com)
## Polling and Syncing --- layout: false ### About Me * John Wang - aka "[Grokify](https://github.com/grokify)" * Sr. Director of Platform for [RingCentral](https://developer.ringcentral.com/) * Top 50 Contributor (of 950+) to [OpenAPI Generator](https://github.com/openapitools/openapi-generator) * 5,476 [RingCentral Dev Community](https://devcommunity.ringcentral.com/) reputation * 6,845 [Stack Overflow](https://stackoverflow.com/users/1908967/grokify) reputation - Top 0.25% --- ### Agenda * Use Cases * Rate Limiting * Polling * Syncing * Timing --- class: middle, center, inverse # Use Cases --- ### Use Cases 1. Archival * Full backup * On-going 1. Client Apps * Viewing call log or messages in a client app * View recent items * Get new and updated items * Get older items via infinite scroll #### Scope * Call Log - Historical Calls * Message Store - Incoming and Outgoing Messages (voicemail, SMS, fax) --- ### Account Limits * Automatic Call Recordings: 90 days or 100,000 messages * Inbound Voicemail/Fax: 200 messages * Sent Fax: 30 days * Text Messages: 5,000 per folder (Inbox, Outbox, Sent, Deleted) Full knowledgebase article #1894: [Message Storage and Account Data Retention](https://success.ringcentral.com/articles/RC_Knowledge_Article/2178) --- class: middle, center, inverse # Rate Limits --- ### Rate Limit Types 1. Overall App Rate Limit 1. API Rate Limits --- ### Overall App Rate Limit Limit * 20 requests / second / IP address * Cannot be increased Throttled Result * Status Code: 429 * Retry-After: 30 Usage * When receiving 429 HTTP status code, retry the request after the number of seconds specified in the `Retry-After` header. --- ### API Rate Limits 1. Set for app/user pair 1. Set for API groups (`X-Rate-Limit-Group` header) 1. Specified in Developer Portal for your app 1. Contact Dev Support if you need more
--- ### Response Headers * `X-Rate-Limit-Group`: heavy, medium, light, auth * `X-Rate-Limit-Limit`: current rate limit * `X-Rate-Limit-Remaining`: remaining in this window * `X-Rate-Limit-Window`: window size * `Retry-After`: seconds to wait (only with 429) #### Usage 1. When `X-Rate-Limit-Remaining` reaches `0`, wait the number of seconds specified by `X-Rate-Limit-Window`. You should not receive a 429. 1. When receiving 429 HTTP status code, retry the request after the number of seconds specified in the `Retry-After` header. --- ### Increasing API Rate Limits * Sometimes you may need higher limits * Contact Dev Support to discuss your use case #### Dev Support Links * Support Page: https://developer.ringcentral.com/support.html * Create Ticket: https://developer.ringcentral.com/api/support-cases/create * Check Tickets: https://developer.ringcentral.com/api/support-cases/check --- class: middle, center, inverse # Polling --- ### Polling Overview Retrieve all call log or message store items to build paged reports Benefits * Uses common RFC-3339 time filters: `dateFrom` and `dateTo`, e.g. `2018-01-01T00:00:00Z` * Uses common paing approaches: `page` and `perPage` properties --- ### Endpoints [`/restapi/v1.0/account/~/call-log`](https://developer.ringcentral.com/api-docs/latest/index.html#!#RefCompanyCallLog.html) - [try](https://developer.ringcentral.com/api-explorer/latest/index.html#/!/Call_Log/loadAccountCallLog) [`/restapi/v1.0/account/~/extension/~/call-log`](https://developer.ringcentral.com/api-docs/latest/index.html#!#RefUserCallLog.html) - [try](https://developer.ringcentral.com/api-explorer/latest/index.html#/!/Call_Log/loadExtensionCallLog) [`/restapi/v1.0/account/~/extension/~/message-store`](https://developer.ringcentral.com/api-docs/latest/index.html#!#RefMessageList.html) - [try](https://developer.ringcentral.com/api-explorer/latest/index.html#/!/SMS_and_MMS/listMessages) #### Polling query parameters Interval and paging parameters (others filters exist): * `dateTo`: default = now, matches `startTime` or `creationTime` * `dateFrom`: default = `dateTo` - 24 hrs, matches `startTime` * `page`: default = `1` * `perPage`: default = `100`, max = `1000` --- ### Example Response
``` { "uri":"https://platform.ringcentral.com/restapi/v1.0/account/11111111/ \ call-log?view=Simple&showBlocked=true&withRecording=false& \ dateFrom=2018-09-17T10:04:00.000Z&page=1&perPage=1", "records":[ { "uri":"https://platform.ringcentral.com/restapi/v1.0/account/11111111/ \ call-log/BpMupf0GWZPFzUA?view=Simple", "id":"BpMupf0GWZPFzUA", "sessionId":"79486033016", "startTime":"2018-09-18T00:30:21.626Z", ... }, ... ], "paging":{ "page":1, "perPage":500, "pageStart":0, "pageEnd":0 }, "navigation":{ "nextPage":{ "uri":"https://platform.ringcentral.com/restapi/v1.0/account/11111111/ \ call-log?view=Simple&showBlocked=true&withRecording=false& \ dateFrom=2018-09-17T10:04:00.000Z&page=2&perPage=500" }, "firstPage":{ "uri":"..." }, "lastPage":{ "uri":"..." } } } ```
--- ### Considerations - Sizing Pages Medium sized pages return faster than max size. * `perPage` can be up to a maximum of `1000` * Consider sizing smaller, e.g. `200` - `500` for better performance --- ### Considerations - Sizing Intervals High page numbers will return slower Use `dateTo` and `dateFrom` intervals to improve response times * Responses return URLs for: `nextPage`, `previousPage`, `firstPage`, `lastPage` * `message-store`, but not `call-log`, returns `totalPages` --- ### Considerations - Date Overlaps Calls that cross polling date intervals require extra care * `dateFrom` and `dateTo` act on `startTime` * Calls are not entered into `call-log` until just after the call is complete * Calls starting and ending across an interval will not be captured with non-overlapping intervals * Set your `dateFrom` far back enough to capture calls, e.g. 2 hrs if your calls are less than 2 hrs. --- ### Considerations - Updates * Updated messages may not be captured. * If necesssary, may want to pull messages after average time a user updates their messages, e.g. days. --- class: middle, center, inverse # Syncing --- ### Syncing Overview Retrieve all new and updated items since last API retrival using last `syncToken` Benefits * Automatically get all changes * No need to manually handle intervals and paging * No need to manually handle start time overlaps * No need to manually handle updates Usage * Used by RingCentral's own end-user apps * Now recommended for archival as well --- ### Endpoints * [`/restapi/v1.0/account/~/call-log-sync`](https://developer.ringcentral.com/api-docs/latest/index.html#!#RefCompanyCallLogSync.html) - [try](https://developer.ringcentral.com/api-explorer/latest/index.html#/!/Call_Log/syncAccountCallLog) * [`/restapi/v1.0/account/~/extension/~/call-log-sync`](https://developer.ringcentral.com/api-docs/latest/index.html#!#RefUserCallLogSync.html) - [try](https://developer.ringcentral.com/api-explorer/latest/index.html#/!/Call_Log/syncExtensionCallLog) * [`/restapi/v1.0/account/~/extension/~/message-sync`](https://developer.ringcentral.com/api-docs/latest/index.html#!#RefMessageSync.html) - [try](https://developer.ringcentral.com/api-explorer/latest/index.html#/!/SMS_and_MMS/syncMessages) #### Syncing query parameters * `syncType`: Full (`FSync`) or incremental (`ISync`), default to `FSync` * `syncToken`: Used for ISync * `recordCount`*: Max number of records to return \* required --- ### Example Response ``` { "uri":"https://platform.ringcentral.com/restapi/v1.0/account/11111111/ \ extension/22222222/call-log-sync?syncType=FSync&recordCount=2", "records":[ { "uri":"https://platform.ringcentral.com/restapi/v1.0/account/11111111/ \ extension/22222222/call-log/BpMupf0GWZPFzUA?view=Simple", "id":"BpMupf0GWZPFzUA", "sessionId":"79486033016", "startTime":"2018-09-18T00:30:21.626Z", ... }, ... ], "syncInfo":{ "syncType":"FSync", "syncToken":"FAMAAAFM3nowYAQAAAFl7Seg5ggAAAAAK1aeuA0AAAASgbykSA4AAAFM3...", "syncTime":"2018-09-18T14:48:41.958Z" } } ``` --- ### Considerations - Duplicates Syncing will ensure that you never miss a message, but to accomplish this, it may return duplicate messages, e.g. `ISync` may return a message that was in a previous sync. Be sure to de-duplicate messages in your app. --- ### Considerations - New Messages An `ISync` for new and updated messages (with `syncToken` but without `recordCount`) will return up to 250 new messages since your last sync. If there are more than 250 new or updated messages, an error will be returned and a new `FSync` will be required. To avoid this, perform `ISync` quickly enough so that you do not exceed the 250 max number of messages from the last sync. See the Trigging section for info on subscribing to events when new messages arrive. --- ### Considerations - Old Messages To perform a full historical sync, use the following steps: 1. First call `FSync` 1. Then call `ISync` with `syncToken` and `recordCount=250` until `records` property is an empty array: `[]` at which time there will be no more messages. --- class: middle, center, inverse # Timing --- ### When to Run? * Regularly: every 5+ minutes for near real-time * Several times / day: high volume inbound voicemail / fax `message-store` * Daily archival: once a day, often at night Event-based Triggers * Message Store: `message-store` event filter * For SMS, no polling may be necessary as you can get full text in the instant message type * Call Log: Check `presence` event filter can poll `call-log` 30 seconds after call completion * For polling, use date filters to prevent receiving too many duplicates --- ### Best Practices 1. Use the Syncing API 1. Subscribe to relevant `message-store` and `presence` events and perform `ISync` after receiving an event 1. Automatically run an `ISync` if a certain amount of time has elapsed without an event, e.g. 30 minutes. --- class: inverse [
](https://github.com/grokify/ringcentral-polling-and-syncing) ### More Info Presentation https://grokify.github.io/ringcentral-polling-and-syncing/ Blog https://medium.com/ringcentral-developers/use-message-sync-api-to-archive-your-sms-fax-and-voicemail-messages-cd23748e188f Example App https://github.com/embbnux/ringcentral-message-sync-demo --- class: inverse [
](https://github.com/grokify/ringcentral-polling-and-syncing) ### Thank You RingCentral Developers * https://developer.ringcentral.com * https://github.com/ringcentral * https://github.com/ringcentral-tutorials * https://medium.com/ringcentral-developers * https://twitter.com/ringcentraldevs Reach Me * https://twitter.com/grokify * https://github.com/grokify