Debugging remote webhooks with ngrok and Visual Studio

webhooks

Over the past few years, we’ve regularly built new integrations into DoneDone. Most of our integrations use webhooks, which are callbacks sent from a remote third-party service to your application. Webhooks are simple yet powerful, and allow us to easily automate tasks like processing incoming emails and updating issues from Git or SVN commits.

The most difficult aspects of working with webhooks are often testing and debugging. You need a way to temporarily point the webhook at your local development machine, then inspect the data payload when it arrives. Ideally, you need to attach a debugger so you can step through your code to see how the incoming data is being processed.

Here’s a short walkthrough showing the process we use to work with remote webhooks locally using Visual Studio.

Create a New Web Application

First, we’ll create a new web application for our demonstration. Open Visual Studio and choose File > New Project > ASP.NET MVC 4 Web Application, and name the project WebhookTest. Choose the Internet Application project template when prompted. Once the project loads, verify you can run it locally by clicking Start Debugging or pressing F5. You should see the application’s welcome screen in your web browser:

mvc-app-home

To keep things simple, we’ll simply add a new action to the existing Home Controller. Our new action will receive our webhook data. Open Controllers/HomeController.cs and add the following method below the Contact() method:

[HttpPost]
public ActionResult Webhook()
{
    var json = "";
    using (var inputStream = new System.IO.StreamReader(Request.InputStream))
    {
        json = inputStream.ReadToEnd();
    }

    return Json(new { message = "success!" });
}

This method is accessible via HTTP POST, reads the input stream as a string, then returns a simple JSON success message. Add a breakpoint to the first line of the method, so that you can step through the code when the action responds to a request.

controller-breakpoint

Configure IIS

By default, Visual Studio uses its built-in web server to run local web applications. However, the built-in server cannot accept incoming requests, so we’ll need to configure our web application to use the full-featured IIS web server. (Note: If you’ve not yet installed IIS, you can follow these instructions.)

Open the Internet Information Services (IIS) Manager, right-click the Sites folder, then choose Add Web Site. Enter WebhookTest as the Site name, then choose the path to your ASP.NET web application in the Physical Path input (this is the folder that contains your web.config file). Change the Port number to 81 (or any other port not in use by IIS on your machine), then click OK.

iis-add-web-site

Open a web browser and navigate to http://localhost:81, and verify that your application loads as expected. (Note: If you receive an error, you may need to set the IIS application pool to use .NET 4.0, or you may need to give your application pool user permissions to your ASP.NET project folder.)

Use IIS with Visual Studio

Now that we’ve created an IIS site for our application, we need to configure the project to use it instead of the VS development server.

We’ll need to re-open Visual Studio in Admin mode, so close VS completely and save your project files if prompted. Then, Shift+Right-Click on the Visual Studio icon and choose Run as Administrator. Once VS loads, re-open your application project, then right-click the application name in the Solution Explorer and choose Properties.

Click the Web tab, locate the Servers section, and choose Use Local IIS web server. Uncheck Use IIS Express, then enter the following as the Project URL: http://localhost:81 (or whichever port number you used when creating the IIS web site). Click Create Virtual Directory, then start debugging your project and verify that the application homepage loads in your web browser.

visual-studio-properties-web

We’re now running our web application through IIS, which will allow us to accept incoming traffic from remote hosts.

Install ngrok

Our next step is to allow remote webhooks to send data to our development machine. We could do this by configuring firewall rules and opening network ports, but that takes a bit of time. We also don’t want to leave our environment exposed to the outside world when we’re not testing, so it would be an additional pain to constantly remember to enable and disable the rules when needed.

Instead, we’ll use a simple command-line tool called ngrok, which automatically creates a publicly-accessible URL that tunnels to a port on your local computer. Once downloaded, unzip ngrok.exe and place it somewhere convenient on your PC.

Next, Shift+Right-Click inside the folder where you placed ngrok, and choose Open command window here. Enter the following command: ngrok http 81

ngrok will create a tunnel to the port we specified, and will even give us an easy-to-use domain name. Make a note of the domain that ngrok has assigned to your tunnel – in the screenshot, the ngrok URL is efed1867.ngrok.io.

ngrok

If we try to use our ngrok URL right now, the request will get routed to our local machine, but IIS won’t know what to do with it. We still need to configure our IIS site to listen for requests that arrive from our ngrok URL.

Bind the ngrok URL to Your Application

Switch back to the IIS manager and select your WebhookTest web site. Click Bindings in the sidebar, then click the Add button. Enter your ngrok URL in the Host name field, then click OK (leave the port number as port 80). Now try visiting your ngrok URL in your web browser, and you should see your application home page!

iis-binding

Test a GitHub Webhook

Now that we have a publicly-accessible URL that’s tunneling to our local application, let’s test it out with a real-world webhook.

Go to GitHub.com and login or sign up for a free account. Create a test repository, or navigate to an existing repository you own. Click Settings in the repository sidebar, choose Webhooks & Services, and click Add a webhook. For the Payload URL, enter your ngrok URL followed by /home/webhook. This is important, as this is the URL of the Webhook action we added to the Home controller earlier. Your Payload URL should look like this: efed1867.ngrok.io/home/webhook

Leave the other settings as their default values, and click Add webhook.

github-webhook

If your application is still running in debug mode, Visual Studio should have immediately hit the breakpoint you added to the HomeController Webhook method. If your application isn’t running, switch to Visual Studio, start debugging the application, then re-deliver the GitHub webhook.

You can now step through the data as it arrives on your local machine:

vs-inspect-payload

And there you have it! You can now debug data sent from remote services via webhooks directly on your local Visual Studio environment. Our next logical step would be to parse our JSON data using a library like Json.NET, but for brevity we’ll stop at this point.

Thanks for reading – we hope this demo will be helpful as you work with webhooks or other remote services in your own applicaitons.

Jeremy Kratz is a developer at DoneDone. Follow him on Twitter via @jwkratz.