Skip to main content

Notifications

Announcements

No record found.

Webhooks

Objetives.

  • Introduce WebHooks.
  • Create our own NAV WebHooks notifications system as an example.

Definition.

I like this definition over others because is simple and happens to be the first browser search option:
A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST. ... For the user, WebHooks are a way to receive valuable information when it happens, rather than continually polling for that data and receiving nothing valuable most of the time. https://webhooks.pbworks.com/w/page/13385124/FrontPage

Example. Webhooks in well-known platforms.

Facebook enables us to set our own API when some event happens. When some-one write in my Facebook wall I can set my own URL to be notified and process the information that Facebook give us in this callback:
Webhook1.png
There are two parts in this deal:
  • Facebook developers change their software, raise an event and enable a callback and its setup.
  • We make our own API or use a third part API to process this callback, and set the URL in the box we can see above, enabled by Facebook programmers.
The main subject in this post will be the first: enable NAV to setup a third-party URL API callback. The second one not the subject of the post, but this could be an example of JavaScript Callback API implementation:
    if (request.method == 'POST'){
        let body = '';
        var qs = require('querystring');
        request.on('data', (data) => {
            body += data;
        });
        request.on('end', function () {
            var post = qs.parse(body);
            Fichero.writeFileSync('\Prueba.txt',post);   
        });  
        }
The code catches the body request and save it in a file called Prueba.txt. Don´t worry about this code, as I said the final API is not the subject of this post. Our main goal is to catch events and enable user API callbacks.

Webhooks advantages and Navision usage.

Webhooks avoid third parts programs checking from time to time if there is some event to process: instead do that, the event raised a call to our system. In real world could be like Call my cell number when you come.
Navision is using now Webhooks in workflows related to Azure Microsoft Flow. We can set in a workflow step an action that call Microsoft Flow, when an event happens. Not 100% sure, but I think all objects with Webhook in the name are related to Microsoft Flow. For more information you can read: https://marcellusnav.wordpress.com/2017/07/10/my-first-microsoft-flow-with-nav/

Hacking NAV Webhook code.

I think this feature could be done with NAV Workflow and Microsoft Flow, but lets do a homemade system to notify an event to an URL (any URL we set), to have a look inside NAV webhooks code.
We are going to make these steps:

Step 1

Create a new table Change Log Webhook Callback:
Webhook2.png
Field Master Table have the options: Customer, Vendor, Item.

Step 2.

A new Page based this previous table above, to set the URL where we like to be notified, when a master table record is inserted, modified or deleted.

Step 3.

Create a New Codeunit, with a Customer table subscription, and when the table is modified, send a callback to the URL settled in our new table.
LOCAL [EventSubscriber] OnAfterModifyCustomer(VAR Rec : Record Customer;VAR xRec : Record Customer;RunTrigger : Boolean)
WITH ChangeLogWebhookCallback DO BEGIN
  IF NOT GET("Master Table"::Customer) THEN
    EXIT;
  RecordRefInserted.GETTABLE(Rec); 
  JSONText := JSONGenerator.RecorRefToJSONText(RecordRefInserted);
  IF NOT PostHttpRequest("Callback URL",JSONText) THEN;
END;
The elements of the function are: a subscription to OnAfterModify event in Customer table and JSONGenerator, my own Codeunit that formats a Recordref in JSON formatted text.

Step 4.

This Codeunit will clone the Codeunit 1545 PostHttpRequest function. Notice that the URL call code is very simple. We are going to connect with REST services, much easier than SOAP service calls, you will love them. For more info about this function and its variables you can see the original one in Codeunit 1545. This function calls the URL with the JSON text in the body request:
LOCAL [TryFunction] PostHttpRequest(NotificationUrl : Text;JSONText : Text)
HttpWebRequest := HttpWebRequest.Create(NotificationUrl);
HttpWebRequest.Method := 'POST';
HttpWebRequest.ContentType('application/json');
 
RequestStr := HttpWebRequest.GetRequestStream;
StreamWriter := StreamWriter.StreamWriter(RequestStr,Encoding.ASCII);
StreamWriter.Write(JSONText);
StreamWriter.Flush;
StreamWriter.Close;
StreamWriter.Dispose;
 
HttpWebResponse := HttpWebRequest.GetResponse;
HttpWebResponse.Close; // close connection
HttpWebResponse.Dispose; // cleanup of IDisposable

Running the example.

First, we setup our new table:
Webhook3.png
Instead doing our own API to process the information, we are going to use a generic webhook tester, in Webhook.Site. This callback does nothing except show us the response history in the browser. Not very interesting but enough for test.
 Webhook4.png
I changed Customer address to Grace Hooper Street and NAV do the callback to the URL settled in my new table. If we go to page webhook.site, we can see that callback with the JSON structure is done:
Webhook5.png

Conclusion, all about decoupling.

In the example above, we can see the use of events and webhooks in combination. We catch an event and the user can set a URL to callback his own application to do something with the information that webhook gives it.

Comments

*This post is locked for comments