/rest/call/read minDate maxDate not filtering

Hi,
As you can probably tell, that API call was originally designed to work with minID, much as you’ve ended up doing. There was an omission in the date checking code which prevented it from working as documented - There is an alternative undocumented format for the minDate and maxDate, which I have no expectation will ever go away, so this may help.

Example:
"minDate":"2017-08-01T01:12:03.629Z"

The time must be in UTC/GMT, and the number of digits must be exactly as specified above, such as a 4-digits year and 3-digits milliseconds. The ‘T’ and the ‘Z’ are literal.

I’ll fix this in an upcoming release to work as documented.

Hope that helps.
Steve

1 Like

Hi Steve,

That’s worked! If it’s not too much trouble could you look at filtering that API by company also? Similar to how the /rest/call/incalls works. Actually the only reason I didn’t use /rest/call/incalls was because I couldn’t find the extension but looking now that appears to be the grouped key!

Rick,
I’m afraid that that REST call is providing raw cdr data, and any one of those rows can relate to one or more companies, or sometimes even none. It takes significant post-processing to determine source company and destination company. You may be able to use the incalls and outcalls REST requests? These are much slower, but are natively run per-company.

Be warned that incalls and outcalls can return a ‘retry’ response as the amount of CPU it takes means it is limited to a single run at a time - Not something you can use for anything very close to realtime data.

Hope that helps,
Steve

Is there anything you would recommend for getting the call logs/data for a realtime reporting wallboard? I thought I nearly got there but seem to be having issues associating which calls are from/to what extension as this client is hot desking so no phone ownership and with hunt groups it logs the extension of the hunt group sometimes rather than the users extension that handled the call.

I’m picking up the majority of outbound calls but it appears some actually come from the src of the hunt group.

Any help would be appreciated.

Perhaps you could detail what you are doing so far?

It is entirely possible that calls would come from the ‘src’ of the hunt group. Most phones will do that by default for a forwarded call for example. In fact a handset with multiple identities can dial a call as coming from any of it’s identities.

The more specific data to use to identify an outbound call source is the ‘channel’, but that then needs to be mapped to the current user as you’ve observed - If it is a hotdesk user, you’ll find some of this info in the cdr userinfo field where you’ll have ‘hd=nnn’ nnn being the hotdesk user’s extension.

All of this is handled by the JavaScript API, but I believe you’re using PHP?

Cheers,
Steve

At the minute I’ve got a list of phone users so extensions and their name stored in a table. I’ve then got a table which is storing call data from the endpoint /rest/call/read. I’m using the src field for mapping to extension for outgoing calls and for incoming I’m string replacing _CompanyName from the dst for incoming.

I did take a look at the JavaScript API and got the listeners working which I could see live call data but wasn’t clear how I could get a total of inbound/outbound calls for each extension/user for that day.

I’m happy to switch over to the JavaScript API if that is what you would recommend and if you could recommend about how I would get the call data for that day?

Thanks

Live and historical data is separate. Let me have a think about it and get back to you.

Regards,
Steve

OK thanks! I appreciate your time.

So, if I were doing a wallboard from scratch, I would certainly use a combination of the incalls, outcalls REST requests to collect initial historical data, and the JavaScript API for live data - On the other hand, that is largely because I use JavaScript most of the time these days!

Reading the CDR data either using the REST interface, or the Asterisk AMI (collector / live-stream) interface is also quite valid and will result in a more consistent data feed, because the AMI interface just dumps the CDR records as they are created.

When Oak approached this problem, we created a lookup table for them to be able to use the ‘channel’ and ‘dstchannel’ columns to determine who was actually making/receiving a call - There is a common disconnect where there is an assumption that handset == user == extension, but handset, user and extension are very much separate entities on an IPCortex system.

You could try the following URL, which dumps that lookup

https://pabx-host-or-ip/admin/oak.whtm

It requires an administrative login session, so to get going, probably just log in manually as admin and browse to that page. It is fairly crude, and does take the current hotdesk situation into account, though that is probably not useful in the long-run.

Hi Steve,

Thanks for your response. I’ve just taken a look at the oak.whtm and I can see the mapping. To further understand this are each map unique? For instance the below snippet for hotdesk phone 16 occurs a few times but has 1 that maps to a correct extension. If a user logs out of the phone and another logs in, will it replace hdesk16=newextension or would it be something unique like hdesk16_6=newextension.

As the links have no datetime then I’m making sure that the mapping/association of the calls to an extension won’t change over to another user if someone then logged into that phone if that makes sense?

I mainly use JS now but in this case I’ve setup a cron that runs every minute which fetches new data from the REST API then fires an event in PHP that sends the new data to PusherJS and the frontend is listening on a certain pusher channel to update the relevant objects/arrays

I replied to this yesterday, but must not have hit “post” and now have lost that response :slight_frown:

The _2, _3, _4 etc numbers represent the multiple lines (identities) on a handset. When hotdesking, only the first line is normally used, but if other lines are activated by the user, a call can be made from one of those other lines.

The oak report will update based on the results of hotdesking, but the query uses a multi-way table join, so don’t run it TOO often. Sadly in the REST environment there is currently no quick indicator of a hotdesk or other config change available.

In case it helps:

In the JS environment, I would say this is a bit “simpler”, as you’d load, login and initialise the API as per the examples, and then I would use the REST incalls/outcalls requests to gather historical data for a starting point. From here you can “simply” register an all-calls update listener:

IPCortex.Types.Call.addListener('update', (call) => { /* process 'call' here */})

using the ‘dial’, ‘ring’ or ‘up’ call state to increment call counts, and the ‘dead’ state to decrease call counts. The call object that is sent in these updates has a uniqueID and a reference to the device they are operating on, which I think gives you what you need?

Hi @steved, thanks for this reply all those months ago! I managed to get a away without having to worry about incoming call stats until the client has just asked me now… :smile:

So, I just wanted to ask how you would use the REST API for historic data. As the “https://pabx-host-or-ip/admin/oak.whtm” endpoint returns hot-desk to extension for that present moment and if you wouldn’t recommend hitting the endpoint too often then I don’t see how I can map historic data of dstchannel to extension? I’ve used the IPCortex JS library for the listeners for another project so I could see a way to POST to an endpoint on my API to store the data for historic/reporting reasons, however, I’m unsure whether this is reliable and can keep running 24/7? Do you know whether this could sit on a NodeJS app and keep running rather than having something setup client side?

Hi,

I agree that the oak.whtm page is a bit horrible if you are using hotdesking - it was put together for our first ever Oak installation and has not received much attention since then.

Hopefully the following will answer your other questions/points.

Cheers,
Steve

  1. Live data…

If you’re using hotdesking with the live JS API, then realtime hotdesking updates can be collected through the getLInes() callback, though I imagine that using it would be non-trivial as it is designed to present data for a single-user UI experience (ie keevio)

http://developers.ipcortex.co.uk/ref/js/methods/pbx/#menu-ipcortex-pbx-getlines--callback----owned----rarr---promise-

  1. Historical data…

For historical data, probably the simplest solution would depend on you running version 6.3.1+ software - Although 6.2.16+ includes the call reports REST call:

http://developers.ipcortex.co.uk/ref/rest/cdr_calls/#auto-9-command--allcalls-

Version 6.3.1 adds a new option scope: {extra: true}} which returns data which takes hotdesking into account, though historical data may be inaccurate as hotdesk events are only recorded in the database in detail from the newest version.

This feature is only about a week old, so the extra option has not been documented yet, but should be added to the above documentation link fairly soon now.

  1. Long running / node…

I run the API long-term in my desktop browser (weeks or months sometimes) specially to confirm that there are no memory leaks, so you should be fine to run the api 24/7 - The code includes common techniques to help the JS garbage collector clean up.

nodeJS should also be an option - It’s not been used for a little while, so let us know if it is broken, but:

This could possibly be improved to do the ‘update’ bit every time it is started, or to ‘eval’ a live-fetched copy of the api instead of caching a local copy which might go out of date if the PABX is updated.

Hi @steved after your recommendation I’ve discussed this with the IT team who have now upgraded the phone system to the latest version.

I’ve tried passing the extra scope through to the /rest/call/allcalls endpoint and it appears that the structure is slightly different for calls in and out. The ones in appear to be grouped by extension which also includes some huntgroup extension numbers.

Can you explain what the best way is to get the user from the extra data?

Is it tohdext and frhdext fields depending whether you’re going through the in or out objects?

Hi,

Yes, all inbound call reports are keyed on the extension they are calling. All outbound calls are keyed on the device that makes the call… There isn’t a 1-to-1 relationship between handset and extension, so calling extension is not always meaningful, and called device is incidental data.

The closes you could get to marrying the two up would be to use extra.toch as the key for inbound calls that are actually answered, but an unanswered or voicemail call won’t have a ‘toch’ value set (which is partly why it is not the key for inbound)

To get the user from the extradata, use extra.frname and extra.toname respectively - As long as a PABX user is one of the parties involved, then that should be set. ‘frid’ and ‘toid’ are available for disambiguation of similar names.

‘frhdext’ and ‘tohdext’ indicate the effective from/to extension number for hotdesked users. Perhaps there is some merit in seeing if I can provide a ‘frext’ value for normal calls - I don’t know how easy that would be.

Hope that is of some help.

Hi @steved,

Is there a way to reduce the all call data using a minId like the other call/read report. Or, is the smallest amount of data just using the day? It would also be useful to filter by company if that’s possible?

Hi, I’ve been out of the office - I’ll try and answer this later today.

At present the pre-precessed call reports can only be run for a whole day, or for days at a time. Also, company cannot be selected - This is because running the report for one company takes the same CPU/effort as running for a many companies so it is better for the PABX if one request is made. The ‘allcalls’ report is designed for bulk daily collection into an external reporting system where more complex reports can be run.

For slightly more granular data you need to combine the ‘incalls’ and ‘outcalls’ reports, which can be filtered by company.

I will make a note to consider adding filtering by ‘acctid’ in future, but the data is so heavily processed in the call reports that it has much less meaning, and is just a ‘key’ rather than being a sequence anymore.

Hi @steved some of the inbound calls aren’t being matched to an extension with the extra info. It seems to be when a call is answered then forwarded. Is this when I’d need to use /admin/oak.whtm? Or would the Node integration provide better call data?

object(stdClass)#7743 (12) {
    ["acctid"]=>
    int(1034684)
    ["calldate"]=>
    int(1544115434)
    ["caller_info"]=>
    string(16) "Forward via 1065"
    ["caller"]=>
    string(11) "{REPLACED_MOBILE_NUMBER}"
    ["type"]=>
    string(8) "External"
    ["ringtime"]=>
    int(6)
    ["billsecs"]=>
    int(1006)
    ["detail"]=>
    string(28) "Answered : HDesk17"
    ["qtime"]=>
    string(0) ""
    ["qstatus"]=>
    string(0) ""
    ["ddi"]=>
    string(11) "{REPLACED_DDI}"
    ["extra"]=>
    object(stdClass)#7744 (8) {
    ["frch"]=>
    string(7) "SIP/Q20"
    ["toch"]=>
    string(21) "SIP/hdesk17"
    ["toint"]=>
    bool(true)
    ["frint"]=>
    bool(true)
    ["toname"]=>
    string(7) "Hotdesk"
    ["disposition"]=>
    string(8) "ANSWERED"
    ["frchname"]=>
    string(3) "Q20"
    ["tochname"]=>
    string(17) "HDesk17"
    }
}```

Hi Rick,

I presume you mean “hdext” is missing?

Whether the node integration would provide better data depends on your use-case - I bet if you went to use it you would find a unique set of requirements and issues which would cause there own set of questions!

I doubt the oak.whtm query would help a great deal although it may patch-up the issue.

I seem to remember recently finding a bug in some SQL that might conceivably be causing this issue.

If you raise a support ticket then I can try to log in and patch it (perhaps include this text in the ticket?)

Regards,
Steve