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!
Related
The new Twilio 5x libraries have introduced a bit of an odd approach to gathering DTMF digits on phonecalls.
The old 4x code for a gather would have looked something like:
twiml.BeginGathertwiml.BeginGather(new { numDigits = "1", action = "/TwilioCallbacks/InputResponse" });
if(x == 10){
twiml.Say("I am saying a thing because x = 10");
}
else{
twiml.Say("I am saying the other thing");
}
twiml.EndGather();
Now, if you wanted to let the user punch digits on the keypad while your bot was talking to them, that'd work just fine.
However in Twilio 5x, it looks like this:
twiml.Say("I am saying a really long thing where the user must wait until the twiml script reaches the gather phrase");
twiml.Say("press 1 if stack overflow is awesome, press 2 to quit programming forever");
twiml.Gather(
numDigits: 1,
input: new List<InputEnum>() { InputEnum.Dtmf },
timeout: 10,
method: "POST",
action: new System.Uri(Startup.hostAddress + "/TwilioCallbacks/InputResponse")
);
Right after Gather(...) you have a short window to collect the response, if you set a timeout on the response, the twiml won't proceed to the next say until the timeout expires.
How can I Gather digits in such a way that the user can interact with the keypad at any point during the message? The new approach seems to be a step backward.
edit:
Clarified the 4xx use case, such that folks can understand why chaining .Say won't work here.
edit:
Some people below are suggesting chaining the .Say() verb right after .Gather().
This actually doesn't behave as expected either. This is the C# code.
twiml.Gather(
numDigits: 1,
input: new List<InputEnum>() { InputEnum.Dtmf },
timeout: 10,
method: "POST",
action: new System.Uri(Startup.hostAddress + "/TwilioCallBot/InputResponse")
).Say("this is a test");
This is the resulting twiml:
<Gather input="dtmf" action="https://callbot21.ngrok.io/RCHHRATool//TwilioCallBot/InputResponse" method="POST" timeout="10" numDigits="1">
</Gather>
<Say>this is a test</Say>
The say verb needs to be inside the gather tag to get the behavior we're looking for.
Okay I've found the issue. It looks like fourwhey was correct to point at the API docs there. What I didn't catch was that the .Say was being appended to the gather in a specific way.
This:
twiml.Gather(...).Say("say a thing");
doesn't work the same as this:
var gather = new Twilio.TwiML.Voice.Gather(...).Say("say a thing");
best I can work out is that there's actually two gather methods, and that twiml.Gather(...) is actually calling Twilio.TwiML.Gather.
From here we can build our dynamic voice message and nest the Say verb like so:
gather.Say("Say a thing");
gather.Say("Say another thing");
And the twiml will get spit out the way we intended like so:
<gather>
<say>say a thing</say>
<say>say another thing</say>
</gather>
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.
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.
Right now I have an app that allows a user to schedule/post a Facebook post and then monitor the likes/comments. One of the problems I foresee is that currently I am pulling every single comment/like whether it's been processed or not. What I would like to do instead is be able to say 'Give me all the NEW comments since XYZdate/XYZcomment.' Is this currently possible?
var accessToken = existingUserNode.Attributes["accessToken"].Value;
var facebookAPIMgr = new FacebookWrapper.FacebookAPIManager();
var msg = new FacebookWrapper.FacebookMessage()
{
AccessToken = accessToken,
FacebookMessageId = facebookPost.FacebookMessageId
};
//Get Facebook Message Comments
// Need to find a way to limit this to only new comments/likes
var comments = facebookAPIMgr.RetrieveComments(msg);
You can do time-based pagination as part of your graph API query. If you keep a unix timestamp of when you polled things last, you can simply do https://graph.facebook.com/{whatever}?since={last run}.
This worked when I was working heavily with the Graph API earlier this year, and is still around on the documentation, but considering how much Facebook loves to change stuff without telling anyone you may still encounter problems. So just a warning, YMMV.
i build mini Question Answering System in C#. I need retrieve document by google Search.
What is google tools name, i can use it in my project?
Thanks
One possibility is to set up a custom Google search engine. Then you also need to create a developer key, which I believe is done under the console.
After setting that up, you can make REST style call with code such as the following, which retrieves the results as JSON:
WebClient w = new WebClient();
string result;
string uri;
string googleAPIKey = "your developer key";
string googleEngineID = "your search engine id";
string template = "https://www.googleapis.com/customsearch/v1?key={0}&cx={1}&q={2}&start={3}&alt=json";
int startIndex = 1;
int gathered = 0;
uri = String.Format(template, googleAPIKey, googleEngineID, "yoursearchstring", startIndex);
result = w.DownloadString(uri);
For extracting the information from the JSON results, you can use something like Json.NET. It makes it extremely easy to read the information:
JObject o = JObject.Parse(result);
Then you can directly access the desired information with a single line of code.
One important piece of information is that the search API free usage is extremely limited (100 requests per day). So for a real-world application it would probably be necessary to pay for the search. But depending on how you use it, maybe 100 requests per day is sufficient. I wrote a little mashup using the Google search API to search for Stackoverflow site information of interest and then used the StackExchange API to retrieve the information. For that personal use, it works very well.
I've never used it before (and it's alpha), but take a look at Google APIs for .NET Framework library.