Can I link all calls in the call log to an extension when I use the account level call log API?

  • 1
  • Question
  • Updated 2 months ago
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
Photo of Matt Spinks

Matt Spinks

  • 500 Points 500 badge 2x thumb

Posted 2 months ago

  • 1
Photo of Phong Vu

Phong Vu, Devangelist

  • 2,466 Points 2k badge 2x thumb
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
Photo of Matt Spinks

Matt Spinks

  • 500 Points 500 badge 2x thumb
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?

Photo of Phong Vu

Phong Vu, Devangelist

  • 2,256 Points 2k badge 2x thumb
Saying extension filter, do you mean that you call the company call log and specify the extensionNumber param? If that is the case, the extension number is the user max 6-digit extension number e.g. 101, 102, not the extension internal id.

However, that param seems to be the search argument and a bit confusing to me too. In your case, you can read the whole call log at company level with the view set to Detailed then parse the extension object from the legs array to find the extension id you want to match.
Photo of Matt Spinks

Matt Spinks

  • 500 Points 500 badge 2x thumb
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.
(Edited)
Photo of Phong Vu

Phong Vu, Devangelist

  • 2,256 Points 2k badge 2x thumb
Hi Matt,

In your first message you don't want to access the call log at extension level as you said it takes too long time. And if you want to use that endpoint then yes, it must be the extension id and don't call it an extension id filter because it confuses with the parameters filter.

Anyway, you can call that user call log endpoint with the view set to Detailed and you should see extension object as shown below:
Photo of Matt Spinks

Matt Spinks

  • 500 Points 500 badge 2x thumb
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.
Photo of Phong Vu

Phong Vu, Devangelist

  • 2,256 Points 2k badge 2x thumb
So you still don't see the extension object with the uri and id keys from the response?
Photo of Matt Spinks

Matt Spinks

  • 500 Points 500 badge 2x thumb
I see multiple extension objects in my response. But I do not see the extension object for the user extension endpoint that I am using. In this example, I am using the user call log endpoint for extension 244421031. But in the response the extension 244421031 does not exist, not even in any of the legs.
Photo of Anton Nikitin

Anton Nikitin, Official Rep

  • 2,674 Points 2k badge 2x thumb
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. 
Photo of Matt Spinks

Matt Spinks

  • 500 Points 500 badge 2x thumb
Hi Anton. That actually makes sense. I was wondering how RingCentral determines the "owner" of a call. And the examples that I'm finding where the extension id doesn't match up (such as this example) all seem to be some sort of multi-user calls. Mostly, though, the calls and extensions match up fine. There are just a small percentage of the calls where the extension id does not match up (such as this example). 

However, it is a little concerning. If I use the user call log endpoint, and I retrieve a call from that endpoint, shouldn't I be confident that the call I retrieve would contain that extension somewhere, at least in one of the legs? Otherwise, why would I even get that call entry in the response when I use that extension endpoint?

I think I am going to contact dev support just to be sure I am not missing anything. And for now I am going to continue to use the user call log endpoint until I am confident that I won't miss any associations.
Photo of Anton Nikitin

Anton Nikitin, Official Rep

  • 2,674 Points 2k badge 2x thumb
Yes, as I said, there may be some bugs. In fact we have hundreds of different call scenarios and API just reflects the internal state which is written by telephony services. So I would prefer to work with it case by case. Please contact dev support and give them full response traces about inconsistencies you experience. We will try to figure out and let you know what can be done.