Custom Webhooks in .NET with Emma API (Easily test with Postman)

I couldn’t find many tutorials for creating a simple .NET listener for receiving Webhooks.  The out-of-the-box options in .Net support services for Github, Azure and others but if the API you’re searching for isn’t offered, it’s hard to find documentation that walks you through the process.

Required Skills

This tutorial assumes familiarity with Visual Studio and REST based API calls.  It was originally adapted from this this post and tweaked to incorporate Postman and Emma.  The solution below is only for receiving API calls from JSON requests.

Required Software

  • Visual Studio
  • Postman
  • Azure Subscription
  • Emma Subscription

Project Setup

Begin by creating a blank Web API project in Visual Studio:

Add the following line to your WebAPI Config class.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
 
        // Initialize Generic JSON WebHook receiver
        config.InitializeReceiveGenericJsonWebHooks();
    }
}

Install the following nuget package using the package manager console to obtain the necessary Webhook classes:

Install-Package Microsoft.AspNet.WebHooks.Receivers.Generic

Add the following line of code to aid in routing the requests.  The keys below can be anything you want but must be 32 characters.

<configuration>
<appSettings>
<add key="MS_WebHookReceiverSecret_GenericJson" value="i=1388a6b0d05eca2237f10e4a4641260b0a08f3a5,z=80ad19e357b01a04fe767067df7cd31b96a844e1" />
</appSettings>
<system.web>

The WebHookHandler base class is required to receive Webhook requests.   Paste in this template code:

using Microsoft.AspNet.WebHooks;
using Newtonsoft.Json.Linq;
using System.Threading.Tasks;

namespace MyWebhook
{
      public class GenericJsonWebHookHandler : WebHookHandler
     {
        public GenericJsonWebHookHandler()
        {
           this.Receiver = "genericjson";
        }

        public override Task ExecuteAsync(string generator,                     WebHookHandlerContext context)
        {
          // Get JSON from WebHook
          JObject data = context.GetDataOrDefault<JObject>();

           if (context.Id == "i")
           {
              //You can use the passed in Id to route differently depending on source.
           }
           else if (context.Id == "z")
           {
           }

           return Task.FromResult(true);
         }
   }
}

Let’s test to see if the handler works by building the solution and copying the URL from the output.

(There won’t be a landing page cause the server doesn’t return anything).

localhost (1)

Paste this URL into Postman and append the following:

Localhost:{Your Port}/api/webhooks/incoming/genericjson/z?code=80ad19e357b01a04fe767067df7cd31b96a844e1

URL format for .Net Webhook            URL endpoint from your webconfig

Enter anything you want into the Body.  Note: You need to include something in the Body or the GenericJson config will error out.

bodyinput

Set a breakpoint and  send the request and make sure it comes through.

postman-local

Connecting to Emma

To connect to Emma you need a public facing API.  Right click the solution and select “Publish” to send the solution to Azure for hosting.  Prior to clicking “Create Profile”, click the Advanced link to set the configuration to Debug to be able to debug from the server.

publish

Attach your application to the remote server for debugging:

View ->  Cloud Explorer ->  Find your application ->  “Attach to Debugger”

Replace localhost with your new URL and add HTTPS at the beginning or it won’t work.

https://{The Azure URL youre given}/api/webhooks/incoming/genericjson/z?code=80ad19e357b01a04fe767067df7cd31b96a844e1

You can test the listener again via Postman if you like by pasting in the URL above. 

Log into your Emma account and retrieve your public API key and Account number into Postman and create your first Webhook with your credentials from above.

emma-1

The example below sends a request each time a contact record is updated within Emma.  For a full list of available Webhooks visit the Emma API documentation.

postman-webhook

Authenticate via the Authorization tab and enter your Emma credentials.

authenticate

Send the request via Postman and it should return to you the ID of your Webhook.

Go back to your application in Visual Studio and attach to the debugger.

Test the Webhook by logging into your Emma platform and updating a contact. If you’re connected to the remote server, your breakpoint should be hit within a minute or so.

In order to use the JSON object you received from Emma you need Newtonsoft and a way to deserialize the Emma request.

using Newtonsoft.Json;

public override Task ExecuteAsync(string generator,, WebHookHandlerContext context)
{     

  JObject data = context.GetDataOrDefault<JObject>();

EmmaWebhook request = JsonConvert.DeserializeObject<EmmaWebhook>(data.Root.ToString());

You need a class to map the deserialization

        public class EmmaWebhook

        {

            public string event_name { get; set; }

            public Data data { get; set; }

        }

        public class Data

        {

            public string member_id { get; set; }

            public string account_id { get; set; }
            //The Emma result can also come with a TimeStamp
            //but I didn't want to deal with a DateTime property.

        }

Update a contact in Emma.  If you’ve entered everything correctly, you should see your result in the debugger 😉

debugger

Troubleshooting

If you experience issues where Emma is not sending the request, make sure your webhook is registered.  You can see registered webhooks with the following GET request in Postman:

https://api.e2ma.net/{Your Account Id}/webhooks.

If that doesn’t help connect your Emma account to Zapier and see if Zapier is able to receive the request.  If you’re still unable to receive the request, go back into the article and make sure you did not miss any details such as using the proper key length or HTTPS.