I need to automatically make calls for customers and start a interaction with them through voice. Basically, when the customer pickup the phone, my "robot" will ask: "Hey, it seems you didn't finish your order. Would you like to finish by phone?" Customer will say YES, NO, or another phrase, and I will follow the flow.
My questions:
1) What is the best approach to solve this problem using Twilio?
2) It seems Twilio has this functionality (ASR) to understand only for inbound calls when I use functions. How can I do that with outbound calls?
3) Is Twilio ready to understand another languages except English? I need to use Portuguese, Brazil.
Thank you for your help.
Twilio developer evangelist here.
To automatically make calls you will need to use the Twilio Programmable Voice API. I note you're using C# according to the tags, so you can start with the Twilio C# library. Using the library you can make calls with the API like this:
using System;
using Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
class Example
{
static void Main(string[] args)
{
// Find your Account Sid and Auth Token at twilio.com/console
const string accountSid = "your_account_sid";
const string authToken = "your_auth_token";
TwilioClient.Init(accountSid, authToken);
var to = new PhoneNumber("+14155551212");
var from = new PhoneNumber("+15017122661");
var call = CallResource.Create(to,
from,
url: new Uri("http://demo.twilio.com/docs/voice.xml"));
Console.WriteLine(call.Sid);
}
}
For a bit more detail on what all this means, check out the guide on making outbound phone calls with C#.
You will see in that example that we pass a URL to the method that makes the call. This URL can point anywhere, including at a Twilio Function (which is just a Node.js run in the Twilio infrastructure) or your own server. When the call connects to the user Twilio will make an HTTP request to that URL to find out what to do next. To tell Twilio what to do you will need to return TwiML.
To respond with the message that you want and then gather speech input from your user you will need to use the <Say> and <Gather> elements of TwiML. An example response might look like:
<Response>
<Gather input="speech" hints="yes, no" action="/gatherResponse">
<Say voice="alice">Hey, it seems you didn't finish your order. Would you like to finish by phone?</Say>
</Gather>
</Response>
In this case we start with <Gather> so that we can capture anything the user says while the call is speaking to them. We set the input attribute to "speech" so that we can use speech to text to recognise what they say. Also included is the hints attribute which can give hints to the service for the text you expect to hear. Finally, there is an action attribute which is a URL that will be called with the result of this.
You can change the language that the <Gather> expects to hear using the language attribute. There are a number of languages available including Brazilian Portuguese, which you would set with "pt-BR".
Nested inside the <Gather> is a <Say> which you use to read out your message. You can use the voice attribute to change available voices.
The next thing you need to do is respond to the result of the <Gather>. At this stage it depends on what web application framework you are using. The important thing is that when it has a result, Twilio will make an HTTP request to the URL set as the action attribute. In that request will be two important parameters, SpeechResult and Confidence. The SpeechResult has the text that Twilio believes was said and the Confidence is a score between 0.0 and 1.0 for how sure Twilio is about it. Hopefully your result will have "Yes" or "No" (or the Brazilian Portuguese equivalent). At this point you need to return more TwiML to tell Twilio what to do next with the call depending on whether the answer was positive, negative or missing/incorrect. For more ideas on how to handle calls from here, check out the Twilio voice tutorials in C#.
Let me know if that helps at all.
Related
I was wondering how I would add a command for 'UpTime' in my commands that will show how long the twitch channel has been live for.
This is my whole code: https://pastebin.com/ty8J3vYS
I'm not sure if I add it into my commands with things added to it with another case such as
case "uptime":
irc.sendChatMessage("");
break;
You can use Twitch's own API for this. Using this URL:
https://api.twitch.tv/kraken/streams/CHANNEL_ID
CHANNEL_ID is numeric, so you'll have to find out what yours is.
Will return json, and within it contains the key created_at, which tells you when a stream went live, and from there you can calculate how long the stream has been live for. (curr_date - created_at)
Although, you will need a Client-ID when sending the API request. You can read more about that here:
https://blog.twitch.tv/client-id-required-for-kraken-api-calls-afbb8e95f843
Here is the documentation on Twitch's API: https://dev.twitch.tv/docs/
I am working on one small utility using Twilio API which intend to download the recording of the call as soon as call ends ( can be done using webhooks ? ). I am not sure if twilio supports this kind of webhooks or not.
The second approach that i have in mind is to create nightly job that can fetch all the call details for that day and download the recordings.
Can anyone suggest me which is the best approach to follow. I checked the webhooks but i am not sure if they provide the call ended event.
I would appreciate if anyone can provide me code sample on how to get the recordings for particular date and download them using C# from twilio.
Twilio developer evangelist here.
You can get recording webhooks, but how you do so depends on how you record the call.
Using <Record>
Set a URL for the recordingStatusCallback attribute on <Record> and when the recording is ready you will receive a webhook with the link.
Using <Dial>
If you record a call from the <Dial> verb using the record attribute set to any of record-from-answer, record-from-ringing, record-from-answer-dual, record-from-ringing-dual then you can also set a recordingStatusCallback.
Using <Conference>
If you record a conference then you can also set a recordingStatusCallback.
Recording an outbound dial
If you record the call by setting Record=true on an outbound call made with the REST API then you can also set a webhook URL by setting a RecordingStatusCallback parameter in the request.
Retrieving recordings from the REST API
You can also use your second option and call the REST API to retrieve recordings. To do so, you would use the Recordings List resource. You can restrict this to the recordings before or after a date using the list filters.
Here is a quick example of how you would use the Twilio C# library to fetch recent recordings:
using System;
using Twilio;
class Example
{
static void Main(string[] args)
{
// Find your Account Sid and Auth Token at twilio.com/user/account
string AccountSid = "AC81ebfe1c0b5c6769aa5d746121284056";
string AuthToken = "your_auth_token";
var twilio = new TwilioRestClient(AccountSid, AuthToken);
var recordings = twilio.ListRecordings(null, null, null, null);
foreach (var recording in recordings.Recordings)
{
Console.WriteLine(recording.Duration);
// Download recording.Uri here
}
}
}
Let me know if this helps at all.
So let's say I created a feedback form in C#.
It sens the feedback to my PHP Page and my PHP Page adds it to my MySQL Database.
Code:
private void PostFeed(string Params)
{
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
wc.Headers["Accept"] = #"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
wc.Headers["Accept-Language"] = #"en-US,en;q=0.5";
string HtmlResult = wc.UploadString("http://website/feedtest.php", "POST", Params);
Console.WriteLine(HtmlResult);
}
}
On my PHP I have a code that looks similar to:
$name = $_REQUEST['name'];
$email = $_REQUEST['email'];
$desc = $_REQUEST['description'];
connect
post result...
close connection
The question I have is: is there a way to protect against flood ? I understand anyone can just spam/flood it by sending feedback continuously or even creating a third party app that sends like 1000 post request per second. I was thinking of implementing some sort of check on the PHP side, for example: if the connection password from the c# app matches, then continue if not, exit.
Basically, I dont want people to take advantage of the feedback method and spam me.
Can anyone suggest a method ? or Should I not even worry about this ?
Any help is appreciated.
A typical technique is to have some kind of submissions per X unit of time limit where you have a last_submitted_at column in a table associated with some kind of identifier. For example, you might associate it with a user if you have a fairly robust user registration system, or you might associate it with an IP if you don't.
This is the system that Stack Overflow uses if you try and vote, post, or as questions too often. Each of these has a separate timer which probably translates to a separate last_X_at column in the database somewhere.
If the last time is less than some threshold, present an error instead of accepting the submission.
I am using Twilio to make outgoing call to a number that is running an IVR system and I have to supply various digits as per the required IVR menu options. Right now, I have tried almost all the sample codes and Quick Start tutorials but it didn't work for me.
I am using ASP .Net web application to make a call using Twilio official C# helper library. I am using following code to make a call.
Following is the TwiML instruction provided to Twilio after the call gets connected
StringBuilder sb = new StringBuilder();
sb.Append("<?xml version='1.0' encoding='UTF-8'?>");
sb.Append(" <Response>");
sb.Append(" <Dial callerId='+1852xxxxxxx' record='true' >");
sb.Append(" +1475xxxxxxx ");
sb.Append(" </Dial>");
sb.Append(" </Response>");
Response.Write(sb.ToString());
Please note that the 'Dial' verb doesn't support the sendDigits parameter.
Your immediate response will be highly appreciated, as I am stuck and need to fix this as earliest as possible.
It looks like you want to pass the SendDigits optional parameter along with your outbound API call.
For more information, see this list of optional parameters when making a Twilio API call
After thoroughly review the documentation, I found a <Number> noun for the <Dial> verb that allows to provide sendDigits parameter. So my problem has been solved. Thanks to all of you for your support.
Regards,
Tahir Ahmed
this can help you
const call = Device.connect(params);
call.sendDegits("1");
I want to write a program that responds to calls. After a welcome message it must tell the client to: press 1 for enter your account number, or 2 for speak with an operator. If the client presses 1 then tell him or her to enter your account number and after he or she enters the account number the number must saved in the database.
Is this possible in c#? If it is, I want an IVR library for c#. If not, I need a great IVR library for c++.
Microsoft has the Microsoft Speech API (SAPI) however if you want simple IVR it is better not to reinvent the wheel and customize an Asterisk implementation (which i guess falls under the "great IVR library for c++" category (it's c not c++ but if you know c++ you should be able to understand the c).) Using AsteriskNow you may not even need to write any custom code, it may do what you want already.
I don't know of a free IVR library for C#, but I do know of a couple that are fairly inexpensive:
http://www.voiceelements.com/
http://www.componentsource.com/products/velocity/index.html
Ricky from the Twilio crew here.
We have a tutorial on building an IVR with C#, taking a look at this may be helpful in getting an idea in how to build this type of application.
Whenever a phone call comes into our phone number, a request is made to our server where we can respond with some basic instructions, using TwiML, on what to do with the call:
public TwiMLResult Welcome()
{
var response = new TwilioResponse();
response.BeginGather(new {action = Url.Action("Show", "Menu"), numDigits = "1"})
.Play("http://howtodocs.s3.amazonaws.com/et-phone.mp3", new {loop = 3})
.EndGather();
return TwiML(response);
}
Since we're using the verb, when the user presses a digit a new HTTP request will be made to another route on our server where we can take action based on what digit(s) the user pressed:
public TwiMLResult Show(string digits)
{
var selectedOption = digits;
var optionActions = new Dictionary<string, Func<TwiMLResult>>()
{
{"1", ReturnInstructions},
{"2", Planets}
};
return optionActions.ContainsKey(selectedOption) ?
optionActions[selectedOption]() :
RedirectWelcome();
}
Hope that helps!