let's say I have an email account and every time I get a new email I want to receive this information in my c# code and save some info of that email in json format, I have read about Context.IO, Webhooks, but I have not find any information yet about doing it with C# code, could you please give an advice of how can I reach that in my c# code? I have an ASP.net MVC app, I just want to get some data about a new email every time is received, I have never worked before with Context.IO or webhooks. How can I do this in C#?
UPDATE:
[HttpPost]
[System.Web.Mvc.ValidateInput(false)]
public IHttpActionResult GetEmail(System.Web.Mvc.FormCollection form)
{
Person person = new Person {
Name= System.Web.HttpContext.Current.Request.Unvalidated.Form["Account_id"],
LastName= System.Web.HttpContext.Current.Request.Unvalidated.Form["webhook_id"]
};
db.People.Add(person);
db.SaveChanges();
return Ok();
}
Context.IO pretty much does what you're looking for with webhooks. Essentially, you would setup a webhook filter on a user (https://context.io/docs/lite/users/webhooks) and provide which filters to watch out for, if any. Set up an endpoint on your app to receive the webhooks, and when a new message is received by the user, you should receive a webhook postback on that endpoint.
If you just want to test out the webhooks without setting up an endpoint on your end, I would recommend a tool like Mockbin, which allows you to set up mock endpoints and receive data http://mockbin.org/
The payload is in json, so it should be easy to parse on your end. The only thing is that Context.IO does not have a C# library, but you could use a library of your choice (or something like restsharp) to develop straight against the REST API.
Related
We're trying to receive payment with cryptocurrencies using coinpayment IPN. We are able to create a request and able to do a payment. However, not able to get success or failure response while user come back to the seller side.
Here is how payment request created:
public ActionResult IPN()
{
var uri = new UriBuilder("https://www.coinpayments.net/index.php");
uri.SetQueryParam("cmd", "_pay_auto");
uri.SetQueryParam("merchant", "merchant_key");
uri.SetQueryParam("allow_extra", "0");
uri.SetQueryParam("currency", "USD");
uri.SetQueryParam("reset", "1");
uri.SetQueryParam("success_url", "http://localhost:49725/home/SuccessResponse"); //todo: redirect to confirm success page
uri.SetQueryParam("key", "wc_order_5b7b84b91a882");
uri.SetQueryParam("cancel_url", "http://localhost:49725/home/FailiureResponse");
uri.SetQueryParam("order_id", "36");
uri.SetQueryParam("invoice", "PREFIX-36");
uri.SetQueryParam("ipn_url", "http://localhost:49725/?wc-api=WC_Gateway_Coinpayments");
uri.SetQueryParam("first_name", "John");
uri.SetQueryParam("last_name", "Smith");
uri.SetQueryParam("email", "a#a.com");
uri.SetQueryParam("want_shipping", "1");
uri.SetQueryParam("address1", "228 Park Ave S&address2");
uri.SetQueryParam("city", "New York");
uri.SetQueryParam("state", "NY");
uri.SetQueryParam("zip", "10003-1502");
uri.SetQueryParam("country", "US");
uri.SetQueryParam("item_name", "Order 33");
uri.SetQueryParam("quantity", "1");
uri.SetQueryParam("amountf", "100.00000000");
uri.SetQueryParam("shippingf", "0.00000000");
return Redirect(uri.ToString());
}
This will be redirected to the coinpayment site, once payment done, it is showing the following screen.
And trying to get data when user click on back to seller's site, I have tried to get data using Request.Form, but not getting any value in form.
The same thing, working with this woocommerce code, but I have no idea of PHP and how they are dealing with it.
Any thought to get IPN response?
Note: there is no development documentation or sample code available for IPN in .NET
Edit
I'm trying to get value from IPN success
Public ActionResult SuccessResponse()
{
var ipn_version = Request.Form["ipn_version"];
var ipn_id = Request.Form["ipn_id"];
var ipn_mode = Request.Form["ipn_mode"];
var merchant = Request.Form["merchant"];
var txn_id = Request.Form["txn_id"];
var status = Request.Form["status"];
return Content(status);
}
You cannot use localhost for a IPN callback. You must use a public domain name.
As an example I would change the following parameters:
var uri = new UriBuilder("https://www.coinpayments.net/api.php");
uri.SetQueryParam("success_url", "http://kugugshivom-001-site1.atempurl.com/Home/SuccessResponse");
uri.SetQueryParam("cancel_url", "http://kugugshivom-001-site1.atempurl.com/Home/FailiureResponse");
uri.SetQueryParam("ipn_url", "http://kugugshivom-001-site1.atempurl.com/Home/CoinPaymentsIPN"); // Public ActionResult CoinPaymentsIPN()
Since you are creating your own gateway you also need to implement it properly as described in the documentation at CoinPayments API and Instant Payment Notifications (IPN).
I have tested your success_url endpoint, and got status code: 100 (when entering status:100). I see you use form-data, but I don't know if that's on purpose / required.
Postman POST http://kugugshivom-001-site1.atempurl.com/Home/SuccessResponse
In Body tab form-data is selected with Bulk Edit values:
ipn_version:1.0
ipn_type:api
ipn_mode:hmac
ipn_id:your_ipn_id
merchant:your_merchant_id
txn_id:your_transaction_id
status:100
As updated answer stated by #Gillsoft AB, you should need to use valid IPN URL from the code end. Also webhook would not work with localhost. thus, you should listen the request with live server.
Simplest way to check webhook response is to use online tool such as Webhook Tester, it will provide an URL which you have to set as your IPN URL, whenever server will sends the data, you can simply see it to the web. To check that, create one URL and set as your IPN URL as below:
uri.SetQueryParam("ipn_url", "https://webhook.site/#/457f5c55-c9ce-4db4-8f57-20194c17d0ae");
After that run the payment cycle from local machine, payment server will sends notification to that IPN URL.
Make sure you understood it right! success_url and cancel_url are for user redirection, you will not get any response code over there, inspection of seller's store URL give your exact same URL that you have been passing though, so it is recommended to use unique URLs for each order(i.e add order id at last to the URL) which will give you an idea which order payment has been done or canceled.
http://localhost:49725/home/SuccessResponse?orderid=123
In order to test your local code, add following changes and deployed it to server.
1) Add one new method which will listen IPN response
[ValidateInput(false)]
public ActionResult IPNHandler()
{
byte[] param = Request.BinaryRead(Request.ContentLength);
string strRequest = Encoding.ASCII.GetString(param);
//TODO: print string request
//nothing should be rendered to visitor
return Content("");
}
2) Pass IPN URL while creating a request:
public ActionResult IPN()
{
var uri = new UriBuilder("https://www.coinpayments.net/index.php");
...
..
uri.SetQueryParam("success_url", "http://localhost:49725/home/SuccessResponse");
uri.SetQueryParam("cancel_url", "http://localhost:49725/home/FailiureResponse");
uri.SetQueryParam("ipn_url", "http://localhost:49725/home/IPNHandler");
....
..
return Redirect(uri.ToString());
}
You will get all status code responses in IPNHandler method.
Hope this helps!
I'm developing a graphic user interface where the user can send a message to mutuple user using Twilio API in c#
I'm trying to bind a list view to the status of each number being sent and I also want to know the status of the message every time the user click on refresh list view
public void sendSMS(string ssid, string token , string fromNumber, List<string>TOnumbersList ,string msgBody )
{
TwilioClient.Init(ssid, token);
foreach (var toNumber in TOnumbersList)
{
var message = MessageResource.Create(
to: new PhoneNumber(toNumber),
from: new PhoneNumber(fromNumber),
body: msgBody,
provideFeedback: true,
statusCallback: new Uri("http://requestb.in/1jnk4451"));
ListViewItem items = new ListViewItem(message.To);//This show the number being sent to ( delivered number)
items.SubItems.Add(message.Status.ToString()); //Refresh the status WHERE number = message.To
items.SubItems.Add(message.ErrorCode.ToString());//Show error code in case
items.SubItems.Add(message.ErrorMessage); // In case error message show them
listView1.Items.AddRange(new ListViewItem[] { items });
}
}
Twilio API is doing the perfect job updating the status so everytime I go click the link I can see the status. as explained in this documentation Track Delivery Status of Messages in C#
But is It possible to bind a list view so it can be updated everytime the user click on refresh list view ?
Or what is the best way to dynamically show the message status from the URI http://requestb.in/1jnk4451? Maybe embedding a webpage would be better ?
Thank you
Twilio developer evangelist here.
Rather than using the RequestBin URL, if you provide a URL to your own application then you can write an endpoint that receives the status updates of the messages. That way you can store the status yourself and update the list view without having to loop through all the messages.
[Edit] In more detail:
When you send an SMS message with Twilio using the REST API you can set a statusCallback URL to receive updates about the message as it processes through from Twilio to the network and the device.
Twilio will make HTTP requests to this URL as the message goes through each state, the possible states being queued, failed, sent, delivered, or undelivered. Twilio sends a number of parameters as part of this request, some are general ones about the message and some are about the actual status.
To receive these requests you need to set up a web server. I'm not a C# developer I'm afraid, however we have a guide on how to set up a C# and ASP.NET MVC environment that can receive webhooks that should be able to help you there.
Let me know if this helps a bit more!
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.
I'm using SDK V3 for .net IppDotNetSdkForQuickBooksApiV3 and trying to send the email with the invoice after I create it (which I found weird that the Quickbook doesn't do it automatically after I create the invoice, so maybe I'm doing something wrong).
So this is how it goes:
//Get customer
var customerQueryService = new QueryService<Customer>(context);
var customer = customerQueryService.ExecuteIdsQuery("query to get customer");
/*I fill the invoice with data
..
..
..*/
//Call to generate invoice
var invoiceAdded = dataService.Add(invoice);
//Email to send
invoiceAdded.BillEmail = customer.PrimaryEmailAddr;
invoiceAdded.EmailStatus = EmailStatusEnum.NeedToSend;
invoiceAdded.EInvoiceStatusSpecified = true;
//Send Email
dataService.SendEmail(invoiceAdded);
This is where I'm getting troubles, first I notices that the object from customer.PrimaryEmailAddrhas no id:
So when I'm gonna make the call to send the email after I created the invoice I get the following exception:
Object not found: EmailAddress
If I go to my Quickbook site I do have my customer of course and that is his email.
So what I'm doing wrong?
Try this:
//Call to generate invoice
var invoiceAdded = dataService.Add(invoice);
//Send Email
dataService.SendEmail<Invoice>(invoiceAddded, customer.PrimaryEmailAddr.Address);
The second argument that you pass to that method is a specific email that will override the default email in the invoice object, which should fix this bug. Basically there are two versions of the request that can be used to send invoices, there's the following:
POST /v3/company/<companyID>/invoice/<invoiceId>/send
And then this one:
POST /v3/company/<companyID>/invoice/<invoiceId>/send?sendTo=<emailAddr>
So when you pass just the invoice, it maps to the first request by taking your invoice object and figuring out what the id is, a lot of those fields however don't get filled by default by QBO for some reason, this would be why you are getting an error with passing just the invoice, because for some reason it relies on that email having an id which I guess QBO doesn't auto-fill for you, so what I would do is use the other overload for this method which maps to the second request, which explicitly sets the email address in the request, that way no matter what, as long as you passed a valid email address, and the invoice exists, the request can't fail, otherwise you're relying on a bunch of data getting filled properly which leaves you open to a lot of bugs, the QuickBooks API in general is very, very prone to bugs and doesn't really help you out when you get them, so in general the less bugs you expose yourself to, the better in my opinion.
I'm trying to write a webhook for Mailchimp events using API version three and I'm struggling a bit due to their lack of a library, documentation, and basic examples, but also my lack of experience.
I know we should secure the webhook by putting a secret in the URL, that's fine. By the way, MailChimp doesn't allow configuration of basic access authentication in their portal.
They say "While we do send HTTP POST for actual data, our webhook validator will only send HTTP GET requests. You'll need to allow both in order for your webhook to function properly." Ok, I guess I can use Request.HttpMethod to return a success status code if it's a GET and process some data if it's a POST.
Not sure how to pick stuff out of the request though, and ideally don't want to write heaps of classes and properties to cover all the event types, C# being statically typed, although I guess the dynamic keyword is also an option.
Do I need to deserialise JSON? I've only written one webhook before for another API with the help of a library, you could construct an API event using either a string, stream, or textreader, which came from the request. The library made everything very simple.
For reference, there's also this question which shows how to get some data using PHP: How to pass email address to webhook from mailchimp
The data that gets posted looks like this (supposedly, there doesn't seem to be any documentation for V3):
"type": "unsubscribe",
"fired_at": "2009-03-26 21:40:57",
"data[action]": "unsub",
"data[reason]": "manual",
"data[id]": "8a25ff1d98",
"data[list_id]": "a6b5da1054",
"data[email]": "api+unsub#mailchimp.com",
"data[email_type]": "html",
"data[merges][EMAIL]": "api+unsub#mailchimp.com",
"data[merges][FNAME]": "MailChimp",
"data[merges][LNAME]": "API",
"data[merges][INTERESTS]": "Group1,Group2",
"data[ip_opt]": "10.20.10.30",
"data[campaign_id]": "cb398d21d2",
"data[reason]": "hard"
I just basically need to get this data into variables so I can sync it with my database.
Here's my (skeleton) controller so far:
[Route("mailchimp/newsletter-webhook/super-secret-key-goes-here")]
public HttpStatusCodeResult ChargeBeeWebhook()
{
return new HttpStatusCodeResult(200);
}
Assuming you've already set up your MailChimp Webhooks as described here, you can get the posted data using Request.Form syntax. Using the example posted data from the question, here's how your controller code should look like:
[AllowAnonymous]
public void ChargeBeeWebhook()
{
// type variable will be "unsubscribe"
string type = Request.Form["type"];
// action variable will be "unsub"
string action = Request.Form["data[action]"];
// reason variable will be "manual"
string reason = Request.Form["data[reason]"];
// ...
// ...
// ... do the same with the rest of the posted variables
// ...
// sync the posted data above with your database
// ...
// ...
}