Play music while waiting an answer in TWIML <dial> - twilio

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.

Related

Call an URL for get phone number to forward the Twilio call using TwiML

I'm trying to automate call forwarding using Twilio. when the user calls the Twilio number it will play some welcome message then it should call an external API, The API will return a phone number the Twilio should call the number. I'm trying to do with this TwiML. here is my TwiML bin document
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Pause length="1"/>
<Say voice="Polly.Joanna"> Welcome
</Say>
<Dial> HERE THE NUMBER SHOULD COME THAT API WILL RETURN
</Dial>
</Response>
for example https://getmynumber/samplenumber is the URL that will return a number. How can I achieve this with TwiML?
and is it possible to define a variable inside TwiML? because if i can save the number to that variable using the <Redirect> tag I can achieve this easily.
is it possible?
That'll be difficult with only TwiML Bin but you could try something like:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Pause length="1"/>
<Say voice="Polly.Joanna">Welcome</Say>
<Dial>{{Number}}</Dial>
</Response>
And then call it via: https://<your TwiML Bin URL>/...?Number=+123456789
This passes custom values into a TwiML Bin, here Number.
If you really need to call an API to get the number to dial you'll need some kind of endpoint to form the TwiML, e.g. a Twilio Function, or any other endpoint.
A version in Python could look like this:
from twilio.twiml.voice_response import VoiceResponse
response = VoiceResponse()
response.pause(length=1)
response.say('Welcome')
number = '+123456789' # Here you would do an API call
response.dial(number)
print(response)
The above basically creates the TwiML you have in your TwiML Bin but with Python. You would need to wrap this in an endpoint to be able to be called and returned. And of course you would need to add your logic to retrieve the number via the API.

How to Receive and Send voicemail from/on Twilio number?

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.

programmatically set room id in a Twilio conference

Does anyone know the best way to programmatically set the name/id of the conference room in the Twilio noun ?
<Response>
<Say>Joining a conference room</Say>
<Dial>
<Conference>MyRoom</Conference>
</Dial>
</Response>
My system will dole out new conference room ID's, dynamically, to keep the conferences small but I'm not sure how to associate the assigned user's room id in the to twiml app's code...
Ricky from Twilio here. Wanted to add some example code for anyone who may stumble on this question.
You need to return TwiML to give Twilio the instructions of what to do with a call but you can generate that TwiML however you'd like. For example, here is a simple PHP script that returns TwiML that places callers in a random conference room.
<?php
header("content-type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
?>
<Response>
<Say>Joining a conference room</Say>
<Dial>
<Conference>Room<?php echo rand(0,2); ?></Conference>
</Dial>
</Response>

Twillio Call Screening silence on answer

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

Announcing the name of participant joining the Conference

I am building a simple conference using Twilio where a conference is started by Agent using Twilio client and a contact is called and added to this conference. Just before adding this contact to conference, we would like to announce the name of the contact in the conference room (for ex: <Say>Now Joining Sam Carter </Say>). The name of the person is figured out based on their phone number from database.
When a call is connected, the following TwiML is executed which connects the contact to the conference:
<Dial callerId="+1415xxxxxxx" record="true" action="/my/action/url">
<Conference endConferenceOnExit="true" >ConferenceRoom1</Conference>
</Dial>
Is there any way to play a message into conference just before <DIAL> verb is executed. If i write <SAY> verb before <DIAL> then it plays message to the contact, not in the CONFERENCEROOM1.
Are there any events like onConferenceEnter, which can be used to fire another TwiML whenever some participant enters the conference? Please suggest what would be the best way to achieve this behavior.
The short answer to the question is that it can't be done through a Twiml Event however it can be done with a kind of hack using their REST API.
The question has already been asked on SO and the answer is available here:
Use Say verb to all Conference participants
Incase the question/answer is ever deleted/removed i've pasted it below:
Here's something that should resemble a good end-to-end solution.
First, the user dials in and you go through the standard prompts to get the PIN for the conference room and their name.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather action="/conference/pin" finishOnKey="#">
<Say>Please the conference pin number followed by the pound key.</Say>
</Gather>
</Response>
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Say your name and then press the pound key.</Say>
<Record action="/conference/name" finishOnKey="#" />
</Response>
Now, once you have the user's pin and recording, two things will happen; the response from the post to /conference/name will contain the verb, placing the user in the room:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial>
<Conference>{conference ID}</Conference>
</Dial>
</Response>
...and, asynchronous to that, it will use the REST API to initiate a new call back into the conference room.
POST /2010-04-01/Accounts/{AccountSid}/Calls
From = {your conference phone number}
To = {your conference phone number}
SendDigits = wwww{conference PIN}#
Url = /conference/announce?name={name ID}
Now, the next bit gets confusing. Twilio will now be talking to your callback URL for the incoming end of the call, and the URL you specified above for the outgoing end of the call. Your incoming call handler will need to detect that the conference line is calling back into itself and behave differently; it will first need to respond with simple TwiML that allows the outgoing end of the call to enter the pin for the conference room.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather action="/conference/announce-pin" finishOnKey="#" />
</Response>
The SendDigits parameter of the POST will provide the digits that bit of TwiML is expecting. That action should then respond by conferencing in the new call.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial>
<Conference>{conference ID}</Conference>
</Dial>
</Response>
The last piece of the puzzle is the TwiML emitted by the URL you specified in the POST. That's the markup that will run once the loopback call is added to the conference.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Play>/conference/name-recordings/{name ID}</Play>
<Say>has joined the call.</Say>
<Hangup />
</Response>
That markup runs, plays the caller's name and a message into the conference room, and then hangs up.
For benefit of others, this is how I have implemented this behavior :
An agent has started the conference using Twilio client and he is already in conference. As soon as a participant is about to join the same conference, using REST API, modify the URL of the live conference call.
TwilioRestClient client = new TwilioRestClient(ACCOUNT_SID, AUTH_TOKEN);
Map<String, String> filter = new HashMap<String, String>();
filter.put("From", "client:AGENT1");
filter.put("Status", "in-progress");
CallList callList = account.getCalls(filter);
Call agentsCall = null;
for (Call inProgressCall : callList) {
agentsCall = inProgressCall;
break; //return the first one only..there shouldn't be more
}
Map<String, String> agentsCallParams = new HashMap<String, String>();
agentsCallParams.put("Url", "http://myserver.com/twiml/agentmessage.xml");
agentsCallParams.put("Method", "GET");
agentsCall.update(agentsCallParams);`
The above code snippet will update the twiml of existing call as below.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Now joining {name of the participant}</Say>
<Dial>
<Conference>Conference1</Conference>
</Dial>
</Response>
The above Twiml will update the call to play the message in <SAY> verb and then put the agent back into the conference.
Now, make the participant join the same conference by returning the below Twiml:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial>
<Conference>Conference1</Conference>
</Dial>
Hope this helps !!!

Resources