Skip to main content
Version: 4.0.0

Webhooks Integration

General

We provide the possibility within our Tributech Node for external services to receive a wide variety of notifications about internal events via Webhooks. A webhook is an HTTP-based callback function that enables lightweight, event-driven communication between a Tributech Node and a client. The only requirement for a client is to provide a HTTP POST endpoint that returns Status code 200 if an event was successfully received (see Error Handling for more details). In the following section, we will demonstrate how to setup a Tributech Node to send events to an client and how a user can verify that the received event data has not been tampered with.

Tributech Node - Webhooks Focus

Webhook Subscription Management

In order to receive information about a Tributech Node Event we need to create a webhook subscription. A webhook subscription defines the clients HTTP POST endpoint, a selection of Events and a secret to sign the event data. In this section we will show how to create and manage a webhook subscription for a specific event in the Tributech Node Webhook Section.

Tributech Node - Webhooks

Create

We can create a Subscription by simple clicking the ADD SUBSCRIPTION button on the right side of the Tributech Node Webhook Section.

Tributech Node - Webhooks Add Subscription

In the following Dialog Box we add our clients HTTP POST endpoint (e.g. Webhook.site), choose the desired Event Types and add a secret for the event information verification. Its important to note that the secret can later only be updated and not retrieved. In this example we subscribe to the Events SourceCommandRequestEvent, SourceCommandResponseEvent and SourceCommandStateUpdateEvent that occurs when interacting with Source commands that we can trigger within our Quickstart Example (more information about events can be found Events).

Tributech Node - Webhooks Create Wizard

Edit

If we want to update the settings for a Webhook subscription, we can do that via the three dots in the actions column.

Tributech Node - Webhooks Overview Edit

This way the events, webhook url or secret can be adjusted for the current Subscription.

Tributech Node - Webhooks Edit

Deactivate

We can disable the previously created Webhook by clicking the three dots in the action colum and choosing Toggle Active button to pause the notifications.

Tributech Node - Webhooks Deactivate

Deletion

If we want to delete a Webhook subscription we can do that via the three dots in the actions column.

Tributech Node - Webhooks Overview Edit

Webhook Events

A Webhook Event is a json object that is generated by a Tributech Node containing Event specific information when a certain condition is met. This json object is send within a HTTP object to a Webhook Subscription previously defined by a User. In this section we will go into detail which events are supported and what information can be retrieved from it.

Headers

Webhooks send by the Tributech Node are HTTP objects that contain default HTTP information and some Tributech specific attributes, which we will discuss in the following section. The following Headers are included in the HTTP response and contain Tributech specific information:

AttributeDescriptionSample Value
x-tributech-correlationidA trace id to track the data through our node00000000-0000-0000-0000-000000000000
x-tributech-eventidunique identifier through the node (guid) to identify the event49acaa7b-fa72-4863-ab4b-7933fedeb59a
x-tributech-eventevent name to identify the type of eventValueReceivedEvent
x-tributech-signaturetimestampcreation timestamp utc of the signature (timestamp format: ISO 8601)06/16/2023 05:08:46 +00:00
x-tributech-signaturesignature of the webhook eventsha256=0316443119ED851EE18AA6176E8281E6A28
D02A52EAF5DC85D45A6149173F412
x-tributech-timestampevent timestamp utc (timestamp format: ISO 8601)06/16/2023 05:08:43 +00:00

Event Types

When creating a Webhook subscription, we can choose what type of events we want to receive. We will describe in the following section the Events based on type of information they are providing, e.g. Device, Proof, Stream,.. .

Its important to note that each of the Event Types contain a predefined property EventQoS which will be contained in each webhook event indicating the frequency of the events. This property is used by the redelivery mechanism to know how often a event should be handled in case the HTTP POST client response with an error code (more details in Error Handling).

Device Events

Device Events are triggered by interactions with devices and device status changes, this includes enrollments, configuration and source commands.

NameDescription
DeviceConnectionEventOccurs when a Device has changed its connection status
DeviceStateEventOccurs when a Device has changed its own state
GetConfigurationRequestEventOccurs when the Get Configuration Command has been requested
GetConfigurationResponseEventOccurs when the Get Configuration Command has finished and the response was received
IncomingEnrollmentRequestEventOccurs when an Enrollment request was received
SetConfigurationRequestEventOccurs when the Set Configuration Command has been requested
SetConfigurationResponseEventOccurs when the Set Configuration Command has finished and the response was received
SourceCommandRequestEventOccurs when a Source Command is invoked and sent to the Agent
SourceCommandResponseEventOccurs when the Source Command has finished and the response was received
SourceCommandStateUpdateEventOccurs when a Agent or Agent Source has sent a execution state of the current Command

Proof Events

Proof Events describe events related to proof handling and status, e.g. received, valid, stored.

NameDescription
ProofConfirmedEventOccurs when the Proof is successfully placed on the BlockChain
ProofReceivedEventOccurs when a Proof is received from a Device
ProofStoredEventOccurs when the Proof is stored into the Persistence Layer and passed into the Block Chain
ProofValidatedEventOccurs when the Proof is validated

Stream Events

Stream Events provide information when stream management operations are executed.

NameDescription
StreamDeletedEventOccurs when a Agent or Stream is deleted and will be removed from the Node

Twin Events

Twin Events provide information when Digital Twin management operations are executed.

NameDescription
TwinInstanceDeletedEventOccurs when a Digital Twin Instance was removed from the Node
TwinModelDeletedEventOccurs when a Digital Twin Model was removed from the Node

Value Events

Value Events are triggered when the Tributech Node interacts with Stream Values.

NameDescription
ValueReceivedEventOccurs when a Value is received from an Device
ValueStoredEventOccurs when a Value is stored into the Persistence Layer

Error Handling

The error handling of webhook events is based on the status code of the HTTP POST responses to the clients HTTP POST endpoint. Commonly errors occur in the following situations:

  • Network is not available
  • Endpoint described within the subscription is not reachable
  • Endpoint returns something else then a HTTP 200 (OK)

In the case of an error during Webhook Event delivery we implemented an back-off redelivery mechanism that calculates retries based on the formula (Attempt Count + 0,7) ^ 4 + Minimum Retry Interval. The Attempt Count in this formula is dependent on the EventQoS property value (contained in ever webhook event) which is predefined and cannot be changed. A value of 1 indicates that the event is a high frequency event (like data received) and a 2 marks standard frequency events.

  • High frequency events will not be retried
  • Standard Frequency events have 10 retries before they are discarded.

Verification

In order to verify that the received Webhook Event has not been tempered with can verify the event using either OpenSSL or Microsoft C#. We will show in this section how to use both approaches with examples based on the previously created webhook. We will use an arbitrary secret foobar and choose as event ProofStoredEvent (see Event Types) and assume that a Tributech Source is already successfully sending data to a Tributech Node (see QuickStarter Guide).

In our examples we use the free Webhook client Webhook.site to provide the HTTP POST endpoint for the subscription. We will use the website to inspect the received events json payload and HTTP Header attributes. The URL https://webhook.site/#!/view/c445d2cb-bbcb-4db6-b71c-04ca220eea6d in our samples needs to be adjusted to your HTTP POST endpoint. Note that Webhook.site limits the amount of events you can receive and high frequency events will reach those limits quickly.

Tributech Node - Webhooks Overview

Make sure that the Webhook Subscription is configured to listen to ProofStoredEvent events. Shortly after starting the Source and activating the Webhook Subscription we should receive our first events from an active Stream:

Tributech Node - Webhooks Received Event

On Webhook.site we see the Tributech Headers with the following headers (excerpt) on the right side:

Headers
x-tributech-webhook-version2.0.0
x-tributech-eventProofStoredEvent
x-tributech-signaturetimestamp2024-05-28T06:31:14.851318+00:00
x-tributech-signaturesha256=065CF4E993CF1DF7399B2DF64A147567552EB4BB7DD91ACC73840D5B8411B940

The Headers contains the Tributech specific Attribute x-tributech-signature and x-tributech-signaturetimestamp which we will use in the next section to verify that the Payload was not tempered with. The payload itself contains the EventQoS flag for Standard Frequency (see Error Handling) and some information about the Agent, Stream and the Proof. Important to note is that in this example the Root hash of the MerkleTree and the Signature of the RootHash are BASE64 encoded strings in byte array form.

{
"TransactionId":null,
"StreamId":"15caf997-2f2f-43c2-b5e9-6a3ac00b1edb",
"MerkleTreeDepth":5,
"LastTimestamp":"2024-05-28T06:31:14.851318+00:00",
"RootHash":[199,51,64,165,193,234,157,113,156,124,186,212,182,137,146,243,6,114,177,215,234,61,38,199,138,227,179,195,27,237,88,198],
"Signature":[61,212,2,199,55,23,184,147,251,18,36,229,59,39,152,32,196,18,189,170,34,162,147,255,69,59,56,31,63,221,41,226,20,128,238,106,148,148,192,217,48,16,67,197,217,118,56,232,167,63,229,27,247,105,208,79,185,193,254,26,17,200,186,154,192,117,153,60,81,232,196,251,28,128,151,44,32,2,41,188,252,224,241,46,172,77,247,81,61,247,32,220,166,141,107,150,149,230,206,5,114,182,111,202,245,217,172,90,178,75,143,113,43,225,34,4,127,85,167,116,150,114,35,47,124,66,196,194,58,114,12,73,253,13,68,181,11,151,152,212,171,189,146,5,187,71,111,212,88,228,246,246,14,33,88,114,151,17,71,23,231,152,56,219,108,220,60,226,241,53,77,104,153,98,200,127,77,153,160,138,245,76,204,171,68,52,236,169,8,238,46,18,58,231,196,104,77,34,190,14,85,41,220,39,180,117,22,77,18,20,229,55,25,170,22,151,157,254,9,199,52,205,71,51,67,135,229,143,248,27,45,19,141,72,72,43,215,87,85,243,93,186,53,202,186,96,120,202,188,215,125,80,115,120,143,97],
"AgentId":"a324b439-c03b-4e0f-a63e-8067c4423b7b",
"EventQoS":1
}

Openssl

With the following OpenSSL command we verify the previous example values of the x-tributech-signature HMAC SHA256 signature on a unix system:

echo -n '<event-json><signature-timestamp>' | openssl dgst -sha256 -hmac "<webhook-secret>"

In order to work we need to replace the placeholders with concrete values

  • event-json - The received raw json content from the webhook event
  • signature-timestamp - The Header attribute x-tributech-signaturetimestamp value
  • webhook-secret - the secret used to create the webhook in the Tributech Node UI

Explicit Example:

echo -n '{"TransactionId":null,"StreamId":"15caf997-2f2f-43c2-b5e9-6a3ac00b1edb","MerkleTreeDepth":5,"LastTimestamp":"2024-05-28T06:31:14.851318+00:00","RootHash":[199,51,64,165,193,234,157,113,156,124,186,212,182,137,146,243,6,114,177,215,234,61,38,199,138,227,179,195,27,237,88,198],"Signature":[61,212,2,199,55,23,184,147,251,18,36,229,59,39,152,32,196,18,189,170,34,162,147,255,69,59,56,31,63,221,41,226,20,128,238,106,148,148,192,217,48,16,67,197,217,118,56,232,167,63,229,27,247,105,208,79,185,193,254,26,17,200,186,154,192,117,153,60,81,232,196,251,28,128,151,44,32,2,41,188,252,224,241,46,172,77,247,81,61,247,32,220,166,141,107,150,149,230,206,5,114,182,111,202,245,217,172,90,178,75,143,113,43,225,34,4,127,85,167,116,150,114,35,47,124,66,196,194,58,114,12,73,253,13,68,181,11,151,152,212,171,189,146,5,187,71,111,212,88,228,246,246,14,33,88,114,151,17,71,23,231,152,56,219,108,220,60,226,241,53,77,104,153,98,200,127,77,153,160,138,245,76,204,171,68,52,236,169,8,238,46,18,58,231,196,104,77,34,190,14,85,41,220,39,180,117,22,77,18,20,229,55,25,170,22,151,157,254,9,199,52,205,71,51,67,135,229,143,248,27,45,19,141,72,72,43,215,87,85,243,93,186,53,202,186,96,120,202,188,215,125,80,115,120,143,97],"AgentId":"a324b439-c03b-4e0f-a63e-8067c4423b7b","EventQoS":1}2024-05-28T06:31:37.3121930+00:00' | openssl dgst -sha256 -hmac "foobar"

We can now compare the output SHA2-256(stdin)= 065cf4e993cf1df7399b2df64a147567552eb4bb7dd91acc73840d5b8411b940 of the command with the value of the Webhook Header attribute x-tributech-signature which does have matching hexadecimal values.

C# Code

In the following section we use the previous example values to verify the HMAC SHA256 signatures by using MS C# which can be pasted into Fiddle or Locale Development Environment:

using System;
using System.Linq;
using System.Security.Cryptography;
using System.Globalization;

public class Program
{
public static void Main()
{
Console.WriteLine(HashHMAC("foobar",@"{""TransactionId"":null,""StreamId"":""15caf997-2f2f-43c2-b5e9-6a3ac00b1edb"",""MerkleTreeDepth"":5,""LastTimestamp"":""2024-05-28T06:31:14.851318+00:00"",""RootHash"":[199,51,64,165,193,234,157,113,156,124,186,212,182,137,146,243,6,114,177,215,234,61,38,199,138,227,179,195,27,237,88,198],""Signature"":[61,212,2,199,55,23,184,147,251,18,36,229,59,39,152,32,196,18,189,170,34,162,147,255,69,59,56,31,63,221,41,226,20,128,238,106,148,148,192,217,48,16,67,197,217,118,56,232,167,63,229,27,247,105,208,79,185,193,254,26,17,200,186,154,192,117,153,60,81,232,196,251,28,128,151,44,32,2,41,188,252,224,241,46,172,77,247,81,61,247,32,220,166,141,107,150,149,230,206,5,114,182,111,202,245,217,172,90,178,75,143,113,43,225,34,4,127,85,167,116,150,114,35,47,124,66,196,194,58,114,12,73,253,13,68,181,11,151,152,212,171,189,146,5,187,71,111,212,88,228,246,246,14,33,88,114,151,17,71,23,231,152,56,219,108,220,60,226,241,53,77,104,153,98,200,127,77,153,160,138,245,76,204,171,68,52,236,169,8,238,46,18,58,231,196,104,77,34,190,14,85,41,220,39,180,117,22,77,18,20,229,55,25,170,22,151,157,254,9,199,52,205,71,51,67,135,229,143,248,27,45,19,141,72,72,43,215,87,85,243,93,186,53,202,186,96,120,202,188,215,125,80,115,120,143,97],""AgentId"":""a324b439-c03b-4e0f-a63e-8067c4423b7b"",""EventQoS"":1}", DateTimeOffset.Parse("2024-05-28T06:31:37.3121930+00:00") ));
}

public static string HashHMAC(string secret, string webHookPayloadJson, DateTimeOffset signatureTimestamp) {
var encoding = new System.Text.ASCIIEncoding();
var messageHash = new HMACSHA256(encoding.GetBytes(secret));
var payload = encoding.GetBytes(webHookPayloadJson)
.Concat(encoding.GetBytes(signatureTimestamp.ToString(CultureInfo.InvariantCulture)))
.ToArray();
var signature = messageHash.ComputeHash(payload);
return BitConverter.ToString(signature).Replace("-", "");
}
}
  • secret - The webhook secret defined during the creation
  • webHookPayloadJson - The whole received Json object
  • signature-timestamp - The Header attribute x-tributech-signaturetimestamp value

This code example can be used to output the exact same signature which is present in the header (without the sha256= prefix, i.e. D633514A1CE9688E816F33B2A6A48E08ED6FE621246483B0F219BB3B873C1B5E).