Get twilio callback on call screen success and also on failure - twilio

I have some working code for call screening with NodeJS, which I modified from the official twilio example.
https://www.twilio.com/docs/howto/callscreening
https://github.com/coolaj86/bizilio/blob/master/routes/twilio/voice/index.js#L246
Snippit:
response += ""
+ '<Response><Gather action="/twilio/voice/connect' + search + '" finishOnKey="any digit" numDigits="1">'
+ '<Say>Press any key to accept this call</Say>'
+ '</Gather>'
// TODO instead of hanging up, redirect to voicemail?
// otherwise it's left to the fallback url to pickup the voicemail and that takes a while
+ '<Hangup/>'
+ '</Response>'
;
If the screening completes successfully, I get a callback to /twilio/voice/connect?foo=bar.
If the screening is unsuccessful I also want a callback to /twilio/voice/miss?foo=bar.
Is the most appropriate way to do this to do a <Redirect> instead of <Hangup/> and then do the <Hangup/> in the redirect? Or should I had a statusCallback somewhere in the original dial and reference the call id?
In thinking about the possibilities to write out the question here, I've probably already discovered a working solution (and I'll go try it), but I'd still like to hear a best practice approach.

As you suggest, you should replace the <Hangup> with a <Redirect>/twilio/voice/miss?foo=bar</Redirect>. After the timeout expires (by default 5 seconds, but configurable via the timeout attribute of the Gather verb), if no input has been received it will go to the next instruction.
From the Twilio Docs for <Gather>:
If no input is received before timeout, falls through to the next verb in the TwiML document.
In the URL that you redirect to you can record that no input was gathered and return any TwiML you like to continue processing the call or return an empty <Response></Response> (or Hangup) to end the call.
StatusCallback is only used at the completion of the call and cannot execute further TwiML instructions.

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 collect the user input when make a call using Twilio API?

I am developing a simple application in C# which
Trigger a call using Twilio
receiver to press * after receiving the call and finish the call after pressing *
Provide the status completed if user pressed * otherwise provide different status.
I was able to make a call but not able to receive the user input Or status, I tried finishOnKey() but that didn't work, and it always provides status as completed. I didn't get much help from Twilio code sample, can someone redirect to correct article or provide the code to accomplish above.
Twilio developer evangelist here.
Once a call is answered successfully, it doesn't matter how the call is finished, the final status it reaches will be "completed". You can see more about Twilio call statuses in this documentation. You can see that the final call statuses could be:
completed: call was answered successfully and then finished
no-answer: Twilio dialled the number but there was no answer before the timeout
busy: Twilio dialled the number but received a busy signal
cancelled: The number was dialled, but the call was then cancelled using the API before answering
failed: the carrier couldn't connect the call
If you are using <Gather> to take the user input, you should ensure you have set the action attribute to a URL in your application. That URL will receive a new webhook request when the user presses a digit. For example:
<Response>
<Gather action="/gather_results" digits="1">
<Say>... your content goes here ...</Say>
</Gather>
</Response>
With the above TwiML a user would only have to press 1 key before the call is moved to the next stage and the webhook '/gather_results'.
The request to the /gather_results endpoint would include a body with a Digits parameter. If the user pressed "*" then the body of the request would include Digits=*, if the user pressed "1" then it would include Digits=1. You could then choose to do whatever you like with those results, including hanging up the call or recording the submitted digits.
Let me know if this helps at all.

Taskrouter problem using Laravel. Task not getting created?

I've followed every single step in the Twilio's documentation called Dynamic Call Center with Laravel.
My problem is that a call gets through the IVR, then after choosing a digit, nothing happens.
My guess is that its not creating a task. the code provided in the documentation just generate a task with json but thats it. I check my tasks in Twilio taskrouter console and nothing shows up.
I've provided all credentials, used ngrok, filled in all url callbacks.
public function enqueueCall(Request $request)
{
define('workflowSid', env('TWILIO_WORKFLOW_SID'));
$selectedSkillInstruction = new \StdClass();
$selectedSkillInstruction->selected_skill = $this->_getSelectedSkill($request);
$response = new Twiml();
$enqueue = $response->enqueue(['workflowSid' => workflowSid]);
$enqueue->task(json_encode($selectedSkillInstruction));
return response($response)->header('Content-Type', 'text/xml');
}
I expect a code that actually creates a task, but when I call this api via postman, a task is not created
The above code returns Twilio Markup Language (TwiML) which uses the enqueue verb and a workflowSid attribute. The enqueue verb is used with Programmable Voice. Have you tried associating your application with a Twilio phone number and then calling the Twilio number which should enqueue the call into a task router workflow?
TwiML Voice: Enqueue
https://www.twilio.com/docs/voice/twiml/enqueue#attributes-workflowSid
I have solved my problem. It turned out that everything was in order, the only problem is that I didn't know I need to press # after choosing from the IVR because all the demo I saw from Twilio only press a number and it gets routed.

How to end a twilio call prematurely

I want to use twilio to test our internal phone system, and make sure calls are routing as they should, since our provider is notoriously bad of notifying us to problems.
I'm can initiate a call from twilio, use the "gather" verb to record speech (to ensure we hit the right queue) and then hang up. Everything works fine. Except that the gather ends up taking over 2 minutes to listen to the whole message from our phone system, charging us for 8 15 second gather chunks. I only need the first 15 seconds, but can't figure out how to hangup sooner. Is there a simple way to limit calls to a specific time?
timeLimit, and timeout both don't apply here, since timeLimit only works inside of a dial verb, and timeout only works for pauses in speech during the gather.
Perhaps just set a timer in your code for 15 seconds or so and then use the POST endpoint at /2010-04-01/Accounts/{AccountSid}/Calls/{CallSid} to cancel the call (using the Status=Completed parameter in order to cancel calls even if they are in progress).
If you use their Ruby SDK, and you make a normal call (not a conference call) then you can use the update method:
client = Twilio::REST::Client.new(account_sid, auth_token)
# fetch all in-progress calls between the two numbers
client.calls.list(from: '+11231231234',
to: '+12312311234',
status: 'in-progress').each do |c| #it's supposed to be just one record, but you can play it safe
c.update(status: 'completed')
end
Updating the status to completed should hangup the call if in-progress.
Updating the status to canceled should hangup the call if ringing/queued.
If you know for sure that the call is in-progress and you know the call sid, then you can use:
client = Twilio::REST::Client.new(account_sid, auth_token)
in_progress_call = client.calls(call_sid).fetch
in_progress_call.update(status: 'completed') if in_progress_call.present?
There is some general information in the official docs. Also snippets are available for the other SDKs.
You can find the source code of the update method here for more details.

Retrieve Key Input before recording a users call when making calls within Twilio

We have currently developed a phone system for our call centre using Twilio (mainly c#, angular2 and typescript). Our company is currently in the UK but we have now started expanding out to the USA and because of laws in the US it looks like we'd need the ability to choose when we turn on the call recording. In the US people have to consent to recording the call before you can start recording them. I am trying to - when we make an outbound call via twilio to first play a message and get the user to input a key on their dialer to consent to recording the call before continuing with the call. I have attempted to use the gather and say verbs after we have dialled out but this doesn't seem to work. Code below:
`
public override void ApplyAction(TwilioResponse response)
{
var attributes = this.GetAttributes<DialAttributes>("attribute-");
attributes.callerId = this.PhoneNumber;
response.Dial(new Number(this.ReceiverPhoneNumber), attributes);
response.Gather(
new
{
timeout = 10,
finishOnKey = '*'
});
response.Say("We record all calls - please press the star key to consent to call recording");
}`
Twilio developer evangelist here.
The problem is that you are performing the <Dial> before the <Gather>
and <Say>. If you want the user to approve the call first you need to nest the <Say> in the <Gather> and provide an action URL for the <Gather>. When the user presses a button as part of the <Gather> Twilio will make an HTTP request to the action URL with the results in the Digits parameter. Then you should return the <Dial> as the response to that request, if the user signifies agreement. This way you ask them first and then connect the call.
Let me know if that helps.

Resources