How can I retrieve a RingCentral call recording from a monitored incoming call? - voice

I'm monitoring incoming calls on RingCentral by listening for the Call Session Notifications (CSN) telephony/sessions event filter:
/restapi/v1.0/account/~/extension/~/telephony/sessions
From this, I will receive events like the following. The recordings property will appear to indicate a recording is available. How can I retrieve this recording?
{
"uuid":"12345678901234567890",
"event":"/restapi/v1.0/account/11111111/extension/22222222/telephony/sessions",
"timestamp":"2019-03-08T22:30:40.059Z",
"subscriptionId":"11112222-3333-4444-5555-666677778888",
"ownerId":"33333333",
"body":{
"sequence":7,
"sessionId":"1234567890",
"telephonySessionId":"1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
"serverId":"10.11.12.13.TAM",
"eventTime":"2019-03-08T22:30:39.938Z",
"parties":[
{
"accountId":"11111111",
"extensionId":"22222222",
"id":"cs12345678901234567890-2",
"direction":"Inbound",
"to":{
"phoneNumber":"+16505550100",
"name":"Jane Doe",
"extensionId":"22222222"
},
"from":{
"phoneNumber":"+14155550100",
"name":"John Smith"
},
"recordings":[
{
"id":"44444444",
"active":false
}
],
"status":{
"code":"Answered",
"rcc":false
},
"missedCall":false,
"standAlone":false,
"muted":false
}
],
"origin":{
"type":"Call"
}
}
}

There are two ways to retrieve the recording using information in the Call Session Notification (CSN) event, specifically the recordings[0].id property and the sessionID property.
retrieving a full media URL by calling the call-log endpoint with the sessionId property
manually creating recording media URL using the recordings[0].id property.
Note 1: While the call is ongoing, the recording will not be available for retrieval, even when the recording id is present in the Call Session Notification event. The recording will be available to be retrieved shortly after the call concludes.
Note 2: Call recordings can be in MP3 or WAV format determined by the company. To distinguish check the response Content-Type header for the MIME type when retrieving the recording media file.
1) Retrieving Full Medial URL via Call Log API
Making an intermediate API call to the call-log API has the dual benefits of being the official approach for receiving a media URL an providing more metadata for the call. In this approach, the recording.id in the call-log record will match the recordings[0].id property in the Call Session Notification event.
Both the company account and user extension call-log APIs can be called with the sessionId parameter from the event as shown:
GET /restapi/v1.0/account/~/call-log?sessionId={sessionId}
GET /restapi/v1.0/account/~/extension/~/call-log?sessionId={sessionId}
In this example, the sessionId is 1234567890 so you would have a Company Call Log API URL as follows
GET /restapi/v1.0/account/~/call-log?sessionId=1234567890
The response object will have a recording property that provides hypermedia links to get the media file. The file can be WAV or MP3 format which is communicated in the response Content-Type header.
{
"uri": "https://platform.ringcentral.com/restapi/v1.0/account/11111111/extension/22222222/call-log?view=Simple&sessionId=1234567890&page=1&perPage=100",
"records": [
{
"uri": "https://platform.ringcentral.com/restapi/v1.0/account/11111111/extension/22222222/call-log/1234567890ABCDEFGabcdefgh?view=Simple",
"id": "1234567890ABCDEFGabcdefgh",
"sessionId": "1234567890",
"startTime": "2019-03-08T22:30:29.505Z",
"duration": 35,
"type": "Voice",
"direction": "Inbound",
"action": "Phone Call",
"result": "Accepted",
"to": {
"phoneNumber": "+16505550100",
"name": "Jane Doe"
},
"from": {
"phoneNumber": "+14155550100",
"name": "John Smith",
"location": "San Francisco, CA"
},
"recording": {
"uri": "https://platform.ringcentral.com/restapi/v1.0/account/11111111/recording/44444444",
"id": "44444444",
"type": "OnDemand",
"contentUri": "https://media.ringcentral.com/restapi/v1.0/account/111111111/recording/44444444/content"
},
"extension": {
"uri": "https://platform.ringcentral.com/restapi/v1.0/account/111111111/extension/22222222",
"id": 22222222
},
"reason": "Accepted",
"reasonDescription": "The call connected to and was accepted by this number."
}
],
"paging": {
"page": 1,
"perPage": 100,
"pageStart": 0,
"pageEnd": 0
},
"navigation": {
"firstPage": {
"uri": "https://platform.ringcentral.com/restapi/v1.0/account/11111111/extension/22222222/call-log?view=Simple&sessionId=1234567890&page=1&perPage=100"
},
"lastPage": {
"uri": "https://platform.ringcentral.com/restapi/v1.0/account/11111111/extension/22222222/call-log?view=Simple&sessionId=1234567890&page=1&perPage=100"
}
}
}
2) Manually Creating Media URL
You can call the Recording API endpoint and retrieve the media directly by manually constructing the recording URL as follows:
https://media.ringcentral.com/restapi/v1.0/account/{accountId}/recording/{recordingId}/content
In this example, the accountId is 11111111 and the recordingId is 44444444 for the following:
https://media.ringcentral.com/restapi/v1.0/account/11111111/recording/44444444/content
The accountId in the URL path can be set to the currently authorized user's account using ~. Alternately, it can be set explicitly by extracting the accountId from the event property or using the accountId property in the relevant party object. Using ~ is the recommended way to set accountId.
Note: This this approach can be quick, it may be error prone as RingCentral has changed the media hostname once in the past. While there are no anticipated, future changes, calling the call-log API and retrieving the full media URL from the response is the safer and recommended approach. See below for this approach. This is only included as some people will try this and potentially run into issues later.
3) Hybrid Approach
The first approach of calling the call-log end point is the recommended approach, however, it involves an extra API call and most of the time the second approach should work fine.
A hybrid approach is to construct the URL as in approach 2 and then fall back to approach 1 if approach 2 returns a 404 or other error.

Related

Does the RingCentral Call Log API Return a "Missed" Value?

In the RingCentral Online Account Portal (https://service.ringcentral.com) and endpoint apps, the call log display shows whether a call was Inbound, Outbound or Missed.
In looking at the API Reference for the Call Log API, it seems that it only sends back Inbound or Outbound for "Direction". Does the developer Call Log API return a "Missed" value? Is there another way to get this information via the Call Log API?
Ref: https://developer.ringcentral.com/api-docs/latest/index.html#!#RefCallLog.html
This question appears to be in reference to the Online Account Portal UI's "Type" column as shown in this screenshot:
The web UI's "Type" column shows Inbound, Outbound or Missed. This can be generated by using the response properties for both direction and result.
direction API response property will be Inbound or Outbound
result API response property is an enumerated value that includes Missed and other values including Voicemail which is the example screenshot. A full list is available in the link below:
Ref: https://developer.ringcentral.com/api-docs/latest/index.html#!#ResultStatusValues
Here is an example response:
{
"uri": "https://platform.ringcentral.com/restapi/v1.0/account/11111111/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2018-08-27T06:18:00.000Z&page=1&perPage=100",
"records": [
{
"uri": "https://platform.ringcentral.com/restapi/v1.0/account/11111111/call-log/22222222?view=Simple",
"id": "22222222",
"sessionId": "33333333",
"startTime": "2018-08-27T17:38:12.634Z",
"duration": 27,
"type": "Voice",
"direction": "Inbound",
"action": "Phone Call",
"result": "Missed",
"to": {
"phoneNumber": "+16505550101"
},
"from": {
"phoneNumber": "+16505550102",
"name": "LOS ALTOS CA",
"location": "Los Altos, CA"
}
}
],
...
}
Please read this blog to find out more information you can find from the call log.

Context size limit inside a node in Watson Conversation

My Watson Conversation bots typically have a node where I load some data into context. This usually contains all possible answers, strings, various other data.
So one of my first nodes in any bot looks like this:
{
"type": "standard",
"title": "Load Messages",
"output": {
"text": {
"values": [
""
],
"selection_policy": "sequential"
}
},
"context": {
// A whole bunch of data here
}
...
Is there a limit on how much data I can put there? Currently I have around 70 kilobytes, but potentially I can put a few megabytes there just for the convenience of running the logic inside Conversation. (Yes I am aware that this entire data will be sent back to the client, which is not very efficient)
There is no documented limit. You are more likely to hit network issues before Watson Assistant has any issues.
But storing your whole applications logic in the context object is considered an anti-pattern.
Your context object should only store what is required in Watson Assistant, and then if possible only for the related portion of the conversation.
For one time context values you can store them in the output object.
{
"context": {
},
"output": {
...
"one_time_var": "abc"
}
}
This will be discarded on your next call.
If you have a large volume of data that could be used at different times, then one pattern to use is a context request object.
For example:
"context": {
"request": "name,address,id"
}
Your next response from the application layer would send this:
"context": {
"name" : "Bob",
"address": "123 street",
"id": "1234"
}
You have your returning response update those variables, then clear the context variables again. If you have other context variables that need to stay, then store those in an object and erase just that object.

Meteor HTTP post request not working with google add place api

I am using a HTTP post request to add places with google api in meteor js. The code I used is
var url = "https://maps.googleapis.com/maps/api/place/add/json?key="+googleKey;
Meteor.http.post(url,
{params: {
"location": {
"lat": -33.8669710,
"lng": 151.1958750
},
"accuracy": 50,
"name": "Google Shoes!",
"phone_number": "(02) 9374 4000",
"address": "48 Pirrama Road, Pyrmont, NSW 2009, Australia",
"types": ["shoe_store"],
"website": "http://www.google.com.au/",
"language": "en-AU"
}
},function(err, result){
console.log(arguments);
})
Am getting an error
{ [Error: failed [400] { "status" : "REQUEST_DENIED" } ]
I had tried with changing the params and googleKey,but there is no change in the error. Can somebody help me to use http post request with google api? Thanks in advance
Did you try data in place of params ?
Meteor.http.post(url,
{data: {
"location": {
"lat": -33.8669710,
"lng": 151.1958750
},
"accuracy": 50,
"name": "Google Shoes!",
"phone_number": "(02) 9374 4000",
"address": "48 Pirrama Road, Pyrmont, NSW 2009, Australia",
"types": ["shoe_store"],
"website": "http://www.google.com.au/",
"language": "en-AU"
}
},function(err, result){
console.log(arguments);
})
Works fine on my remote server, but in localhost I have an INVALID_REQUEST response, due to the key I think.
Based on the FAQs of the Places API documentation
The "status": "REQUEST_DENIED" is returned by the Google Places API Web Service when:
You have not activated the Google Places API Web Service in the Google Developers Console.
The key parameter is missing from your request.
The key parameter does not match the your API key in the Google Developers Console.
Your API key has not been correctly set up in the Google Developers Console:
If you are using a browser key, check that your allowed referer(s) are correct.
If you are using a server key, check that your allowed IP(s) are correct.
Android and iOS keys are not supported, please use a Browser or Server key.
The request was not sent as an HTTPS request, HTTPS is required for all Google Places API Web Service requests.
The incorrect HTTP method was used to send the request:
All requests must be sent as a GET request except for Place Add.
All Place Add requests must be sent as a POST request.
The request body you specified looks complete, you can check out the Google Developer Console if you missed some configuration on it.
Hope this helps!

Triggering smart campaign and getting 603

I am trying to use Marketo smart campaign to send email data.
What I do is:
1) get or create Lead with addresse email
2) trigger smart campaign I've created with this lead_id and a couple of tokens I created on the folder containing the campaign.
That is, I am sending POST to https://.mktorest.com/rest/v1/campaigns/5826/trigger.json?access_token= with body
{
"input": {
"leads": [
{
"id": 2034349
}
],
"tokens": [
{
"name": "{{my.subject}}",
"value": "subj"
},
{
"name": "{{my.message}}",
"value": "the text"
}
]
}
}
And I get the response:
{u'errors': [{u'message': u'Access denied', u'code': u'603'}], u'requestId': u'c8f5#14c79fae723', u'success': False}
I was trying token names without "{{" and "}}", without "my." - the same result. The campaign exist and has this ID.
What's wrong here?
The role of the Marketo API user that you're using needs the "Execute Campaign" permission, and your current user is probably missing that permission. Unfortunately you can't edit the existing role. You'll need to create a new role, check that permission, and possibly also create a new API User.

How to "Add guest" to event via google calendar API?

could you please give me a hint on how to share a single event via google calendar api?
That is I'd like to invite other users to see the event programmatically without sharing the whole calendar. To mimic the "Add guests" UI action
As Claudio mentioned, you need to use the Google Calendar Advanced API for this.
You'll want to use a patch because you don't want to replace all the other data on the calendar invite. However, even in the case of patch, since the attendees lives in an array, if you attempt to pass a patch such as this:
{
attendees: [ { email: "new#example.com"} ]
}
... it'll replace all old invitees (i.e. it'll remove anyone that was on the invite before you called patch). To fix this, you must first get the current invitees, add a new person to the array, and then send a patch.
You can see a detailed example of this in this answer which also explains how to use Google Apps Scripting to ensure an email is sent to the user when adding them to a calendar event (see the addGuestAndSendEmail() method in that post).
You can use the API to add people to the attendees collection:
https://developers.google.com/google-apps/calendar/v3/reference/events/update
refer the following request.
method: POST
endpoint: https://www.googleapis.com/calendar/v3/calendars/primary/events?sendUpdates=all
here, sendUpdates means when you add any guest so he would get an invitation mail used based on scenario.
Input Json:
{
"kind": "calendar#event",
"etag": "etag",
"status": "confirmed",
"summary": "JayKara",
"description": "eqwbdjhwhhwhhwrhjehrhejhfj",
"location": "America",
"creator": {
"email": "#mail.com",
"self": true
},
"organizer": {
"email": "#mail.com",
"self": true
},
"start": {
"date": "2019-12-23"
},
"end": {
"date": "2019-12-24"
},
"originalStartTime": {
"date": "2019-12-24"
},
"visibility": "public",
"attendees": [
{
"email": "****#mail.com" //this guys are the guest
}
]
}.
After that there is no patch method required your guest guys will receive an invitation whenever update event
Cheers!

Resources