Twiml discarding voice, loop in SAY verb inside GATHER - twilio

I have an API which first creates a call to a number using the C# wrapper, lets say the receiver is +1000000001
var call = CallResource.Create(new PhoneNumber("+1000000001"),
new PhoneNumber("MYVERIFIEDNUMBER"),
url: new Uri("https://api.com/answered"),
method: HttpMethod.Get,
client: _client,
sendDigits: ""
);
When answered the TWIML returned from https://api.com/answered is
<?xml version="1.0" encoding="utf-8"?>
<Response>
<Gather action="https://api.com/connect/6AE3045C0D024F1896BF7ECFCB2FC40A" method="GET">
<Say voice="alice" loop="0" language="en">Press any key to connect to John Doe, , </Say>
</Gather>
</Response>
This should result in an infinite loop in the voice of "alice" for the SAY verb being repeated to the receiver at +1000000001 but it is a male robotic voice and it only repeats once then drops the call. This is first part of the issue.
The second part is the GATHER verb does nothing. I should be able to press a touch tone phone and have the url https://api.com/connect/6AE3045C0D024F1896BF7ECFCB2FC40A return
<?xml version="1.0" encoding="utf-8"?>
<Response>
<Dial>client:6AE3045C0D024F1896BF7ECFCB2FC40A</Dial>
<Hangup></Hangup>
</Response>
which it does on the GET request but I can never get to it because of the GATHER issue
The third part is does this look correct to dial a client app?
<Dial>client:6AE3045C0D024F1896BF7ECFCB2FC40A</Dial>
Thanks for any advice

Looks like Alice defaults to en-US so you can leave the language attribute off. Also, can you make sure you are returning TwiML with the right MIME type, https://www.twilio.com/docs/voice/twiml#twilio-understands-mime-types.
Client is used inorrectly, refer to the TwiML syntax here, https://www.twilio.com/docs/voice/client/twiml.
Let me know if that addresses the issue.

Related

How do I modify a in-progress call by sending a digit with Twilio-Python?

I have an app that makes a outbound call to user A.
User A answers and either says "foo" or "bar"
If User A says "foo" -> c.calls(callSid).update(status="complete")
If User A says "bar" -> twilio.update('press the number 2')
How can I implement this?
I'm using the Python helper library and have tried this.
call = c.calls(callSid).update(twiml="<Play digits='2'/>")
But the app errors out.
In your outbound call use TwiML to ask the user to say "foo" or "bar" and then supply a webhook which can be called to process the response, i.e.:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather input="speech" timeout="5" action="<your webhook>">
<Say>Please say foo or bar.</Say>
</Gather>
</Response>
Twilio will do a POST to the specified webhook in action and the user answer will be stored in SpeechResult along with a confidence score in Confidence. You can then continue with your business logic as you outlined.
For more information on Gather have a look at the TwiML documentation.

Twilio TwiML How do I pass URL parameters to TwiML script?

I want to pass a parameter via URL for TwiML to read from when it addresses the person on the other end of the phone. I can't seem to get it to work right. I've tried all sorts of things.
Here is my ASP.NET VB Code...
Dim XClient As New TwilioRestClient(accountSid:=accountSID, authToken:=authToken)
XClient.InitiateOutboundCall(from:=From, [to]:=SendTo, url:="http://mywebsite.com/TestURI.xml?test=Todd")
Here is my XML...
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say voice="alice">$test</Say>
<Pause length="1"/>
<Say voice="alice">Do you enjoy hotdogs? I do.</Say>
<Pause length="1"/>
<Say voice="alice">Please work so that I can enjoy my lunch in peace!</Say>
</Response>
How do I get this TwiML script to report "Todd" from the URL? Any help is much appreciated. Thank you!
TwimL Bins has has the concepts of templating you can leverage (and also not have to host the TwiML on your own servers).
How to use templates with TwiML Bins
https://support.twilio.com/hc/en-us/articles/230878368-How-to-use-templates-with-TwiML-Bins
Pass in the URL parameter and then reference it in the TwiMLBin as a Template.
<Say>{{Test}}</Say>
You can also use Twilio Functions (Node),https://www.twilio.com/console/runtime/functions/manage, with JavaScript ES6 template literals to do similar:
exports.handler = function(context, event, callback) {
let twiml = new Twilio.twiml.VoiceResponse();
let testParam = event.test;
twiml.say(`Hello ${testParam}`);
callback(null, twiml);
};
What you'll need to do is generate a dynamic XML (TwiML) response that can incorporate any query parameters into the XML response. I don't know ASP.NET or Visual Basic very well, but most web programming languages have a way to generate dynamic responses in response to HTTP requests.
Here's an example in the Twilio docs of how to generate a TwiML response from an ASP.NET MVC application - it might not be precisely the same technology you are working with, but it might help you get pointed in the right direction:
https://www.twilio.com/docs/voice/quickstart/csharp?code-sample=code-make-an-outgoing-call-using-twilio-and-c&code-language=C%23&code-sdk-version=5.x

TwiML If User hang up

I am using the following TwiMl code to record a user over the phone:
<Response>
<Record action="#nextPageUrl" maxLength="15" method="GET" trim="trim-silence" finishOnKey="*" />
</Response>
I would like to do something if the user hang up and not pressed * to end the recording. I am looking for something like ifHangUp:
<Record ifHangUp="#someUrl" action="#nextPageUrl" ....
Does twilio support something like this?
If you look at the twiml documentation page: https://www.twilio.com/docs/api/twiml/record you'll see the request sent after in may include the value "hangup" in the "Digits" parameter for the case where the caller hung up the the "action" set. I believe this should provide you a way of detecting a hangup vs a "*".
Basically, for an implementation have a conditional statement on #nextPageUrl examine the the Digits parameter and use a redirect tag to #someUrl if Digit = 'hangup'

Twimlet that will forward request parameters to next verb

I have this conceptual Twiml that I want the echo twimlet to provide:
<Response>
<Record timeout="10" method="GET" action="http://someURL" />
<Redirect>http://twimlets.com/forward</Redirect>
</Response>
My intent is to use this for outbound dialing, so that the calls that are being made are recorded. The issue is that the request parameters are sent to the echo Twimlet containing the To, From, CallerID, etc. but I really need them passed to the url in the Redirect verb. Is that possible using the echo Twimlet?
Twilio developer evangelist here.
You don't actually need to do this in order to record a two legged call. The <Record> verb is used to record messages, for example a voicemail service.
If you are generating these calls using the REST API, then you can set the call to record in the API call, like this (example in Node.js, I see you've answered some SO questions with Node):
var accountSid = 'AC...';
var authToken = "{{ auth_token }}";
var number1 = '+1555123456';
var number2 = '+1555456789';
var twilioNumber = '+1555654321';
var client = require('twilio')(accountSid, authToken);
client.calls.create({
url: "http://twimlets.com/forward?PhoneNumber=" + encodeURIComponent(number2),
to: outboundNumber,
from: twilioNumber,
record: true
}, function(err, call) {
process.stdout.write(call.sid);
});
You can also give that call a statusCallBack URL that the recording will be POSTed to after the call.
If you are not generating the call from the REST API but you still want to record both sides of the call. You need to use the <Dial> verb and set to record that way. You need to create some TwiML at a URL your Twilio number points to that looks like this:
<Response>
<Dial record="record-from-answer">
{{ onward number }}
</Dial>
</Response>
If you supply an action attribute to the <Dial> verb then once the call is done Twilio will POST the URL of the recording to the action.
I'm not exactly sure how you'd accomplish this with Twimlets. Ideally you want to be able to set the URL that the recording URL is sent to and save it somehow, but you'd need your own server for that. It would be possible to create any of the resulting TwiML you'd need using the echo Twimlet, but it may be better to consider your own server at this point.
Let me know if this helps at all.

Dialing Fallback with Twilo

I am working on my inbound TwiML. At one point I want to attempt to forward a call to my cell phone number.
So I got 5555555555 but I want to redirect to a different TwiML script if there is no answer or no human answer. For example if I do not answer and Twilo gets my Cell VM, I would instead want to have Twilo try someone else in another TwiML script rather than let them leave a message on my personal VM.
I know I can set it up so I have to press 1 to connect the call, then I am assuming if I don't press 1 it would continue processing the TwiML after is this possible without requiring me to press 1?
Joel from Twilio here.
The best way to do what you want is to use the call screening process that you describe ("press 1 to connect the call"). This is because automatically detecting voice mail is a very error prone process.
We have an in-depth Call Screening HowTo on how to do this. Here's the overview:
Create a file called "attempt_call.php" on your web server that contains the following code (pay particular attention to the $numbers array on line 4):
<?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.xml">
<?php echo $numbers[$number_index] ?>
</Number>
</Dial>
</Response>
<?php
} else {
?>
<Response>
<Hangup/>
</Response>
<?php
}
?>
Next, in the same location as the "attempt_call.php" file, create a file called "screen_for_machine.xml" with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather action="complete_call.xml">
<Say>Press any key to accept this call</Say>
</Gather>
<Hangup/>
</Response>
Then, in the same location as the "attempt_call.php" file, create a file called "complete_call.xml" that contains the following:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather action="complete_call.xml">
<Say>Press any key to accept this call</Say>
</Gather>
<Hangup/>
</Response>
Finally, set the "Voice Request URL" on your Twilio number to the full publicly available URL for the "attempt_call.php" file you created.
For more details, all of this code above is also available with mode in-depth explanation on the Call Screening HowTo which is available on our website.

Resources