Skip to main content

I am currently using the call log to pull all calls using the extension id:


        for (var extensionId in extensions)
{ var request = (HttpWebRequest)WebRequest.Create("/restapi/v1.0/account/~/extension/" + extensionId + "/call-log");
request.Method = "GET";
request.Headers.Add("Authorization", "Bearer " + AccessToken);
request.Accept = "application/json";
WebResponse response = request.GetResponse();
Stream dataStream = response.GetResponseStream();
//DO STUFF WITH CALLS HERE...
dataStream.Close();
response.Close(); }


However, my client has around 150 extensions (call center). And the above code makes 150 separate api calls, and takes around 45 minutes to run. I want to speed this up by making only one api call. Something like this:


        var request = (HttpWebRequest)WebRequest.Create("/restapi/v1.0/account/~/call-log");
request.Method = "GET";
request.Headers.Add("Authorization", "Bearer " + AccessToken);
request.Accept = "application/json";
WebResponse response = request.GetResponse();
Stream dataStream = response.GetResponseStream(); for (var extensionId in extensions) { //GET CALLS FOR EXTENSION... //DO STUFF WITH CALLS HERE...
}
dataStream.Close();
response.Close();


Obviously I am leaving out some code for parsing the call log into an object. But this is the general idea. My question has to do with the call log structure itself. Is there a way that I can:


  1. Use the call log api to get all calls for an account (without using the extension filter)
  2. Then take all those calls and divide them up by extension

Is that built into the call log structure? Or can I use a combination of direction and from/to?


I do see that there is an extension object returned from the cal log api. But when analyzing the results, I see that sometimes the extension object is present in the main call log entry, and sometimes it is present inside one of the legs. I just want to make sure that if this is the method to get the extension, that it is reliable, and will get me the same results as making the separate api calls (one for each extension). I also need to take into consideration the case when the call has been forwarded to an external number.


One more thing - I found this question, which seems similar to mine. And I don't see that it was ever definitively answered: https://devcommunity.ringcentral.com/ringcentraldev/topics/extension-id-in-call-log

Hi Matt,

Absolutely you can use the company call log API to access the call log for all extension under the account. Make sure you log in with the admin user. And specify the page and perPage parameters. Since you mentioned that it is a large account so there can be a lot of data, so from the response, check the paging for page information to make sure you don't miss any records.

+ Phong
Hi Phong. Thanks for the feedback. My concern is this - in doing some analysis, we found there are some calls that we retrieve when using the extension filter, and the call log entry does not contain that extension we filtered by anywhere in the body of the response. For example, here is a call log entry we retrieved using the extension filter for 244421031:
        {    "id": "Am_P6UKcw8AbTUA",    "uri": "https://platform.ringcentral.com/restapi/v1.0/account/244327031/extension/244428031/call-log/Am_P6UKcw8AbTUA?view=Detailed",    "sessionId": "29458696030",    "type": "Voice",    "direction": "Inbound",    "action": "Phone Call",    "result": "Accepted",    "startTime": "2018-06-01T22:54:43.515Z",    "duration": 84,    "lastModifiedTime": "2018-06-01T22:56:20.061Z",    "transport": "PSTN",    "from": {     "phoneNumber": "+12064094566",     "extensionNumber": null    },    "to": {     "phoneNumber": "+12069815834",     "extensionNumber": null    },    "recording": {     "id": "944281520030",     "uri": "https://platform.ringcentral.com/restapi/v1.0/account/244327031/recording/944281520030",     "type": "Automatic",     "contentUri": "https://media.ringcentral.com/restapi/v1.0/account/244327031/recording/944281520030/content"    },    "message": null,    "billing": {     "costIncluded": "0.000",     "costPurchased": "0.000"    },    "legs": [{     "id": null,     "uri": null,     "sessionId": null,     "type": "Voice",     "direction": "Inbound",     "action": "Phone Call",     "result": "Accepted",     "startTime": "2018-06-01T22:54:43.515Z",     "duration": 84,     "lastModifiedTime": null,     "transport": "PSTN",     "legType": "Accept",     "extension": {      "id": "244428031",      "uri": "https://platform.ringcentral.com/restapi/v1.0/account/244327031/extension/244428031"     },     "from": {      "phoneNumber": "+12064094566",      "extensionNumber": null     },     "to": {      "phoneNumber": "+12069815834",      "extensionNumber": null     },     "recording": {      "id": "944281520030",      "uri": "https://platform.ringcentral.com/restapi/v1.0/account/244327031/recording/944281520030",      "type": "Automatic",      "contentUri": "https://media.ringcentral.com/restapi/v1.0/account/244327031/recording/944281520030/content"     },     "message": null,     "billing": null    }, {     "id": null,     "uri": null,     "sessionId": null,     "type": "Voice",     "direction": "Outbound",     "action": "VoIP Call",     "result": "Accepted",     "startTime": "2018-06-01T22:54:43.528Z",     "duration": 84,     "lastModifiedTime": null,     "transport": "VoIP",     "legType": "PstnToSip",     "extension": {      "id": "244428031",      "uri": "https://platform.ringcentral.com/restapi/v1.0/account/244327031/extension/244428031"     },     "from": {      "phoneNumber": "+12064094566",      "extensionNumber": null      "device": {       "id": "116860031",       "uri": "https://platform.ringcentral.com/restapi/v1.0/account/244327031/device/116860031"      }     },     "to": {      "phoneNumber": "+12069815834",      "extensionNumber": null     },     "recording": {      "id": "944281520030",      "uri": "https://platform.ringcentral.com/restapi/v1.0/account/244327031/recording/944281520030",      "type": "Automatic",      "contentUri": "https://media.ringcentral.com/restapi/v1.0/account/244327031/recording/944281520030/content"     },     "message": null,     "billing": null    }]   }  
As you can see, the extension 244421031 is not listed anywhere in the call log. How am I supposed to attach this call to this extension without using the api with the extension filter?


Hi Phong. Thanks again for the reply. I'm a little confused. According to the documentation, we should be using the extensionId, not the extension number (https://developer.ringcentral.com/api-docs/latest/index.html?_ga=2.209303514.915834205.1528053511-70...). Something like this: 

/restapi/v1.0/account/{accountId}/extension/{extensionId}/call-log

And the problem I'm having is this - in order to obtain the response I posted above, we are using the extension filter like this:

https://platform.ringcentral.com/restapi/v1.0/account/xxxxxx/extension/244428031/call-log?view=Detailed
We are getting the call log for extension 244428031. However, in the response (shown above), that extension is nowhere to be found, even in the multiple legs (detailed view is turned on). So if we switch over to use the company call log, how will I know that this particular call should be attached to extension 244428031?

This is just one example. There are multiple examples of this that we have found.
Hi Phong. Sorry for any confusion. Yes, we are currently using the user call log end-point. But my problem is that in my example, the extension id is not present in the response I get back, even though I am using the user call log end-point for that particular extension id. I see other extension ids in the response, but not the one I am explicitly using in the user call log end-point. And I have found many more examples like this. When we stop using the user call log end-point, there won't be any way for me to attach these calls to the correct extension.
Matt, it really can look complicated, I understand your confusion. Here is what we have in reality.

1. There is a company-level call log. Each call contains multiple legs. And there may be different users owning particular legs. Simplest example is a call from one extension to another. And there may be more than two extensions participating in the same call as well.

2. There is a user-level call log. The same call entry from company call log may look differently if you retrieve it on behalf of different parties. E.g. the same extension-to-extension call can look like inbound or outbound depending on extensionId you specify in URL. 

3. ExtensionId which is returned for a call leg (in detailed view) should more or less correspond to leg owner from system standpoint. There is only one leg which system chooses as a master leg which is returned in company call log: the owner of this leg becomes the owner of the entire call. But master leg is chosen differently when you look at it from user's projection (extension call log). 

4. There may be some buggy situations when leg owner is incorrectly determined or remains empty so you don't see it in API.

I am not sure if I helped you even a bit. But the main point is that your implementation depends on what kind of view you want to replicate in your system. If it is user-centric view of a call log, you will most likely have troubles while trying to construct it from company call log. But if you want to implement your own filtering basing on participating extensions, you may be able to do it by analyzing call legs in detailed view of company call log. Of course if you don't hit something I mentioned in p.4. In this case it is better to explain particular call scenario so we can file a bug and have it fixed. 

Reply