Twilio voice callback - twilio

I'm having a tough time getting the Twilio Voice callback function to work properly, and would greatly appreciate any assistance in resolving this.
I have a working VOIP webapp using Python, twilio package and twilio voice SDK.
I need to get call status when a call is being made: answered, completed, ringing, in-progress and the likes.
is_record = fetch_recording_data_from_DB
handle_url = '/handle'
callback_url = '/events'
events = 'answered ringing initiated completed'
#incoming call
dial = Dial(timeout=15, record='record-from-ringing' if is_record else 'false', action=handle_url)
dial.client(
identity=contact_data['company_id'] or company_id,
status_callback_event = events,
status_callback = callback_url,
status_callback_method = 'POST'
)
return response.append(dial)
The handle_url is triggered after call ends or the 20s is exhausted with no answer to determine whether to make a call forwarding or play VM, this works fine. No error whatsoever, calls come in - I answer and talk for a while, if I don't, it goes to voicemail, records and hangs up. I see my recording, cost, duration and other data on the calls tab on Twilio console, under Monitor. All fine. I just can't get the status callback bit.
#status callback function
def stat_events():
return request.values, {'Content-Type': 'text/xml'}
.....
class StatEvents(Resource):
def post(self):
return stat_events()
Now, on the Twilio console, I can see the response and the other information (fromstate, sequencenumber,...) under Request Inspector (multiple times, as it should be) xdxxdxd.ngrok.io/events (POST, 200) regarding the call, but on my network tab (chrome) (when I make a call on the frontend) I check under the events network and see {} - empty
I tried console.log() on the events, nothing! so either I am not using this option well or there's something magical at play.
I need the status so I can save the call log to my DB (background task) when it's completed or no-answer.
data I want but it's only showing up on Twilio console and empty on network tab (apart from saving call log, I need this data to show the status on the front-end):
"Called": "+653xxxxxx",
"ParentCallSid": "CAd1ed07xxxxxxxxxxxxxxx",
"ToState": "",
"CallerCountry": "US",
"Direction": "outbound-dial",
"Timestamp": "Fri, 22 Jul 2022 08:58:56 +0000",
"CallbackSource": "call-progress-events",
"CallerState": "MI",
"ToZip": "",
"SequenceNumber": "0",
"CallSid": "CA3a39c6b1xxxxxxxxxxxxxx",
"To": "+653xxxxxxxx",
"CallerZip": "",
"ToCountry": "SG",
"CalledZip": "",
"ApiVersion": "2010-04-01",
"CalledCity": "",
"CallStatus": "initiated",
"From": "+194xxxxxxx",
"AccountSid": "ACb9f4fe8f52xxxxxxxxxxxxx",
"CalledCountry": "SG",
"CallerCity": "",
"ToCity": "",
"FromCountry": "US",
"Caller": "+1947xxxxxx",
"FromCity": "",
"CalledState": "",
"FromZip": "",
"FromState": "MI"
}```
```handle_url```'s function uses ```DialCallStatus``` in place of ```CallStatus```, as I read that this would be sent by Twilio request to the endpoint.

You describe that you are receiving requests to your /events webhook, but that you're not getting events in the browser.
When you register to receive events via a status_callback_url then those events are only sent as webhooks to your server.
However, if you have implemented the Twilio Voice SDK in JavaScript, then you can get call events by listening to events on the Twilio.Device object and on Twilio.Call objects. For example, the Twilio.Device will emit the incoming event when there is a new incoming call. And the Twilio.Call will emit accept events when an incoming call is accepted, and disconnect for when a call is over.
You can use these events to show call progress in your UI.

Events looks to be a list:
status_callback_event=['initiated', 'answered']

Related

Twilio - PHP - Forward ringing call to voicemail through agent action

What i'm trying to accomplish:
On an incoming call, I display a small box in the frontend that contains caller info along with a button to pickup the call, and a button to send to voicemail. When the agent clicks the button for voicemail, I want to simply forward the incoming call to voicemail.
The issue:
As long as the call is unanswered and still ringing, I cannot redirect it by updating the call the usual way, it has to be answered to allow updating. If I make the button either ignore or reject the call, I have no specific callback status to track, ignore has no status at all, reject just returns "completed" which is no help to me at all.
What I have tried:
// Called by Ajax on button click, variable $callSid contains the call SID
$client->calls($callSid)->update([
"method" => "POST",
"url" => "https://URL_TO_TWIML"
]);
// TWIML returned by URL_TO_TWIML
$response = new VoiceResponse();
$response->say('Agent is unable to take your call, please leave a message');
$response->record(['timeout' => 10]);
$response->hangup();
return $response;
I have tried to find a usable status on callback for ignore / reject as mentioned previously without success. I've searched far and wide for an answer to this without success.
Maybe i'm looking at it the wrong way, i'm still fairly new to Twilio. Any help would be appreciated.

How to ensure Twilio returns the correct event callback?

My calls are connecting fine to the client app, and I can chat over it. However, the status of the call sent during callback events seems to be wrong.
Below is my TwiML.
response = Twilio::TwiML::VoiceResponse.new do |r|
r.dial do |d|
d.client(identity: 'xx#gmail.com',
status_callback_event: 'initiated ringing answered completed',
status_callback: 'https://example.com/twilio_callbacks/call_status',
status_callback_method: 'POST')
end
end
After the call is completed, I receive a callback with parameter CallStatus of no-answer, but checking the logs on Twilio, I was connected, and the call should have a status of completed instead.
What am I doing wrong?
Twilio developer evangelist here.
The completed statusCallback event may have many different statuses, from "no-answer", "busy", "completed", "failed" or "cancelled".
If, however, you believe the call status is wrong, then you should get the call SID and contact Twilio support who can look into what happened with the call.

Twilio Target Worker Expression--blocking voice calls while on a text

I've read the documentation here: https://www.twilio.com/docs/taskrouter/multitasking#preventing-a-worker-from-receiving-chat-tasks-if-on-a-voice-task on how to block an agent from getting chats while they are on a voice call, but I want to do the reverse with a twist.
I successfully managed to stop workers from getting a voice call while they have an active chat going using "worker.channel.chat.assigned_tasks == 0" as the Expression. However, it also prevents a second chat, SMS, Facebook, or WhatsApp message coming in even though the worker's capacity is higher than 1.
Would love suggestions on what the expression should be so that the additional SMS or chats can come through up to the worker's capacity but not any voice calls when they have an active chat or SMS going.
The following filter should do the trick. The expression will only apply to voice tasks and the target routes to workers with no assigned chats.
{
"filter_friendly_name": "Do not assign Voice Tasks if assigned Chat",
"expression": "(task_channel_unique_name=='voice')",
"targets": [
{
"queue": <default queue sid>,
"expression": "worker.channel.chat.assigned_tasks == 0"
}
]
},

Twilio Node.js - Getting Conference Participant Details In statusCallback

I'm trying to have the ability to update a call to dial it into a conference, and then I want to keep track of which phone numbers are in the conference. I'll already have the phone number before updating the call, so my plan was to add it as parameter to the statusCallback, then when someone joins, I'll know which phone number has joined (or left). Here is the Twiml I'm using to update the call into the conference.
let conferenceTwiml = function(conferenceName, phoneNumber) {
let voiceResponse = new VoiceResponse();
let options = {
startConferenceOnEnter: true,
endConferenceOnExit: false,
waitUrl: <myWaitUrl>,
statusCallbackEvent: "join leave",
statusCallback: <myStatusCallBackUrl> + '?phoneNumber=' + phoneNumber,
statusCallbackMethod:"POST",
};
voiceResponse.dial().conference(options, conferenceName);
return voiceResponse.toString();
}
The body sent to the statusCallback looks like this:
{
Coaching: 'false',
FriendlyName: 'Room 123',
SequenceNumber: '4',
ConferenceSid: 'CF1c7a162ba5d0587f390a0d7e7c6eb9a5',
EndConferenceOnExit: 'false',
CallSid: 'CA5244195567afec7327bb24d65a2d2b15',
StatusCallbackEvent: 'participant-join',
Timestamp: 'Wed, 17 Jul 2019 18:18:27 +0000',
StartConferenceOnEnter: 'true',
Hold: 'false',
AccountSid: <myAccountSid>,
Muted: 'false'
}
So you can see there's not really any identifying information, without the additional query parameter.
The problem I've run into is that, according to the docs:
The statusCallback URL is set by the first Participant to join the conference, subsequent statusCallbacks will be ignored.
So in essence I can't dynamically set the phoneNumber parameter for each person I'm dialing into the conference, since it will always reflect the phoneNumber of the first person who joined.
My question is, how can I get some kind of identifying information about who is joining or leaving the conference? Where are my twilio evangelists at? Thanks!
Heyooo Developer Evangelist here. 👋
There are two ways to approach this.
1. Persist the call information via CallSid yourself
When you receive the initial phone call and you put people into the conference, what you could do it to persist the call information (including the phone number) on your end and use the CallSid later to reference it when you receive the statusCallback hook. This way you would have all the information at hand using the available CallSid when the statusCallback hook comes in.
2. Fetch the call information when you receive the statusCallback
While the statusCallback hook doesn't include the call details what you can always do is to fetch the call information again by using the CallSid. This way you can take the information from StatusCallbackEvent and merge it with additional information after you received the call details.
Both approaches have pros and cons but are similar in the way that you have to get the call information from "somewhere".
The first approach needs you to find a way to persist call information. This brings additional overhead in your application.
The second approach saves you the need to persist call details but introduces an additional API request.
As always – it depends on your case. I hope that helps. :)

Not getting callback after task reservation fails

I'm using the Twilio TaskRouter. A call comes into our number, Twilio makes an API call to our incoming call endpoint. I send the following response:
<Response>
<Say voice="woman">Thank you for calling</Say>
<Enqueue waitUrl="/Call/HoldMusic" workflowSid="WW..."/>
</Response>
The call is successfully enqueued and my workflow kicks off. I get the workflow assignment callback and respond with the following JSON:
{
"instruction": "dequeue",
"to": "+18885551213",
"timeout": 10,
"status_callback_url": "/Workflow/Changed",
"status_callback_events": "initiated,ringing,answered,completed",
"from": "+18885551212"
}
The outbound call is successfully made to my "to" number. If I accept the call, I get the reservation.accepted event to my task router callback endpoint. If I don't accept the call (let it timeout), I don't get a notification. Because I don't get a notification the dequeue failed, I can't cancel the reservation and have the call ring down through the queue.
I also changed the workflow assignment callback to return a "call" instruction and set the "status_callback_url" but again I only receive a callback if the call is answered, not if the call times out.
Is there something I'm doing wrong, or something fundamental I'm not understanding?
To answer my own question. If you don't include the "status_callback_events" value, then Twilio will send an event for all events. The missing event was no-answer. I'm marking this as answered so that future people can see the list of Twilio events for the dequeue and call instruction.
Current known list of dequeue and call events:
queued
no-answer
initiated
ringing
answered
completed
in-progress
busy
canceled
failed

Resources