We are very happy to announce ASP.NET WebHooks V1 RTM making it easy to both send and receive WebHooks with ASP.NET.
WebHooks provide a simple pub/sub model for wiring together Web APIs and services with your code. A WebHook can be used to get notified when a file has changed in Dropbox, a code change has been committed to GitHub, a payment has been initiated in PayPal, a card has been created in Trello, and much more — the possibilities are endless! When subscribing, you provide a callback URI where you want to be notified. When an event occurs, an HTTP POST request is sent to your callback URI with information about what happened so that your Web app can act accordingly. WebHooks happen without polling and with no need to hold open a network connection while waiting for notifications.
Because of their simplicity, WebHooks are already exposed by most popular services and Web APIs. To help managing WebHooks, Microsoft ASP.NET WebHooks makes it easier to both send and receive WebHooks as part of your ASP.NET application:
- On the receiving side, it provides a common model for receiving and processing WebHooks from any number of WebHook providers. It comes out of the box with support for Azure Alerts, BitBucket, Dropbox, Dynamics CRM, GitHub, Kudu, Instagram, MailChimp, MyGet, PayPal, Pusher, Salesforce, Slack, Stripe, Trello, Visual Studio Team Services, WordPress, and Zendesk as well as IFTTT and Zapier, but it is easy to add support for more.
- On the sending side, it provides support for generating WebHooks as a result of changes in your service. It helps managing and storing subscriptions as well as sending event notifications to the right set of subscribers. This allows you to define your own set of events that users can subscribe to. ASP.NET WebHooks provides a lot of flexibility for sending and persisting WebHooks, scaling your solution up and out, as well as sending WebHooks from WebJobs and other places in addition to your Web Application.
The two parts can be used together or apart depending on your scenario. If you only need to receive WebHooks from other services, then you can use just the receiver part; if you only want to expose WebHooks for others to consume, then you can do just that.
In addition to hosting your own WebHook server, ASP.NET WebHooks are part of Azure Functions where you can process WebHooks without hosting or managing your own server! You can even go further and host an Azure Bot Service using Microsoft Bot Framework for writing cool bots talking to your customers!
The WebHook code targets ASP.NET Web API 2 and ASP.NET MVC 5, is available as Open Source on GitHub, and as Nuget packages.
A port to the ASP.NET Core is being planned so please stay tuned!
Receiving WebHooks
Dealing with WebHooks depends on who the sender is. Sometimes there are additional steps registering a WebHook verifying that the subscriber is really listening. Often the security model varies quite a bit. Some WebHooks provide a push-to-pull model where the HTTP POST request only contains a reference to the event information which is then to be retrieved independently.
The purpose of Microsoft ASP.NET WebHooks is to make it both simpler and more consistent to wire up your API without spending a lot of time figuring out how to handle any WebHook variant:
A WebHook handler is where you process the incoming WebHook. Here is a sample handler illustrating the basic model. No registration is necessary – it will automatically get picked up and called:
public class MyHandler : WebHookHandler
{
// The ExecuteAsync method is where to process the WebHook data regardless of receiver
public override Task ExecuteAsync(string receiver, WebHookHandlerContext context)
{
// Get the event type
string action = context.Actions.First();
// Extract the WebHook data as JSON or any other type as you wish
JObject data = context.GetDataOrDefault<JObject>();
return Task.FromResult(true);
}
}
Finally, we want to ensure that we only receive HTTP requests from the intended party. Most WebHook providers use a shared secret which is created as part of subscribing for events. The receiver uses this shared secret to validate that the request comes from the intended party. It can be provided by setting an application setting in the Web.config file, or better yet, configured through the Azure portal or even retrieved from Azure Key Vault.
For more information about receiving WebHooks and lots of samples, please see these resources:
- Sending and Receiving WebHooks triggered by workflows and custom workflow activities from Microsoft Dynamics CRM.
- Subscribing to Instagram listening for media posted within a given geo-location and associated sample.
- Subscribing to new and updated leads and opportunities from Salesforce.
- Subscribing to Slack WebHooks and Using Slack Slash Commands enabling rich commands with structured data, images, and more; see associated sample.
- Integrating with IFTTT and Zapier to Monitor Twitter and Google Sheets and associated sample.
- Receiving WebHooks from Azure Alerts and Kudu (Azure Web App Deployment) and associated sample.
- Sample building a Bitbucket WebHooks receiver.
- Sample building a Stripe WebHooks receiver.
Sending WebHooks
Sending WebHooks is slightly more involved in that there are more things to keep track of. To support other APIs registering for WebHooks from your ASP.NET application, we need to provide support for:
- Exposing which events subscribers can subscribe to, for example Item Created and Item Deleted;
- Managing subscribers and their registered WebHooks which includes persisting them so that they don’t disappear;
- Handling per-user events in the system and determine which WebHooks should get fired so that WebHooks go to the correct receivers. For example, if user A caused an Item Created event to fire then determine which WebHooks registered by user A should be sent. We don’t want events for user A to be sent to user B.
- Sending WebHooks to receivers with matching WebHook registrations.
As described in the blog Sending WebHooks with ASP.NET WebHooks Preview, the basic model for sending WebHooks works as illustrated in this diagram:
Here we have a regular Web site (for example deployed in Azure) with support for registering WebHooks. WebHooks are typically triggered as a result of incoming HTTP requests through an MVC controller or a WebAPI controller. The orange blocks are the core abstractions provided by ASP.NET WebHooks:
- IWebHookStore: An abstraction for storing WebHook registrations persistently. Out of the box we provide support for Azure Table Storage and SQL but the list is open-ended.
- IWebHookManager: An abstraction for determining which WebHooks should be sent as a result of an event notification being generated. The manager can match event notifications with registered WebHooks as well as applying filters.
- IWebHookSender: An abstraction for sending WebHooks determining the retry policy and error handling as well as the actual shape of the WebHook HTTP requests. Out of the box we provide support for immediate transmission of WebHooks as well as a queuing model which can be used for scaling up and out, see the blog New Year Updates to ASP.NET WebHooks Preview for details.
The registration process can happen through any number of mechanisms as well. Out of the box we support registering WebHooks through a REST API but you can also build registration support as an MVC controller or anything else you like.
It’s also possible to generate WebHooks from inside a WebJob. This enables you to send WebHooks not just as a result of incoming HTTP requests but also as a result of messages being sent on a queue, a blob being created, or anything else that can trigger a WebJob:
The following resources provide details about building support for sending WebHooks as well as samples:
- Sending WebHooks with ASP.NET WebHooks Preview describes the basic model for handling WebHook subscriptions, generating event notifications, and for receiving such WebHooks. Also check out the associated sample of a basic Web Application sending custom WebHooks and a sample receiving custom WebHooks.
- The blog New Year Updates to ASP.NET WebHooks Preview Dec 2015 goes into details for how to send events to all users and how to scale up and out your solution using persistent queues. There is also a sample scaling out WebHooks by sending them to a queue.
- The blog Sending ASP.NET WebHooks from Azure WebJobs describes how to send WebHooks from WebJobs, which enable you to generate WebHooks triggered by a number of sources including queues, blogs, etc. See also the associated sample sending WebHooks from a WebJob.
- The blog Updates to Microsoft ASP.NET WebHooks Preview Nov 2015 describes how to store WebHook registrations in SQL and how to register WebHook modules with a dependency engine.
Thanks to all the feedback and comments throughout the development process, it is very much appreciated!
Have fun!
Henrik
In version 1.2.1 there is an issue with Microsoft.AspNet.WebHooks.AzureWebHookDequeueManager.SendWebHookWorkItemsAsync.
Following line HttpResponseMessage[] array = await Task.WhenAll( list );
Is not wrapped inside try – catch and therefore failure in any request is handeled elsewhere and reported as failure in reading the queue. Moreover failure on the call will result in endless retry and the message will not be removed from the message queue.