Twimlet that will forward request parameters to next verb - twilio

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.

Related

Unable to get custom parameters passed using Twilio connect function for outgoing and incoming calls

Am trying to create a call center with Twilio, am almost there but now am stuck because i can't get custom passed parameters.
My main aim is to allow customers to call but first they should provide their emails and names first, then click call-customer button, i want to receive the custom parameters on the agent's side.
Now i try to pass the parameters but i can't retrieve them.
Here is my code to make and receive calls and to pass and get the parameters
(Customer side)This code allows outgoing calls, customers to make calls to the call-center agents
require __DIR__ . '/vendor/autoload.php';
use Twilio\Jwt\ClientToken;
$accountSid = '';
$authToken = '';
$appSid = '';
$capability = new ClientToken($accountSid, $authToken);
$capability->allowClientOutgoing($appSid);
$token = $capability->generateToken();
So according to the documentation i should pass the custom parameters like this:
var params = {"name": "John", "email": "john#gmail.com"};
Twilio.Device.connect(params);
(Agent side) This code allows incoming calls from customers to agents.
$accountSid = '';
$authToken = '';
$capability = new ClientToken($accountSid, $authToken);
$capability->allowClientIncoming('joey');
$token = $capability->generateToken();
In the agent side i use this code to receive customer information or custom parameters.
According to the documentation a code to get custom parameters is this:
if (connection.customParameters.hasOwnProperty("name")) {
let displayName = connection.customParameters.get("name");
console.log(displayName)
}
if (connection.customParameters.hasOwnProperty("email")) {
let customerID = connection.customParameters.get("email");
console.log(customerID)
}
but i get undefined
So when a customer calls this twilio function en-queues the call and assign it to an operator
here is the code:
exports.handler = function(context, event, callback) {
let twiml = new Twilio.twiml.VoiceResponse();
twiml.say(" Please hold, while we connect you to one of our available agent ");
twiml.enqueue({
workflowSid: context.WORKFLOW_SID
}).task({}, `{"selected_skill":"operator"}`);
callback(null, twiml);
};
Then from here an available operator will accept the task then dial an agent
The operator dials the client like this
{"skills":["operator"],"contact_uri":"client:joey"}
Please help
Thanks in advance
Based on my take on the associated documentation, it looks like the parameters are only sent to the Twilio client via TwiML, as shown here.
https://www.twilio.com/docs/voice/client/javascript/changelog#160-aug-29-2018
Added support for custom incoming parameters from TwiML as Map Connection.customParameters. When a TwiML application sends
custom parameters using the noun, these parameters will be
added to Connection.customParameters
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial>
<Client>
<Identity>alice</Identity>
<Parameter name="foo" value="bar"/>
<Parameter name="baz" value="123"/>
</Client>
</Dial>
</Response>
It sounds like you are using the Task Router JavaScript SDK, maybe you can add these parameters as attributes to the task, and then access those tasks from the Task Router client SDK?

Twiml discarding voice, loop in SAY verb inside GATHER

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.

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

Twilio: programmatically join conference and play <Say> command or <Play> sound file?

I have two users and I joined them both into a <Conference>.
I would like to have a robot join the <Conference> and then make an announcement.
There are two approaches I'm considering:
Take everyone in the conference, redirect them to a TwiML that plays a sound, and then move them back into the Conference.
Create a bot that somehow joins the Conference and plays TwiML, but it's not clear for me, from the documentation, how to do that.
Twilio developer evangelist here.
Either of those approaches will work, though will have slightly different effects. Redirecting will cut the conference regardless of who is speaking at the time, but a bot joining in may get spoken over. It depends on which will work better for your use case.
To do the redirect, you'll need to run through the list of Conference participants, redirect them by updating their call to a new URL and return TwiML from that URL that plays the sound and redirects back to your original Conference URL. Something like:
$sid = "{{ account_sid }}";
$token = "{{ auth_token }}";
$client = new Services_Twilio($sid, $token);
// Loop over the list of participants and redirect ($client->account->conferences->get(CONFERENCE_SID)->participants as $participant) {
$call = $client->account->calls->get($participant->call_sid);
$call->update(array(
"Url" => "http://example.com/conference_message"
));
}
Then your /conference_message endpoint would need TwiML like this:
<Response>
<Play>http://example.com/message.mp3</Play>
<Redirect>http://example.com/conference</Redirect>
</Response>
On the other hand, having a bot enter the room requires you to create a call to the conference number and supply a URL which points to the TwiML to play the message and then hangup. Like this:
$sid = "{{ account_sid }}";
$token = "{{ auth_token }}";
$client = new Services_Twilio($sid, $token);
$call = $client->account->calls->create(A_TWILIO_NUMBER, THE_CONFERENCE_NUMBER, "http://example.com/conference_message");
Then your /conference_message endpoint would return TwiML like this:
<Response>
<Play>http://example.com/message.mp3</Play>
<Hangup/>
</Response>
Let me know if this helps at all.

Pass Inbound call between twilio clients

i have several twilio client users
Sky - Kevin - Paul
A twilio registered number connects to callsky.xml by default / that code looking like.
<Response>
<Dial>
<Agent>sky</Agent>
</Dial>
</Response>
a call comes in and goes to sky, she then wants to pass that call over to Kevin or Paul.
how is this possible ?
tried:
$caid = $_REQUEST["CallSID"];
$client = new Services_Twilio($sid, $token);
$call = $client->account->calls->get($caid);
$url = 'http://thesite.com/twiml.xml';
$call->update(
'Url' => $url,
'Method' => "GET",
);
This is executed through Ajax, when sky presses a button with the destination users name on it.
<button onclick="divert('kevin')">Kevin</button>
Also: Oddly, the update command shows as a syntax error in my IDE.
Twilio evangelist here.
The update method takes an array, so that might be causing the syntax error:
https://www.twilio.com/docs/api/rest/change-call-state
I'd also recommened checking out the AppMonitor (https://www.twilio.com/user/account/developer-tools/app-monitor) to see if Twilio is logging and errors when trying to retreive the TwiML from your URL.
The URL you point the call at can return static XML, or you ca ndynamically generate it using the PHP helper library. Here is an example of using the <Dial> verb to dial a Client instance:
$response = new Services_Twilio_Twiml;
$dial = $response->dial(NULL, array(
'callerId' => '+14152223333'
));
$dial->client('client-id');
print $response;
This will output TwiML that looks like:
<Response>
<Dial callerId="+14152223333">
<Client>client-id</Client>
</Dial>
</Response>
Hope that helps.

Resources