The following Twilio code doesn't work. This is my webhook handler in an ASP.NET (Core) 6.0 app.
[AllowAnonymous]
[HttpPost]
[Route("webhook-url")]
public IActionResult PostTwilioMessageReceived([FromForm] TwilioMessageReceivedFormModel formModel)
{
// logging code etc.
var response = new Twilio.TwiML.MessagingResponse();
response.AddText($"You sent '{formModel.Body}' but our systems are dumb and can't process this yet.");
return new TwiMLResult(response);
}
There are no errors. I don't receive the message, and my delivery status webhook doesn't appear to be called.
The method above is called as I see it in my logs.
Note - There is no "to" address. I have adapted sample code from Twilio's documentation which also does nothing to either read the sender address or configure the response with a recipient or other correlation ID.
https://www.twilio.com/docs/whatsapp/tutorial/send-and-receive-media-messages-whatsapp-csharp-aspnet#generate-twiml-in-your-application
I've modified my logging to make doubly sure my webhook is being called. It is. And in Twilio's log there's no acknowledgement of the reply my webhook attempts to produce.
To be clear, the code above is using Twilio's libraries.
The TwiML output of your application would be:
<Response>You sent '...' but our systems are dumb and can't process this yet.</Response>
Unfortunately, that isn't valid TwiML, instead it should look like this:
<Response>
<Message>You sent '...' but our systems are dumb and can't process this yet.</Message>
</Response>
This will respond with a message to the sender. To do this, use the .Message method instead of .AddText:
response.Message($"You sent '{formModel.Body}' but our systems are dumb and can't process this yet.");
Everything else looks fine in your code AFAIK.
Aside: If all you need to do is to respond to the current sender with a single message, you can also respond with plain text and the text/plain content type.
Edit by OP
I also changed the return line to:
return this.TwiML(response);
Which was the advice of Twilio support. I didn't try it my original way, but assumed that if there was some kind of magic that's pre-addressing the response, or correlating it in some way, then it might be in using the helper function on the base controller. Thanks.
It's hard to say what caused this without seeing an error or message log. You should be able to see something in the "Monitor" in the console (more details here).
I've had similar issues in the past with Node.js and the problem was there that I forgot to set the content-type of the response to text/xml. But I'm not sure if this is required in your C# code.
Related
I am using Stripe.net SDK from NuGet. I always get the exception from StripeEventUtility.ConstructEvent method.
The WebHook key is correct, the Request Header contains "Stripe-Signature" keys.
I correctly receive incoming data from the Webhook tester utility (using nGrok with Visual Studio).
I tried to manipulate the incoming data from Stripe (Jobject, string, serializing...). The payload signature may cause some problem.
Has anybody had the same problem?
Webhook tester utility
Are you referring to the Stripe CLI, using the listen command and forwarding to your endpoint? If so, it's important that you use the webhook secret returned by the listen command, and not one related to a configured endpoint on your Dashboard.
The other main source of this issue is mutation of the request body. Signature verification depends strictly on having access to the raw body of the request, including original whitespace etc.
See this sample implementation of a webhook endpoint in .NET accessing the raw request body: https://github.com/stripe-samples/accept-a-payment/blob/main/custom-payment-flow/server/dotnet/Controllers/PaymentsController.cs#L86
I recently upgraded the Twilio C# DLL we've been using to handle SMS messages. We are now on Twilio.DLL v5.16.2. I have a webhook set up to call a custom URL on our website. That part is working, because I can log the Request coming in (message SID and body and all that good stuff). At the end, we have code to instantiate a MessagingResponse object to send back a confirmation that the message was received. That's not working anymore. I don't get a SMS message on my phone nor do I see an Outgoing API record on the SMS logs page when I'm logged into my project on Twilio.com (whereas I do see the test message I've sent to our number as an Incoming message).
There is no error or exception either.
Any idea how to debug/solve this?
string responseTxt = "TESTING: Got it. Thanks.";
var smsResponse = new MessagingResponse();
var smsMsg = smsResponse.Message(responseTxt);
response.Write(smsMsg);
Twilio developer evangelist here.
I'm not a C# developer, so forgive me if I'm wrong. Also, I don't know what happened with this change.
Anyway, from what I can see, the message body when using the MessagingResponse's Message method appears to be a named argument now. Changing your code to the following should work for the latest version of the DLL.
var smsMsg = smsResponse.Message(body: responseTxt);
Let me know if that helps.
I'm not sure there's much to update as the exact same scenario still stands. But I can reiterate to see if this provides any additional clues.
We have a Twilio SMS service set up. There is a webhook assigned to our number that maps to an HTTP Handler on an ASP.NET website. The code in the handler logs in our database the fact that an SMS message was received and various bits of info (from the Request.Form variables supplied by Twilio, From number, body of the message, num of media, etc.).
Then, the code "replies" to the original SMS sender using the MessagingResponse object. See original code snippet. Really couldn't be much simpler.
Note, this is and has all been working quite well, using the Twilio c# helper library 5.6.
I upgraded the Twilio library to the latest rev (5.25.1) and its dependencies. Copied the new DLLs to our dev webserver. Now the reply message, using the MessagingResponse object, never occurs. The webhook is still called as I can see the new record in the database logging the message details. Just no response. No error, no exception. Just nothing.
If I rollback to our old version of the Twilio library (and its dependencies, thank goodness for Git!), it works again.
I'm trying to get to grips with OneDrive, using this tutorial:
https://msdn.microsoft.com/en-us/library/hh826529.aspx
When I run in code, it gets as far as the makeAccessTokenRequest function, sending the following requestURL:
"https: //login.live.com/oauth20_token.srf?client_id=[myclientID] &client_secret=[myclientsecret]&redirect_uri=https:// login.live.com/oauth20_desktop.srf&grant_type=authorization_code&code=[authcode]"
(please ignore the spaces after "https:", I had to add them here to allow the question)
[myclientid], [myclientsecret], and [authcode] all appear to be populated correctly. It seems to get a response, as it runs the function "accessToken_DownloadStringCompleted", but throws a "TargetInvocationException" error, The inner message of the error is ""The remote server returned an error: (400) Bad Request.".
Could anyone throw any light on this? I'm completely new to this, so apologies if my question makes no sense, or is irritatingly vague..
Requests to the oauth20_token.srf end point need to be a POST with the parameters in the body of the post, instead of the query string. Since you didn't mention what code you're using to build the HTTP request it's hard to provide an example, but take a look at RedeemAuthorizationCodeAsync in my sample OAuth 2 project for an idea.
The outgoing request should look like this:
POST https://login.live.com/oauth20_token.srf
Content-Type: application/x-www-form-urlencoded
client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}&code={code}&grant_type=authorization_code
You may also find this tutorial easier to follow than the one you linked with: https://dev.onedrive.com/auth/msa_oauth.htm.
If you are doing something with OneDrive (you tagged the post OneDrive) then you may want to consider using the OneDrive SDK instead. It includes authentication for several types of .NET projects so you don't need to figure out how to do auth yourself.
I am writing a web application in C#. One piece of functionality is that the server will send out a push notification offering a client the opportunity to do a round of work. The client can accept or refuse this work.
However, if the client takes too long to respond, the server will see this as an implicit refusal and offer the round of work to someone else.
Here is an extract of the controller endpoint on the server, where a client can post it's acceptance of the current round
public HttpResponseMessage PostAcceptRound(PersonData accepter){
Round currentRound = repo.GetCurrentRound();
if(currentRound.offeredTo.id == accepter.id){
repo.RoundAccepted(currentRound.id);
return Request.CreateResponse<String>(HttpStatusCode.OK, "Round has been accepted");
}
else{
//return appropriate response
}
}
My question is: what is the appropriate response for the client taking too long to accept?
My initial reaction was that I should sent a "BadRequest" error response. However, it is not as if a person refusing late is poorly formed request or something that is unexpected. Indeed, it seems as if accepting too late will be a situation that will happen often within the use of this application.
408 = 'Request Timeout' seems to me to most appropriate.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
I want to create a small windows application will go automatically every time period to my site and check if its running fine, if it found it down, not working or have an error "Examples: 404, network error, connection to db failed" it will show a message on my screen.
How can i know that there is an error there programmaticly using any .NET language?
It's pretty easy to do with a WebClient. It would look something like this:
WebClient client = new WebClient();
try
{
string response =
client.DownloadString("http://www.example.com/tester.cgi");
// We at least got the file back from the server
// You could optionally look at the contents of the file
// for additional error indicators
if (response.Contains("ERROR: Something"))
{
// Handle
}
}
catch (WebException ex)
{
// We couldn't get the file.
// ... handle, depending on the ex
//
// For example, by looking at ex.Status:
switch (ex.Status)
{
case WebExceptionStatus.NameResolutionFailure:
// ...
break;
// ...
}
}
You could hook that up to a Timer's Tick event or something to periodically make the check.
Why bother? You can get a much better solution for cheap from a provider like RedAlert
The nice thing about this is:
1) It tests your site from outside your firewall, so it can detect a wider variety of problems.
2) It is an impartial 3rd party so you can prove uptime if you need to for an SLA.
3) For a small premium you can have the thing try and diagnose the problems.
4) It can page or e-mail you when there is a problem.
5) You don't need to commission a new server.
Geez, I sound like an ad for the guys, but I promise I don't work for them or get a kickback. I have just been happy with the service for our servers.
BTW: I checked pricing and it is about $20 per site/month. So you could probably pay for a year of the service in less time than it will take to build it yourself.
Wanting to perform the same functionality I first looked into third party solutions. One particular service that is free and has been fairly accurate is MonitorUs.
If, however, you are wanting to build your own then I would have one recommendation. Consider using a Head request instead of a get request:
The HEAD method is identical to GET
except that the server MUST NOT return
a message-body in the response. The
metainformation contained in the HTTP
headers in response to a HEAD request
SHOULD be identical to the information
sent in response to a GET request.
This method can be used for obtaining
metainformation about the entity
implied by the request without
transferring the entity-body itself.
This method is often used for testing
hypertext links for validity,
accessibility, and recent
modification. w3.org
Here's a link to Peter Bromberg's article that explains how to perform a Head request in C#.
Use the System.Net.WebClient object. It's easier to use than HttpWebRequest. It has a "DownloadString" method that will download the contents of a URL into a string. That method may also throw a WebException error if the server returns a 500. For other errors you can parse the string and look for key words.
Use HttpWebRequest, and wrap it in a try catch for WebException. The error code in the exception object will give you the code. 404, etc. If it is 500, you could print the message.
If you do this, create a special page that exercises any special subsystems, like the data base, file IO, etc, and serves up the results in plain text, not html. This will allow you to parse the returned data easier, and will also catch things like DB or IO problems that may not give you a 404 or 500 HTTP error.
Try Adventnet's Application Manager (http://www.manageengine.com/products/applications_manager/), it is free for 5 monitors, and provides excellent monitoring capabilities
You could configure the actions that can be done in case of a failure like send email etc.
If you'd prefer to get email/SMS when your sites are down, try the Are My Sites Up web-based solution.