Practical ASP.NET

Serverless C# with Azure Functions: Implementing Webhooks

Azure Functions can be used to trigger event-driven Webhooks. Here’s how.

More on This Topic:

One of the features of Azure Functions is the ability to easily create Webhooks. Webhooks allow integration with other systems, including third-party systems. Essentially, the external system can call an Azure Function when an event happens; in this way, there’s no need to periodically poll an external system to look for changes. If an external system supports Webhooks, it can be configured to point to an Azure Functions Webhook (via HTTP) and call the endpoint with relevant data. Code inside the Azure Function can take this incoming data and perform processing.

Some potential events that can trigger a Webhook:

  • New issue created in source code repository (for example, GitHub)
  • Product purchase completed
  • SMS message sent
  • Social/chat message sent (for example, Slack)
  • Help desk ticket created
  • New comment added on a blog post

Azure Functions currently supports three types of Webhook function triggers:

  • Generic Webhook
  • GitHub Webhook
  • Slack Webhook

Creating a GitHub Webhook
GitHub Webhooks allow a function to be notified on a wide range of events that occur in a GitHub repository, including:

  • Branches created/deleted
  • Issue created, assigned, labeled, edited and so on
  • Pull request opened, edited, closed and so on
  • Pushes to a repository
  • Repository forked

To create an Azure Functions GitHub Webhook, first create a Function App in the Azure Portal, click the New Function button and select the C# GitHub Webhook template, as shown in Figure 1.

[Click on image for larger view.] Figure 1. Creating a GitHub Webhook Azure Function

This will create a function with some starter code that attempts to extract a GitHub comment from the incoming data:

using System.Net;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
  log.Info("C# HTTP trigger function processed a request.");

  // Get request body
  dynamic data = await req.Content.ReadAsAsync<object>();

  // Extract github comment from request body
  string gitHubComment = data?.comment?.body;

  return req.CreateResponse(HttpStatusCode.OK, "From Github:" + gitHubComment);
}

You can write function code to extract different data items depending on what’s configured in GitHub.

Configuring a GitHub Webhook Trigger
In this example, the function will be called every time a new issue is added to the repository.

The first step is to obtain the "GitHub secret" and the function URL for the Azure Function. To do this, click on the GitHub secret item and the function URL item in the Azure Portal function editor and take a copy of the secret and URL as in Figure 2.

[Click on image for larger view.] Figure 2. Obtaining the Function GitHub Secret and URL

Next, head over to GitHub and navigate to the settings for the repository that will have a Webhook configured. In the settings for the repository, navigate to the Webhooks section and choose "Add webhook." Paste in the function URL and secret, and change the content type to "application/json," as shown in Figure 3.

[Click on image for larger view.] Figure 3. Basic GitHub Webhook Configuration

To specify that only specific events will trigger the Webhook, choose "let me select individual events" and then check only the "issues" checkbox. Finally, click "Add webhook" to create it.

Creating Function Code to Extract Issue Data
The (JSON) data payload that will be POSTed to the function URL depends on what events were selected. For example, the issues payload contains a JSON "title" property nested inside an "issue." The following code shows the extraction of the action type and the issue title:

using System.Net;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
  log.Info("C# HTTP trigger function processed a request.");
    
  dynamic data = await req.Content.ReadAsAsync<object>();
    
  string actionPerformed = data?.action;
  string title = data?.issue?.title;    

  log.Info($"Issue {title} was {actionPerformed}");

  return req.CreateResponse(HttpStatusCode.OK);
}
[Click on image for larger view.] Figure 4. Configuring Specific GitHub Events

Testing the Webhook
Now if a new issue (for example, with the title "Something’s Wrong") is added to the repository, the Webhook will be called and the function code executed. The function logs in the Azure Portal show that the Webhook was executed as expected with the following log messages:

2017-03-01T02:54:57.254 Function started (Id=1b6de019-a9a8-47f1-8ae5-317fdf9f0382)
2017-03-01T02:54:57.520 C# HTTP trigger function processed a request.
2017-03-01T02:54:57.817 Issue Something's Wrong was opened
2017-03-01T02:54:57.817 Function completed (Success, Id=1b6de019-a9a8-47f1-8ae5-317fdf9f0382)

To learn more about Azure Functions, check out the documentation here and the series of articles on my blog here.

About the Author

Jason Roberts is a Microsoft C# MVP with over 15 years experience. He writes a blog at http://dontcodetired.com, has produced numerous Pluralsight courses, and can be found on Twitter as @robertsjason.

comments powered by Disqus
Upcoming Events

.NET Insight

Sign up for our newsletter.

I agree to this site's Privacy Policy.