Background: Using webhooks to direct incoming voice call to our application handler which connects the caller to an available reps cell phone.
The first part of the app checks to see if the incoming Caller telephone number is on an internal blacklist (to ignore robo dialers etc) -- if there is a match, our app will reject the call so we do not get billed. This rejection is being done echoing a Reject TWIML verb as follows:
echo '<Response><Reject reason="rejected"/></Response>';
exit;
The code works fine, send the xml response and exits the PHP script, however, the incoming caller doesn't get a "busy" signal or "Not In Service" message -- instead it just hangs in silence.
Additionally, the Twilio webhooks handler keeps firing off calls with the CallStatus = no-answer every approximately 2-seconds until the caller hangs up.
Any idea as to what I am doing wrong?
I determined that problem was with the formatting of the xml response being echo out. It turns out that formatting of the XML response needs to preserve format and whitespace, etc of XML (???):
This did not work (twilio will hang in silence until caller hangs up):
echo '<Response><Reject reason="rejected"/></Response>';
exit;
This does work (caller will receive busy signal):
echo '<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Reject reason="busy" />
</Response>';
exit;
Related
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.
Im placing an outbound call, and based on the automated message from whom Twilio is calling, it calls my phone with the connection.
Here is the script that places the phone call.
import os
from twilio.rest import Client
account_sid = "xxxx"
auth_token = "xxxx"
client = Client(account_sid, auth_token)
call = client.calls.create( url='http://myhost.com/rec.php',to='+1234',from_='+9876')
print(call.sid)
The phone call is placed, and the action script sends a TwiML gather response. Here's rec.php
echo '<Response>
<Gather input="speech"
partialResultCallback="http://myhost.com/partial.php"
action="http://myhost.com/finalresult.php">
</Gather>
</Response>
I've got the partial page logging the text. But when I forward a call, my phone rings for one second, then disconnects. There's no errors in the debugger either.
Here's partial.php
if(contains("To continue in English", $_REQUEST['UnstableSpeechResult'])){
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<Response>
<Dial>+myPhoneNumber</Dial>
</Response>";
}
here is final result, which i think is called when the phone call is complete? im not sure.
if(contains("To continue in English", $_POST['SpeechResult'])){
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<Response>
<Dial>+myPhoneNumber</Dial>
</Response>";
}
According to the documentation, partialResultCallback doesn't process TwiML.
The webhooks Twilio makes to your partialResultCallback are
asynchronous. They do not accept any TwiML in response. If you want to
take more actions based on this partial result, you need to use the
REST API to modify the call.
Not sure how your phone is ringing given the above. Any more details you can provide will help troubleshoot the issue.
I have a scenario where say at 5.00 AM every morning, I have a server side script / batch job that wakes up, selects a phone number from a list based on an algorithm, places a call to that phone number and uses text-to-speech to deliver a customized message. I have 2 questions,
Which Twilio API can I use to achieve this? Bear in mind there is no app UI and all the code would be on the back end. Think NodeRED flow or a Python script that is made to run at a given time.
Instead of specifying the text in the TwiML, can I pass say an audio stream from Watson's Text to Speech to the appropriate Twilio API?
To do this, you would need to use the programmable voice API from Twilio. This lets you play audio files, text to speech, make and manipulate phone calls, etc. I have never used Watson Text-to-Speech, but, if it can output an audio file you can play that with Twilio TwiML.
Here's an example in Node.
npm install twilio
//require the Twilio module and create a REST client
var client = require('twilio')('ACCOUNT_SID', 'AUTH_TOKEN');
client.makeCall({
to:'+16515556677', // Any number Twilio can call
from: '+14506667788', // A number you bought from Twilio
url: 'url/to/twiml/which/may/have/WatsonURL' // A URL that produces TwiML
}, function(err, responseData) {
//executed when the call has been initiated.
console.log(responseData.from); // outputs "+14506667788"
});
The TwiML could look like this:
<Response>
<Play loop="1">https://api.twilio.com/cowbell.mp3</Play>
</Response>
This would play the cowbell sound from the Twilio API. Just a default sound. This could be easily generated to play a Watson sound file if you can get a URL for that.
You could do the same thing in Node, if you'd rather not build the XML manually.
var resp = new twilio.TwimlResponse();
resp.say('Welcome to Twilio!')
.pause({ length:3 })
.say('Please let us know if we can help during your development.', {
voice:'woman',
language:'en-us'
})
.play('http://www.example.com/some_sound.mp3');
If you were to take this toString() it would output formatted XML (TwiML):
console.log(resp.toString());
This outputs:
<Response>
<Say>Welcome to Twilio!</Say>
<Pause length="3"></Pause>
<Say voice="woman" language="en-us">Please let us know if we can help during your development.</Say>
<Play>http://www.example.com/some_sound.mp3</Play>
</Response>
Hopefully this clears it up for you.
Scott
I know that on making a call Twilio can detect an answering machine, and react differently.
However if I use the <dial> verb, there's no obvious place to add this feature, even though it's essentially the same thing.
My intended flow is:
Customer enters their phone number
Twilio calls Customer and plays a voice message
Twilio dials an agent number, likely a mobile
If the Agent picks up, connect the customer to the agent
If the Agent busies the call or does not answer, call will likely go to Agent's voicemail.
Terminate call to Agent
Record voicemail from Customer
Email voicemail to Agent
From the official docs on the <Dial> verb (emphasis mine):
This is the simplest case for Dial. Twilio will dial 415-123-4567. If someone answers, Twilio will connect the caller to the called party. If the caller hangs up, the Twilio session ends. If the line is busy, if there is no answer, or if the called party hangs up, <Dial> exits and the <Say> verb is executed for the caller before the call flow ends.
<?xml version="1.0" encoding="UTF-8"?>
<!-- page located at http://example.com/simple_dial.xml -->
<Response>
<Dial>415-123-4567</Dial>
<Say>Goodbye</Say>
</Response>
Placing a <Record> verb after the <Say> verb sounds like what you are looking for. You can change the timeout from the default value of 30s like this:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial timeout="9001">415-123-4567</Dial>
<Say>Please leave a message</Say>
<Record action="/process_new_voicemail" />
</Response>
I am sure this is late, but hopefully it helps some one out. It sounds like you may just need to screen the call.
Basically, you can ask the "agent" that you dialed to accept the call and hang up if you do not receive input.
I am not sure what language you are using, but here is a great php/Laravel tutorial to explain:
https://www.twilio.com/docs/tutorials/walkthrough/ivr-screening/php/laravel
The key part is here:
$dialCommand = $response->dial(
['action' => route('agent-voicemail', ['agent' => $agent->id], false),
'method' => 'POST']
);
$dialCommand->number(
$numberToDial,
['url' => route('screen-call', [], false)]
);
Notice that the dial command uses the 'action' to specify a location that is sent a POST request should the call end i.e POST to /agent-voicemail.
Then, the number is dialed along with a 'url' parameter this is the location that will be requested after the agent has picked up but before connecting the two parties.
The /screen-call route then asks the agent to accept the call, if no input is received it hangs up and will make a POST request to the initial setup /agent-voicemail route.
This method will handle your scenario because if it goes to voicemail no input will be received and the call will end.
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.