I use Twilio to make phone calls during which the user can reply by pressing key. My problem is that I want to manage 4 cases:
1) the user answer and press 1
2) the user answer and press another key than 1
3) the user answer and press no key
4) the user don't answer
For cases 1, 2 and 3, everything is OK:
I have a "Gather" in my XML, with an "action" URL, a time-out and a actionOnEmptyResult="true"
For managing case 4, I use a statusCallback url, with 'statusCallbackEvent' => ['answered','completed']
What I notice in my Log is that I receive exactly the same data in case 3 (user answer but press nothing) and in case 4 (user don't answer the call).
Maybe this came from the fact after a few "rings" the call fall in voice-box, fooling Twilio which believe it's an "answer" event.
In my LOG I see (case 3 or 4) this 3 events:
Call to my statusCallback with CallStatus = in-progress
Call to my return hook with msg = Gather End and Digits = ""
Call to my statusCallback with CallStatus = completed
So my question is: how can I know the difference between "answer the call and press nothing" and "don't answer the call" ?
Edit: if I refuse the call, result is the same. So I get the same "hook" and statusCallback call, with same data if the user pick-up and give no reply, if he doesn't pick up or if he refuses the call...
Twilio developer evangelist here.
You may want to handle the "doesn't answer the call" slightly differently. If the user doesn't answer, your action URL is still called but the parameter CallStatus sent to the webhook will be no-answer. In this case you can <Hangup/> the call and mark it as not answered.
There is one other issue. If the call is answered by a voicemail then your call will attempt to continue as normal. You can put this down as a call that was answered but didn't enter anything, or you can try using Twilio's answer machine detection to detect whether a human or machine answered the call. If it's a human you continue as usual, but if a machine answers you can also mark it as not answered and <Hangup/> the call.
Let me know if this helps at all.
Related
I'm trying to add a participant to an existing conference. It works just fine, but now I want to add a statusCallback to be called when the ringing begins for the new participant.
Here's the line where I'm creating the new participant:
client.conferences(conferenceName).participants.create({
from: `client:${fromAgentId}`,
to: `client:${toAgentId}`,
statusCallback: statusCallbackUrl,
statusCallbackEvent: "initiated ringing answered completed",
statusCallbackMethod: "POST",
});
As I said, the new participant is successfully getting added to the conference, but the statusCallbackUrl never gets called.
According to these docs https://www.twilio.com/docs/voice/api/conference-participant?code-language=Node.js#parameters-1 it looks like the participants.create() method should accept a statusCallback, so I have no idea why it's not working. If anyone has an idea, I'd love to hear from you.
Answering my own question here.
It seems like it's a problem with the Twilio docs. Regarding the statusCallbackEvent parameter, the docs state:
Can be: initiated, ringing, answered, and completed. Separate multiple values with a space.
However, rather than separating multiple values with a space, the statusCallbackEvent parameter should be an array of values.
I want to join Webex conference using Twilio api. I am using Call class like this:
Call call = Call.creator(toNum, fromNum, twiMLUrl).setSendDigits(dialCode).setStatusCallback(STATUS_CALLBACK_URL).setStatusCallbackEvent(callbackEvents).create();
Here fromNum is my Twilio number, toNum is the phone number provided by Webex and dialCode is the participant code
I am unable to join the conference. I feel it is because webex asks to enter "1" to confirm the participant code in the end while joining.
Is there a way in api to send that "1" to confirm?
Twilio developer evangelist here.
It's a little bit blunt, but you can send pauses as part of the sendDigits parameter. Every "w" you send as part of the string will pause for half a second.
It might take a bit of testing, but you should be able to make your dialCode out of the initial code, say "1234", a few pauses and then the final "1". Like 1234wwwwww1.
Let me know if that helps at all.
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.
How do I know whether or not a call is answered?
For StatusCallback, I can set the following values:
initiated
ringing
answered
completed
When Twilio sends me statuses, I don't see a value for "answered" what I see are the following:
no-answer
busy
completed
initiated
failed
I'm wondering why there is no status returned for:
answered
though I'm setting "answered" as one of the values for StatusCallback.
What confuses me is that Twilio sends "Completed" irrespective of whether or not the call was answered or not.
I need a definite status for the call being answered. If the call is not answered then I need to retry again later or build a business logic around it.
When the call is not answered, then I get "not-answered".
When the call is answered, then I get "completed", but "completed" does not necessarily mean the call was actually answered assuming that the call went to the voicemail box or something.
On a side note, I am also setting the "IfMachine" parameter in the call request. Though I know that it is an experimental feature, I get the call status as "completed" as in this case, my expectation is "not-answered".
How do I know if the call was actually answered?
Megan, also from Twilio!
Just wanted to clear a few things up here. You mention using StatusCallback which expects a URL. The answered value is actually set using StatusCallbackEvent as you can see here in the docs.
I don't know what language you're using but an example in Python (you can find other languages on that docs page):
# Your Account Sid and Auth Token from twilio.com/user/account
account_sid = "YOUR_ACCOUNT_SID"
auth_token = "YOUR_AUTH_TOKEN"
client = TwilioRestClient(account_sid, auth_token)
call = client.calls.create(
url="http://demo.twilio.com/docs/voice.xml",
to="+14155551212",
from_="+18668675309",
method="GET",
status_callback="https://www.myapp.com/events",
status_callback_method="POST",
status_events=["initiated", "ringing", "answered", "completed"],
)
print call.sid
And a final note about using IfMachine. For the time being, we actually recommend that you use Twilio's <Gather> verb to detect if a human picks up as explained in this question here.
Hope this helps!
we have integrated Phone Poll in our Website, But when originating the call to a number, by default call made 3 times, but we want to control the call from default 3 times to either only one or two or more than 3 times. how is it possible?
Twilio evangelist here.
It sounds like you are making three calls to your customer all at the same time. I'm not sure why you are doing that, but I suspect what you want to do instead is wait for the first call to complete, then if needed make a second and possibly third call.
There are a couple ways to know if the call completes or not. When you make your first outbound call, you can include the StatusCallback parameter in your call to to the REST API. The StatusCallback parameter lets you specify a URL that Twilio will make an HTTP request to when the call ends.
To do this in PHP, you can use the options parameter in the create method. This parameter takes an array that lets you add extra parameters to your request:
call = $client->account->calls->create(
'9991231234', // From this number
'8881231234', // Call this number
'http://example.com/call.xml',
array(
'StatusCallback' => 'http://example.com/callback',
'StatusCallbackMethod' => 'GET'
)
);
When Twilio makes its request to the URl you've specified as the StatusCallback, you can check the CallStatus parameter to see why the call ended. In the case of no-answer your application can queue up another call to the customer.
$callstatus = $_REQUEST["CallStatus"];
if (
$callstatus == "no-answer" ||
$callstatus == "busy" ||
$callstatus == "failed") {
//caller never answered, line was busy or call failed, so do something about that
}
If the caller answers, then you are going to use the <Gather> verb to let the customer enter in 1, or some other value. The Gather verb includes a parameter named action that lets you specify a URL that Twilio should request once the user has entered a digit. You can check the Digits parameter in this request to see if they pressed 1 or some other number. If they did not press 1, you can either re-prompt the customer to try entering the digits again or hangup and have your application queue up another call to the customer.
Hope that helps.