My goal is to have the ability to screen incoming calls, and send them to voicemail. The below code does the screening correctly, however if I answer the call and and then just hangup the call is dropped instead of directing it to voicemail. How can I accomplish this?
<Say>Please wait while we connect you to Aaron. Calls may be recorded for quality assurance purposes.</Say>
<Dial action="voicemail.php?email=aaron" timeout="15">
<Number url="screen-caller.xml">+11231231234</Number>
</Dial>
screen-caller.xml:
<Response>
<Gather action="handle-screen-input.php" numDigits="1">
<Say>To accept, press 1.</Say>
</Gather>
<!-- If customer doesn't input anything, prompt and try again. -->
<Say>Sorry, I didn't get your response.</Say>
<Redirect>screen-caller.xml</Redirect>
</Response>
handle-screen-input.php:
echo '<?xml version="1.0" encoding="UTF-8"?>';
echo '<Response>';
$user_pushed = (int) $_REQUEST['Digits'];
if ($user_pushed == 1)
{
echo '<Say>Connecting. Calls are recorded.</Say>';
}
else {
echo '<Hangup />';
}
echo '</Response>';
voicemail.php:
header("content-type: text/xml");
echo '<?xml version="1.0" encoding="UTF-8"?>';
$email = $_REQUEST['email'];
?>
<Response>
<?php if ($_REQUEST['DialCallStatus'] == 'completed') { ?>
<Hangup/>
<?php } else { ?>
<Say>Please leave a message at the beep. Press the star key when finished.</Say>
<Record transcribe="true" action="goodbye.php" transcribeCallback="voicemail-send.php?email=<?php echo $email; ?>" maxLength="120" finishOnKey="*" />
<Say>I did not receive a recording.</Say>
<Redirect>voicemail.php</Redirect>
<?php } ?>
</Response>
[[ edit ]]
Ahhh! I know what it is! The below answer (which I've kept for posterity) is straight wrong.
When the person being dialled and getting the whisper hangs up, then the action on the <Dial> verb is called. From the documentation, the DialCallStatus values can be: completed, busy, no-answer, failed or canceled. When the person picks up the phone the status cannot be busy, no-answer, failed or canceled. So when they hang up before the whisper is over, the call status will be completed.
So, when your action gets called, the DialCallStatus will be completed and your voicemail.php will hang up.
You do also get sent a DialCallDuration, so you could check how long the call went on for and work out whether the call was connected or the person just hung up.
Hope this helps now!
[[ original answer ]]
Twilio developer evangelist here.
If you hang up during the whisper part of the call then the original caller will continue to make their way through the TwiML they were given. In this case, you only give them a <Dial> verb, so once you hang up on your end, the caller completes the <Dial> action, gets to the end of their TwiML and hangs up.
Try adding a <Redirect>/voicemail.php?email=aaron</Redirect> after the <Dial> in the first TwiML.
Let me know if that helps.
Related
we have a Windows service, that automatically send multiple voice calls for appointment reminders.
var call = CallResource.Create(
machineDetection: "DetectMessageEnd",
asyncAmd: "true",
twiml: new Twiml(message),
to: new PhoneNumber(toPhone),
from: new PhoneNumber(FromPhone));
The message used for the one above is dynamically generated using the Twiml below.
<Response>
<Pause length="1"/>
<Say voice="alice">Hello {name},</Say>
<Pause length="1"/>
<Say voice="alice">Your appointment is scheduled for {date} at {time}.</Say>
<Pause length="1"/>
<Gather timeout="3" numDigits="1" action="https://6f8137e0cb9a.ngrok.io/Voice/gather?aid=12345" method="GET">
<Say voice="alice">To confirm this appointment press 1, to cancel press 2, or you may hang up.</Say>
</Gather>
</Response>
It works fine, when the call is picked up, but if no answer then when it goes to voicemail. I want to send a different Twiml like the one below
<Response>
<Pause length="1"/>
<Say voice="alice">Hello {name},</Say>
<Pause length="1"/>
<Say voice="alice">Your appointment is scheduled for {date} at {time}.</Say>
<Pause length="1"/>
<Say voice="alice">To confirm or cancel this appointment call 18888888888.</Say>
</Response>
Is this even possible with Twilio ?
Twilio developer evangelist here.
That is absolutely possible! In your original script it shows that you are using asyncAmd, which means that your initial message will start playing even as the machine detection goes on. If a machine is detected then the AMD will want to alert you of that.
To do that, you need to provide an asyncAmdStatusCallback parameter to your outbound call that points to a URL that can receive a webhook when you get the result from the AMD.
That webhook will receive paramters including the CallSid and your AccountSid and most importantly the AnsweredBy parameter. When using DetectMessageEnd for your AMD, the AnsweredBy parameter could be any of "machine_end_beep", "machine_end_silence", "machine_end_other", "human", "fax" and "unknown".
For the machine results, if you want to leave a message you will now need to update your call with new TwiML.
var call = CallResource.Update(
twiml: new Twiml(MACHINE_MESSAGE),
pathSid: CALL_SID
);
Let me know if that helps at all.
I am creating a Twilio based application that will receive the Voicemail if the call is not picked up.
For now, I had set up the incoming call URL in the console against the phone number.
<?php
header('content-type: text/xml');
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
error_reporting(E_ALL);
ini_set('display_errors', 1);
file_put_contents('incoming_call.log', "\n" .json_encode($_REQUEST) . "\n", FILE_APPEND);
?>
<Response>
<Dial timeout="15" action="/voicemail.php">
</Dial>
</Response>
Whereas my voicemail.php file will has to code
<?php
// echo "hello ";exit;
header('content-type: text/xml');
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
file_put_contents('incoming_voicemail.log', "\n" .json_encode($_REQUEST) . "\n", FILE_APPEND);
?>
<Response>
<Say voice="alice">Your call could not be answered at the moment. Please leave a voice message.
</Say>
<Record></Record>
</Response>
I am not receiving the voicemail. Where can I setup the recordingStatusCallback attribute in twiml?
Secondly, I am trying to send voicemail from Twilio number to phone number by dialing One calling and again dial a Second call as the second call will receive a busy status and we are able to send a voicemail, but it's not working. My code is
$call = $twilio->account->calls->create(
$phone_no, // To
$from_no, // From
array(
"method" => "GET",
"statusCallback" => SURL . "voicemail?to_phone_no=" . $phone_no,
"statusCallbackEvent" => ["initiated","ringing"],
"statusCallbackMethod" => "POST",
"twiml" => '<Response><Say>Testing voicemail</Say></Response>'
)
);
sleep(3);
$call2 = $twilio->account->calls->create(
$phone_no, // To
$from_no, // From
array(
"url" => AURL.'Vm/audio_file'
)
);
Please guide me what I am doing wrong. For help thanks in advance.
Twilio developer evangelist here.
For your first question, if you don't include a number (or a SIP address, or a Client identity) to try to connect to, then the <Dial> will move straight on to the action URL, without bothering with the timeout.
If you want the <Dial> to try to connect to a phone, then you should add a phone number.
Second, if you want to receive a webhook when the recording is complete, then you need to add the recordingStatusCallback attribute, with a URL to send the webhook to, to your <Record>, e.g.:
<Response>
<Say voice="alice">Your call could not be answered at the moment. Please leave a voice message.
</Say>
<Record recordingStatusCallback="/recording-complete.php"></Record>
</Response>
Finally, we do not support the final use case of trying to dial a number twice in order to block it up and then leave a voicemail. Making calls and then dropping them is against the terms of service (see point 19 under "prohibited services". So I encourage you to consider a different way to reach out to your customers or contacts that engages with them in a legitimate way.
How to dial numbers and diffuse a music to the caller while waiting a successful connexion ?
The code below waits the music to end before doing the <dial> (which is logic)
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Play>http://com.twilio.music.ambient.s3.amazonaws.com/gurdonark_-_Plains.mp3</Play>
<Dial timeout="10" callerId="+1234567890">
<Number url="whisper?id=1">+1122334455</Number>
<Number url="whisper?id=2">+1122334466</Number>
<Number url="whisper?id=3">+1122334477</Number>
</Dial>
</Response>
NB: It would be nice NOT to use conference functionalities. Something with <Enqueue> maybe ?
Twilio developer evangelist here.
You could do this with <Enqueue>. Here's how it would work:
You would need replace the TwiML that <Play>s and then <Dial>s. This would have to be a dynamic action as you would need to make the three simultaneous calls using the REST API instead of TwiML. The TwiML that you would return would put your original caller into a queue as you suggest and play them music. In PHP that would look a bit like:
<?php
// Get the PHP helper library from twilio.com/docs/php/install
require_once '/path/to/vendor/autoload.php';
use Twilio\Rest\Client;
// Your Account Sid and Auth Token from twilio.com/user/account
$sid = "your_account_sid";
$token = "your_auth_token";
$client = new Client($sid, $token);
$numbers = array('+1122334455', '+1122334466', '+1122334477');
foreach ($numbers as $number) {
$call = $client->calls->create(
$number, $YOUR_CALLER_ID,
array("url" => "http://example.com/dial_queue")
);
}
header("content-type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
?>
<Response>
<Enqueue waitUrl="http://com.twilio.music.ambient.s3.amazonaws.com/">
dialling
</Enqueue>
</Response>
At the URL http://example.com/dial_queue you would need to return TwiML that dials the callee into the original caller. You have a whisper URL in your original example, which you can achieve by inlining that into the TwiML.
<Response>
<Say>Your custom message</Say>
<Dial>
<Queue>dialling</Queue>
</Dial>
</Response>
Note that you dial the name of the <Queue> that you used in the original <Enqueue>. If this system will be used for more than one caller, then you probably need to generate unique queue names for them.
The final things to do would then be to cancel the other two calls once a call connects and cancel the queue if none of the calls answer. I will leave that to you as I'm sure there's many ways you could achieve it with your own setup.
Let me know if that helps at all.
I am using the call screening example at https://www.twilio.com/docs/howto/callscreening
When I place a call to my incoming Twilio number via landline, it is forwarded to my mobile and I am prompted to "press a key to accept"
Problem is that as soon as I answer it on my mobile the incoming call stops getting the ringing tone and has silence until about 5 seconds after I press any key.
As soon as I answer the call on my mobile the user is presented with silence and has the impression that the call has been answered but it is not until I have pressed a key to accept the call and further until Twilio does its hookup of the call, that is the point that I can talk to the person.
Could I present them with music or a ringing tone until the cal really has been connected to me?
Here is the code of the forwarding
<?php
// Set the numbers to call
$numbers = array("<number to call 1>", "<number to call 2>", "<number to call n>");
$number_index = isset($_REQUEST['number_index']) ? $_REQUEST['number_index'] : "0";
$DialCallStatus = isset($_REQUEST['DialCallStatus']) ? $_REQUEST['DialCallStatus'] : "";
header("content-type: text/xml");
// Check the status of the call and
// that there is a valid number to call
if($DialCallStatus!="completed" && $number_index<count($numbers)){
?>
<Response>
<Dial action="attempt_call.php?number_index=<?php echo $number_index+1 ?>">
<Number url="screen_for_machine.php">
<?php echo $numbers[$number_index] ?>
</Number>
</Dial>
</Response>
<?php
} else {
?>
<Response>
<Hangup/>
</Response>
<?php
}
?>
And the part that asks me to accept the call
<?php header("content-type: text/xml");
echo '<?xml version="1.0" encoding="UTF-8"?>';
?>
<Response>
<Gather action="complete_call.php">
<Say>Press any key to accept this call</Say>
</Gather>
<Hangup/>
</Response>
Twilio Customer Support here.
What I would recommend is that you place the incoming caller into conference, this would allow you to use the waitURL parameter to play hold music whilst your agent decides to take the call:
https://www.twilio.com/docs/howto/simple-conference
I'm trying to build a voicemail inbox feature, but whenever I use twilios voicemail functionality, once the user records after the beep, the call hangs up.
Is there any way to let the user hear what they said before saving it?
Twilio developer evangelist here.
When you use the <Record> verb in TwiML, you should add the attribute "action" with a URL for what to do once the recording is done. That action URL will receive a request once the recording is finished with the attributes of the recording, that is the recording URL and duration and any digits the caller pressed to end the recording.
If you return more TwiML from this action, then the call will continue and you will be able to do things like repeat the recording, like you want.
So, for example (with a pseudo templating language) your <Record> TwiML might be at the path /record and look like:
<Response>
<Record action="/repeat" />
</Response>
Then your /repeat URL would look something like this:
<Response>
<Say>Your message was:</Say>
<Play>{{ recordingUrl }}</Play>
<Gather numDigits="1" action="/choice">
<Say>Press 1 to record the message again or press 2 to save your message</Say>
</Gather>
</Response>
Then finally your /choice action:
<Response>
{{ if Digits == '1' }}
<Redirect>/record</Redirect>
{{ else }}
<Say>Thank you for your message</Say>
<Hangup />
{{ end }}
</Response>
I hope that helps! Let me know if there's any other way I can help.