Using Webhooks with iotQi Alerts

Your IoT devices must be able to raise events in your back-end applications

Fortunately, LooUQ iotQi has established patterns for both commands (to device) and webhooks (event from device). This guide explains iotQi alert webhooks and shows how to implement a webhook receiver in a Windows console application; this same approach can be used with WPF (Windows Presentation Foundation) and server based ASP.NET Web API projects. This article explains how to automate iotQi alerts with webhooks, but the concepts here apply to webhooks in general and most parts of this article can be applied to other systems sourcing webhook events.

Webhooks are a lightweight HTTP pattern providing a simple pub/sub model for wiring together Web APIs and SaaS services like LooUQ iotQi. When an event happens on a iotQi device, you can send an alert to the LooUQ cloud. Based on rules you setup for your subscription, a notification is sent to designated recipients. One form of notification is a webhook. For this type of notification, your application will receive a HTTP POST request with a request body containing JSON data originating from your device’s alert.

The discussion below shows you how to setup the required pieces to turn your device events into event actions on your back-end applications using this webhook pattern.

Configure Your Subscription for Webhook Notifications

In iotQi Setup you can define notification rules for device events. These rules use match filters and designate recipients for notifications. Using these rules, you can map device alerts to notifications as emails, text messages, or webhook requests.

From your list of Subscriptions, click Details to the right of the subscription you want to setup a webhook notification for, this will take you to that subscription’s options menu.

Choose Notification Rules from the Subscription menu, this will show you any existing notification rules for the subscription in the list area below the subscription options menu.

Select Create New Notification Rule to add a new rule for your webhook.

Complete the notification rule form, include the full HTTP addresses like shown below. If you are not listening on port 80 (default HTTP port number) you will need to designate it as shown in the 1st example.

The webhook notification will be delivered as a HTTP POST to the address you specify. You can optionally use HTTPS (SSL\TLS). If you implement HTTPS with a self-generated certificate (one you did not purchase from a certificate company) you can check the box to Ignore Cert Trust Errors. The alert data will still be SSL encrypted, but we won’t validate the certificate’s trust path.

Coding A Webhook Receiver

You webhook receiver can be deployed on a web server such as IIS (Internet Information Server) or can be self-hosted. You may want to self-host if you are say using a server or workstation running a dedicated application without installing a web server. This could be a console application or a dashboard application running a WPF application (Windows Presentation Foundation). Our demo found on GitHub and described here is for a self-hosted Windows console application. The self-hosted example illustrates same steps that are required if you want to deploy your receiver on a web server running IIS, while using ASP.NET Web API 2. If you are already familiar with Web API, you will recognize most of the code in our sample.

Basically, your webhook receiver is a web API server, regardless of whether you run it on a workstation or server. You will be implementing the Microsoft Web API 2 pattern in this example. To accomplish this without installing IIS, we will be using Microsoft Katana technology, which is Microsoft's implementation of OWIN.

We will need the following functions (classes) built. None of the below items are very large. In the sample you can download from GitHub here, all of the classes are in separate files to make copying to your project easier.

Class

Description

IotqiAlert

A definition of the data from the LooUQ cloud representing the device event

The API controller with a POST action to receive the webhook notification

IotqiWebhook

A helper or utility class containing methods to validate the received notification

WebhookDispatcher

A thin class that defines a .NET event that your application can subscribe to. You alternately can wire subscriber functions directly into your controller action, but by using the dispatcher you will better separate code responsibilities.

Program

The main program of the console application. Contains initialization and main loop processing to demonstrate the webhook processes.

Rather than show each of the source files here I suggest GitHub and review them or download them to your development environment. We have placed numerous comments about each of the duties and approaches for the files mentioned above. If you have questions while reviewing, building or testing please reach out by opening a support request.

Setting Up the Environment for Self-Hosting

In many cases your webhook receiver will be resident on a server that is member of your enterprise infrastructure. For this situation, your application should follow a typical Web API pattern (such as ASP.NET Web API 2).

But if your webhook receiver is a Windows workstation or similar lightweight platform you can self-host without running a full web server technology stack. Our demo example found on GitHub, follows the self-hosted approach. For self-hosting, we use Microsoft Katana\OWIN to self-host the Web API receiver functionality, to service the arriving webhook events.

Self-hosting is simple, but going that route will impose a couple extra tasks that you must complete. Normally, Internet Information Server (IIS) will handle network registration and IP\HTTP reservations; this also includes firewall rules. But when you are self-hosting, you will need to handle these configuration tasks yourself.

Moving Outside, Beyond localhost

To self-host without IIS you need perform some network configuration so that your webhook events (http requests) make it to your receiver application. These steps are not required for testing with localhost.

Required…

HTTP.SYS must be listening on the IP address or host name you are using for your application. This could be all interfaces on your computer host, or only selective interfaces.

The URL you are using must be authorized to receive requests with HTTP.SYS.

The Windows firewall must allow requests to reach HTTP.SYS.

Listening on Your Target IP

These actions make sure your host (workstation) is listening for HTTP request at the intended IP address. To check your current settings, use this command from an administrator elevated command prompt.

netsh http show iplisten

To add an IP address to the IP listen list use this command:

netsh http add iplisten ipaddress=<ip_address>

Or use address of 0.0.0.0 for any available host address

netsh http add iplisten ipaddress=0.0.0.0

URL ACL Reservation

Applications receiving requests for URLs must have sufficient permission to do so. One way to do this is to run your application as an Administrator, this is the brute force way and not recommended. Alternately you can register a URL ACL (access control) so that you can run your application without special permissions. This is best accomplished with a wildcard value, if you can be assured your port number is unique on a workstation. Here I used my local username as the account where I will be running the webhook receiver.

netsh http add urlacl http://+:8070/ user=gt

This created the following reservation

Reserved URL : http://+:8070/

User: LVOX1-MANTA\GT

Listen: Yes

Delegate: No

SDDL: D:(A;;GX;;;S-1-5-21-3539391823-863078876-1109220060-1001)

You can view URL ACL entries with:

netsh http show urlacl

Windows Firewall Rule

Lastly you must configure the Windows firewall to allow the incoming HTTP request connection. You do this within Windows Firewall with Advance Security, by creating a custom inbound rule (shown here is _iotQi webhook).

Create you New Rule as follows:

In Windows Firewall with Advanced Security

Select Inbound Rules (on the left navigation panel)

Add a New Rule (on the right navigation panel)

Rule Type: Custom

Program: This program path: SYSTEM

Protocol: TCP, Local Port (range suggested like: 8080-8089)

Scope: Any IP address (unless you want to be more specific)

Action: Allow the connection

Profile: Leave all checked (unless you are aware of a more restrictive policy)

Name: Enter a descriptive name and optional description paragraph

Using Postman to Test Your Webhook Receiver

A quick way to interactively test your webhook receiver code is to use Postman (or CURL, but we like Postman) to test the webhook API, remember a webhook is nothing more than a “reverse API” where the iotQi cloud calls your application.

By example, LooUQ has a sample to simulate a smart parking meter (named parkingOccupied, located in the \examples folder that is included with the iotQ-Arduino-Client repository on GitHub). We used Postman to test the parkingOccupied demo, you can use the sample patterns below to get started with this approach to test your webhook application. There is a separate guide on the LooUQ Support Center dedicated to using Postman here.

You can choose to implement webhook signing or not during testing; if the X-Iotqi-Signature header is present the iotQi webhook receiver logic will validate it. To skip validating the signature, do not include the X-Iotqi-Signature header.

Test Body (copy and paste into Postman)

You can copy and paste a JSON payload (like above) into the body of your POST request as shown below. To enable the automatic JSON decode built into our sample controller it is required that you set the body type to raw and select the JSON (application/json) option; this automatically adds a Content-Type header to your outgoing POST request.

While testing with Postman, you can optionally test the iotQi signing function by setting up your own signature header. To do that...

Add a custom header with a Key of X-Iotqi-Signature (see below)

For the initial run, you can use any text string for the Value

Place a breakpoint in your code within the IotqiWebhook.ValidateWebhookObject() method at about line 28 (if statement comparing signatureReceived with signatureComputed)

Copy the value of signatureComputed and paste it into your Postman header

The signature will remain constant as long as you do not change any part of the body