Getting the call response from the menu with Twilio - c#

I am using C# to send a phone message with option(Twimlet) for the user to press 1 to confirm. How do I get the response from the call?
The code terminates prior to the call being placed, I assume I need to query the twilio server with the call sid?
static void Main(string[] args)
{
var twilio = new TwilioRestClient(AccountSid, AuthToken);
var options = new CallOptions();
options.Url = "http://twimlets.com/menu?Message=Please%20press%201%20to%20confirm%20or%20Press%202%20to%20cancel&Options%5B1%5D=http%3A%2F%2Ftwimlets.com%2Fmessage%3FMessage%255B0%255D%3DYou%2520have%2520confirmed%252C%2520Thank%2520you%2520good%2520bye.%26&Options%5B2%5D=http%3A%2F%2Ftwimlets.com%2Fmessage%3FMessage%255B0%255D%3DYou%2520have%2520selected%2520to%2520cancel.%2520Thank%2520you.%2520Good%2520bye%26&";
options.To = "+13105551212";
options.From = "+13105551213";
var call = twilio.InitiateOutboundCall(options);
Console.WriteLine(call.Sid);

In order to respond to any input from the call, you need to use URLs under your control. Twimlets are pre-defined "apps" that don't give you control of the call flow outside of what you can specify in URL parameters.
The code you have now terminates because all it is doing is making an HTTP call to Twilio's servers telling it to start the call, with the options.Url endpoint responsible for handling that call's flow. To write a custom flow, you would need to create a public URL that returns TwiML for the desired flow.
Once you've got that going, you'll use the url attribute of the <Gather> verb to indicate where the key press data should be sent.

Related

Trigger a flow using c#

I have Microsoft flow which triggers When an HTTP Request is Received. I want to trigger this flow from the C# code. I tried the following code to trigger the flow but it is not working. The flow didn't get triggered and the code remains in the running state.
private static async System.Threading.Tasks.Task NewMethod()
{
var url = "https://prod-06.australiasoutheast.logic.azure.com:443/workflows/15702797187b4ffcbe386f714f532a8a/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=pOBhhzWW9cUel9v2jfyCUIY5wt4c1o84ezvMBNoLGm4";
var client = new HttpClient();
var response = await client.GetAsync(url);
string result = response.Content.ReadAsStringAsync().Result;
}
I also need to pass the parameter to flow from code. What is wrong with the code or do I need to do anything in flow to trigger from outside application?
Consider verifying that the Flow id 15702797187b4ffcbe386f714f532a8a is a valid flow. You may have transposed the id or are using the incorrect API version number associated with that id.

RESTful API call using C#

I am building my URL to make an API call, using the key and secret that the provider has given me.
https://api.testurl.com/api/test/calldata?key=12345&secret=999999&query=hello
My question is I am appending the 'query' based on user input each time and performing the call with the 'key' and 'secret' every time - to me this doesn't seem that secure. Isn't the secret key exposed each time the call is made?
public async Task<List<APIResult.Data>> ApiAsync()
{
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(_apiUrlToCall);
if (!response.IsSuccessStatusCode) return null;
var result = await response.Content.ReadAsStringAsync();
var rootResult = JsonConvert.DeserializeObject<APIResult.Rootobject>
(result);
return rootResult.Data.ToList();
}
}
Normally you'd pass the identity data (in this case your key and secret) in a HTTP header rather than on the querystring. That way it doesn't get logged anywhere (e.g. IIS logs, browser history, slurped by google, facebook et al trackers).
If you're using HTTPS that should stop it being exposed anywhere else.
But yes since HTTP is stateless you have to send some sort of identifying data every time you make a request, be that a secret key, Kerberos token, session coookie, whatever it is.
You can pass the key & secret as Http header. Normally for rest api the Authorization Http Header is set with the authtoken. You could so something similar.

How do I set up HttpClient PostAsync to call a new web browser

I am using HttpClient PostAsync to send data to a URI. However, the following code doesn't behave as expected:
using (var client = new HttpClient())
{
var values = new Dictionary<string, string>
{
{"cpm_site_id",TOKEN},
{"apikey",API_KEY},
{"cpm_amount",input.Amount},
{"cpm_currency",input.Currency},
{"cpm_trans_id",input.Id},
{"cpm_custom",input.Custom},
};
// Get the parameters in the url encoded format
var content = new FormUrlEncodedContent(values);
//Send request
var response = await client.PostAsync(new Uri(Urls.GetUrl(Methods.Pay, IS_PRODUCTION_SITE)), content);
When the client closes their browser, I want to receive an event notification to call this code, send the above data to the client, and open a new browser instance to perform additional actions. However, this code doesn't accomplish this and I'm not sure exactly why.
I think you'll need to use something like Selenium to automate a web browser. The HttpClient can perform HTTP functions, but does not work like a web browser does.
See this SO post for a 'hello world' example
See this SO post for an example of capturing the browser close event. I've not done this with C#, but I'd imagine it'll be similar to this JAVA example.

Setting Callback URL and retrieve data using RestSharp

I am calling an Restful API that expects me to pass a parameter callback(a URL)when doing POST.
The tool that I am using to make the call is RESTSharp. I have written the below code
var client = new RestClient("https://services.mywebsite.com/api/v3/");
client.Authenticator = new HttpBasicAuthenticator("Usernamae", "P2$$w0rd");
var request = new RestRequest("myAction", Method.POST);
request.AddHeader("Accept", "application/json");
request.AddParameter("Id", "sid");
request.AddParameter("callback", "http://localhost"); // ????????
request.RequestFormat = DataFormat.Json;
request.AddFile("file", #"e:\MyDocuemnt.pdf");
client.ExecuteAsync(request, response => {
Console.WriteLine(response.Content);
The line with the parameter callback requires me to pass a url
what should I be passing in here ?
the result is passed back to the callback Url provided, how do I get to see that?
My application is a console application and I want to capture the result here.
Your API is expecting a place to dump the results after it has been processed.
This is what is happening as per my understanding.
You make a call to the API and expects you to provide a callback url
The API returns you a response.
Now the question here is where is my result and if it is sent to the callback url how do I get it.
This is waht you need to do.
You could create a Web API with a POST method that would do the trick for you.
Make sure you are hosting your WebApi which should be accessible by the service which you are calling and expect to send you the result.
public void Post([FromBody]JToken value)
{
var path = HttpContext.Current.ApplicationInstance.Server.MapPath("~/App_Data");
File.WriteAllText(path + #"/WriteJSON" + DateTime.Now.Ticks.ToString() + ".txt", value.ToString());
// write any code that you want to here
}
This should do the trick for you.All i am doing here is writing the response back you may want to do whatever you wish to do with this.

Resend HTTP header

I have application. It send request to my proxy class. Proxy must to parse http header string (I done this) and resend it request to server to get a video.
At first, mediacomponent connect to proxy:
var uri = new Uri("http://127.0.0.1:2233/files/1.mp4");
videoPlayer.Source = uri;
Play();
Proxy get http header string
"GET /files/1.mp4 HTTP/1.1\r\nCache-Control: no-cache\r\nConnection: Keep-Alive\r\nPragma: getIfoFileURI.dlna.org\r\nAccept: */*\r\nUser-Agent: NSPlayer/12.00.7601.17514 WMFSDK/12.00.7601.17514\r\nGetContentFeatures.DLNA.ORG: 1\r\nHost: 127.0.0.1:2233\r\n\r\n"
I replase host:
"GET /files/1.mp4 HTTP/1.1\r\nCache-Control: no-cache\r\nConnection: Keep-Alive\r\nPragma: getIfoFileURI.dlna.org\r\nAccept: */*\r\nUser-Agent: NSPlayer/12.00.7601.17514 WMFSDK/12.00.7601.17514\r\nGetContentFeatures.DLNA.ORG: 1\r\nHost: myserver.ru\r\n\r\n"
Now proxy must get video from server. What must I do?
When using .NET, you don't have to manually create the HTTP message itself. Instead, use the classes in the System.Net.Http namespace to form and send an HTTP message and process the response.
For example, sending an HTTP GET message to a URL can be as simple as:
var uri = new Uri("http://www.foobar.com/");
var client = new HttpClient();
string body = await client.GetStringAsync(uri);
Note that this general approach will download the entire contents of the resource at the given URI. In your case, you may not want to wait for the whole video to download before you start playing/processing/storing it. In which case, you might want to use the HttpClient.ReadAsStream() method which will return a stream from which you can read until the stream closes.

Categories