Import Call Log Data from Ring Central with PHP
Using the RingCentral API, I wanted to import all data from the “Call Logs” into my own database.
I previously wrote about how to initially connect to Ring Central’s API with PHP, found here.
The Problem
Ring Central’s Call Log API will show you- at most- 1,000 rows “per page.” Otherwise you’ll need to read data in the “next page.”
My original idea was to set a counter and loop until I get the total number of entries for the dataset. Unfortunately Ring Central pagination won’t tell you how many rows there are!
The API documentation indicates that that for paging >> totalElements
The total number of elements in a dataset. May be omitted for some resource due to performance reasons
“May be omitted?” Ugh, we can’t rely on that! In my testing, it was never included.
The Solution
In the data returned, there’s an object for navigation >> nextPage.
I took the route of checking “is there a next page?”
I decided to loop through the data and continue on until the nextPage did not have a value.
How much time do you need?
There’s only so much data you can import in at once without getting a “timeout” error:
PHP Fatal error: Maximum execution time of 30 seconds exceeded
I therefore chose to import in 1 day at a time. But even to do this, I had to increase the time limit via:
set_time_limit(300);
Of course, you’ll have to experiment to see if 5 minutes (300 seconds, above) is enough time for one batch of data. The default of 30 seconds was not enough for me.
Also, Ring Central limits you on the amount of data/API calls you can make before giving you an error/warning. Keep this in mind for the interval that a cron job should run (for example: maybe once every 10 minutes instead of every 1 minute).
Date Format
When passing data into the Ring Central API, you need to specify the dates in a specific format: there must be a T to separate the date and the time and have it end with a Z. For example, December 1, 2021 at midnight would be:
2021-12-01T00:00:00Z
I wanted to grab one day at a time. For the dateFrom I can simply not specify a time (hours/minutes), to have it defaulted at midnight. I wanted to end at 11:59PM, so I used this code:
$dateFrom = '2021-08-07';
$dateTo = $dateFrom . ' 23:59:59';$dateFrom = date('Y-m-d\TH:i:s\Z', strtotime($dateFrom));
$dateTo = date('Y-m-d\TH:i:s\Z', strtotime($dateTo));
The Problem-Solving Code
Here it is:
Code Explanation
First, a brief explanation of some code omitted:
- Row 3: import a setup/configuration file; including database class and handling session variables.
- Row 7–10: Ring Central API included (using Composer)
Explanation for code that is there:
First, authenticate the user
This particular example is using the “3-legged authorization flow” so you can detect who is logged in. If you were to do this with cron job, you’ll want to use the 2-legged approach. I wrote about the connection differences in my previous article.
- There’s a do/while loop on lines 103–120. After setting the initial variables (date range of a single day, default of 1 page), I call the Ring Central API. The endpoint is specified on line 98, and the function it calls is in 24–33.
- The foreach loop on row 108 imports data into my database, using a custom-made function (defined on line 36).
- Then I check the “navigation” element in the object that was returned. If there is indeed a “nextPage” then it will continue on (the variable hasNextPage is set to true; and that’s the value that is checked on row 120).
I left some things in there that were commented-out for debugging purposes.
Validation
I found a day that had less than 1,000 entries (the maximum it would output). I ran this script, showing “all” data, to find out how many rows there should be on a specific day.
Then I was able to run my script, experimenting with the perPage variable and printing out “what the next page would be”.