Can Twilio IVR record a single answer? - twilio

I'm looking to build an integration with Twilio and here's a brief outline of what I want to do:
1) Prompt the caller with a numeric (verbal FTW) menu of options
- "Press 1 for X, 2 for Y"
2) Prompt the caller to leave a recording
- e.g., "Leave a message and press # or hang up"
3) Access a recording (mp3) of JUST the answer for #2
Thanks

Twilio developer evangelist here.
You can absolutely do that! In order to do so, you'll need to provide a series of URLs that respond with TwiML to tell Twilio what to do with the call.
Firstly, you'll need to set up a Twilio number so that an incoming call is directed to your first webhook URL. You'll need to do this in your Twilio console.
Then, your first webhook URL needs to produce the menu of options. This is typically called an IVR and we have a couple of tutorials that show you how to build one in depth here: IVR: Screening and Recording and IVR Phone tree (I've linked to the Ruby/Rails versions of the tutorials here, but there are other languages available, just check the tutorials page).
Essentially though, you need to use the <Say> and <Gather> verbs from TwiML to read out the options and respond to the results. For example:
<Response>
<Gather numDigits="1" action="/gather_results">
<Say voice="alice">Dial 1 to leave a message, Dial 2 to hangup</Say>
</Gather>
</Response>
The action attribute on the <Gather> element points to where the caller should be directed once they enter a digit. At that point you need to write something dynamic that extracts the Digits parameter from the request. If the number responds to the recording action then you can use the <Record> verb to record just that answer.
I've written the below as if it were using Sinatra and Ruby, but hopefully it shows how this would be used in any language.
def gather_results
if params["Digits"] == "1"
"<Response finishOnKey='#'>
<Say voice="alice">Leave a message and press # or hang up</Say>
<Record action="/record_results"></Record>
</Response>"
else
# Do something else
end
end
Finally, you need something to get the recording once it is complete. This final URL lives at the endpoint described in the action attribute for the <Record> verb. This URL will receive extra parameters that refer to the recording, including the URL of the recording file itself. You can write any code you like here, either just saving the URL of the recording or downloading the file itself.
Hope this helps, let me know if there's anything that isn't clear.

Related

Twilio - Transfer an Inbound Call

I am having alot of trouble wrapping my brain around how to transfer an inbound call using Twilio. The idea is:
Call Comes In
Call is Connected to A Receptionist
Receptionist Greets and Dials Extension - Presses #.
Caller is transferred to the specified # / sip device.
I have implemented a portion of this flow. I used conference tag on the initial call in to force the caller into a room with hold music, and as that call comes in I dial the receptionist and then have the receptionist join the conference. This works perfectly.
What I cant figure out is how to grab the input from the receptionists phone and then act on it. For example, if the receptionist pushes #200* (or something to that effect), I want extension 200 dialed, and the caller in the conference put back on hold until the transferred party answers (all of which should be easy once I can grab the input and act upon it).
Any help on this is appreciated.
Thanks.
Twilio developer evangelist here.
Thanks for the extra detail in the comments. Your receptionist is dialed into a conference to deal with the incoming call using startConferenceOnEnter to stop the hold music and make the connection. This is a good start.
You say you also have endConferenceOnExit for the receptionist. I would remove that because in order to achieve this we are going to want to remove the receptionist from the conference and leave the caller in it while we sort out the transfer.
So, instead you're going to want to add hangupOnStar to your receptionist's TwiML. When the receptionist hits * the call with either request the action attribute for the original <Dial> or, if that is not present, will continue to the next TwiML verb after <Dial>. Either way, this is where you want to include a <Gather input="dtmf">. This will start Twilio listening for keypad tones.
Your receptionist can then dial the extension to connect to and press # to finish (the default finishOnKey. This will send a webhook to the action attribute of the <Gather> with the Digits in the body of the request. You can then pick those Digits out and initiate a new call to the user with that extension. When that call connects you can then drop them into the original conference.
So, that should look a bit like:
Receptionist TwiML:
<Response>
<Dial hangupOnStar="true">
<Conference startConferenceOnEnter="true" endConferenceOnExit="false">CALLERS_CONFERENCE_ID</Conference>
</Dial>
<Gather action="/transfer" input="dtmf" finishOnKey="#">
<Say>Please enter the extension you want to dial</Say>
</Gather>
</Response>
Then the /transfer action should, in pseudo code, do something like:
/transfer
def transfer
extension = params["Digits"]
twilioClient.calls.create( to: getNumberFromExtension(extension), from: TWILIO_NUMBER, url: "https://example.com/connect" )
return "<Response><Hangup/></Response>" # this hangs up the receptionist
end
Finally, the /connect endpoint referenced in the new call above should return TwiML to drop the new caller into the conference:
<Response>
<Dial>
<Conference startConferenceOnEnter="true" endConferenceOnExit="true">CALLERS_CONFERENCE_ID</Conference>
</Dial>
</Response>
You could even make the /connect endpoint the same as the original receptionist TwiML, which would allow the next person on the call to also transfer out by pressing * and dialling another extension.
Let me know if this helps at all.

Dynamic destination phone assign, at incoming call start

I am looking into the possibility to implement call tracking with Twilio.
What I would need is that right at the start of an incoming call I would like to be able to change the destination number for that call.
How is this achievable with Twilio via API?
Reading the API docs I found the that there is a real-time call and message routing feature (here) and followed the example (here) but it's not what I would like to achieve.
Thanks ahead for any suggestion and help!
--Steve
Twilio developer evangelist here.
You absolutely can dynamically change the destination number for calls on Twilio. When you are forwarding calls you use the <Dial> noun in TwiML like so:
<Response>
<Dial>YOUR_NUMBER_HERE</Dial>
</Response>
However, if you serve your TwiML dynamically you can return whatever number in the <Dial> tag that you want, based on whatever conditions you want. For example in Ruby using Sinatra:
post "/voice" do
if params["From"] === SOME_SPECIAL_NUMBER
number = FORWARDING_NUMBER_1
else
number = FORWARDING_NUMBER_2
end
"<Response>
<Dial>#{number}</Dial>
</Response>"
end
Let me know if this helps at all.

Customize Twilio's click-to-call, transcribe and collect statistics

I'm using Java but the question is language-agnostic, so I posted it under twilio-PHP tag too.
My application needs to connect two customers: A and B. I want to transcribe the conversation and find out whether one of the parties did not pick up and screened the other to voicemail.
I'm following the steps in the click-to-call-tutorial
However, it looks like the Rest API supports recording but not transcription. I successfully can do:
Map<String, String> params = new HashMap<String, String>();
params.put("From", myTwilioNumber);
params.put("To", customerAPhoneNumber);
params.put("Url", "http://MyHandler.jsp");
params.put("IfMachine", "Hangup");
params.put("Record", "true");
Call call = client.getAccount().getCallFactory().create(params);
which gets the entire conversation recorded, but not transcribed!
As a side note -
params.put("IfMachine", "Hangup");
indeed hangs up, when reaches voicemail, but not before leaving a voicemail with random noise. Looks like Twilio's "probing" the response, and by the time it understands it got to voicemail, background noises have been recorded. Which is terrible user experience. Any advice?
Additionally, my call handling servlet does:
TwiMLResponse twimlResponse = new TwiMLResponse();
Say sayMessage = new Say(
"Hi, customer A, stay on line to speak with customer B?");
twimlResponse.append(sayMessage);
Dial dial = new Dial(customerBPhoneNumber);
twimlResponse.append(dial);
But when I'm looking at the TwiML Verbs , there is no place where I can set params.put("IfMachine", "Continue") . So the field call.getAnsweredBy() is null for the second call. In other words, I cannot know whether conversation between customer A and B ever happened.
Additionally, [TwiML Verb Record] ( https://www.twilio.com/docs/api/twiml/record ) does allow transcription, but if I do
twimlResponse.append(new Record());
it stops the conversation and records one of the customers.
So I cannot direct the REST API to transcribe, and TwiML Verbs does not even record the conversation in a way I want.
Can anyone help?
Thanks.
Twilio developer evangelist here.
I'm afraid that when recording both legs of a call, using the REST API, then transcription is not available. Transcription is only available on single messages recorded by the <Record> verb when the recording is under 2 minutes long.
I'd recommend recording the call and downloading the file to be sent off to a third party transcription service in order to transcribe longer, 2 legged calls like that.
In terms of the answering machine detection, it is an experimental feature and requires Twilio to listen to the first few seconds of a call to work out whether it is a machine or not. A good alternative, which can work as part of your <Dial> verb as well, is to use call screening. This is a good article on the pros and cons of AMD, as well as a good description of using human detection by call screening.
Let me know if this helps at all.

Twilio connection parameters missing "To" parameter

I'm developing a Rails Twilio-based application and want to show to my user the number that the caller is calling (because in my application, a user can be associated with multiple numbers).
Here's the code:
Twilio.Device.incoming (conn) ->
$("#log").text("Receiving call from:" + conn.parameters.From)
$("#log").text("Calling to:" + conn.parameters.To)
ringtone.play()
$('.answer').click ->
ringtone.pause()
# accept the incoming connection and start two-way audio
conn.accept()
However, the conn.parameters object does not have a To parameter as the documentation says.
For now, I can get the number being called only server side, with params["Called"], but that is not what I need.
Any ideas ?
Megan from Twilio here. I'd like to share some of what I learned after recently getting Twilio Client up and running.
The way I imagine your call flow is that a 'user' in your application represents an agent with multiple sales lines connected to Twilio numbers configured to a TwiML app. When a customer or the 'caller' finds one of those numbers and dials it, you want to display to the user-agent which of the Twilio numbers the customer is calling.
In the code above conn.parameters.To likely represents your default_client, if you specified one. But conn.parameters.From should actually display the number the caller is calling, which if I am understanding correctly is the desired behavior.
Hope this helps!

Twilio call transfer from in-call

I'm not finding a definite answer from the Twilio docs on this. I'm trying to build a phone system that can place the other party on hold while in-call and only from the phone. Example: There are two agents working with me out in the field. I get a call on my mobile (away from a computer) and find that the other agent would need to speak to the person I'm on the phone with. I would like to be able to press something into the phone that would either directly transfer the other person to the agent, or place them in a queue. I could then call the other agent and he could retrieve the person from the queue. All of which would need to happen just from our phones.
I've found some documentation on this, but it seems to all require me to be at a computer, which wont be possible.
Is this even possible with Twilio?
Twilio evangelist here.
This sounds like it might be a good place to use some <Conference>s.
Lets define the actors in your scenario: Agent1, Agent2, Field.
Lets say that Field calls Agent1. Instead of connecting the two directly with a <Dial> you could <Dial> Field into a <Conference> (lets call it ConferenceA), then use the REST API to initiate an outbound call to Agent1. When they answer <Dial> them into the same <Conference>. The system will need to grab the CallSid's of both Agent1 and Field, as well as the Sid of the <Conference>, persist them in some type of storage to use later.
Using <Conference> in this scenario gives you more flexibility to manipulate each leg of the call independent of the other than you would have if you use <Dial> to connect Field and Agent1.
So now Agent2 calls Field. Agent2 would go through the same process, just in reverse. Agent2 would get dialed into a <Conference> (lets call it ConferenceB) and your system would use the REST API to call Field. When Field answers they get <Dial>ed into the same conference as Agent2. Again, the system will need to grab the CallSid's of both Agent2 and Field, as well as the Sid of the <Conference>, persist them in some type of storage to use later.
Now, Field needs a way to tell the system to connect Agent2 with Agent1. To do that you can utilize the <Dial>s hangupOnStar attribute in the TwiML you hand Twilio when you dial Field into the ConferenceB. The <Dial> verb would look something like:
<Dial hangupOnStar="true" action="[process_hangup_url]">
<Conference>ConferenceB</Conference>
</Dial>
hangupOnStar tells Twilio to disconnect the caller (Field) from whoever they <Dial>ed (the conference), but still makes a request to the URL defined in the <Dial> verbs action attribute. That is important because when Field needs to tell the system to redirect Agent2 into the ConferenceA with Agent1, and the request to the URL in s action attribute gives the system the opportunity to prompt Field to see if thats what he wants to do. So you might have Twilio execute some TwiML like this:
<Response>
<Gather action=[gather_handler]>
<Say>Press 1 to connect this caller to another<Say>
</Gather>
</Response>
If Field presses one, the system (who knows all of the CallSids for all of the parties involved here, and the conference sids), can use the REST API to redirect Agent2 out of the ConferenceB and into ConferenceA.
It makes for a bit more complicated of a system, but it should work for you.
Hope that helps
Redirect an incoming call to new url:
<?php
// Get the PHP helper library from twilio.com/docs/php/install
require_once '/path/to/vendor/autoload.php'; // Loads the library
use Twilio\Rest\Client;
// Your Account Sid and Auth Token from twilio.com/user/account
$sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
$token = "your_auth_token";
$client = new Client($sid, $token);
// Get an object from its sid. If you do not have a sid,
$call = $client
->calls("CAe1644a7eed5088b159577c5802d8be38")
->update(
array(
"url" => "your_url/test.xml",
"method" => "POST"
)
);
echo $call->to;
XML Code:
---------
<Response>
<Redirect method="POST">url goes here</Redirect>
</Response>

Resources