Receiving signals
Introduction
You have to subscribe to a webhook event to receive signals updates from a vehicle.
Updates will be sent at the endpoint provided at subscription time.
Info
If you don't remember what a signal is, visit the Signals guide's page.
The following diagram explains the process of subscribing, receiving events, and unsubscribing via the webhook endpoint.
To subscribe to the events, the request will consist of the following:
Body parameters table:
Parameter | Type | Description |
---|---|---|
'hub.mode' | subscribe OR unsubscribe | subscribe to subscribe to the channel, unsubscribe in the other case. |
'hub.topic' | string | The topic of interest. |
'hub.callback' | string | You'll receive the challenge and the webhooks at this URL. |
'hub.secret' | string | The secret used to generate the webhook signature. |
e.g.
{
"hub.mode":"subscribe",
"hub.topic":"vehicle:'UUID':generic:position",
"hub.callback":"https//:example.com",
"hub.secret":"A secret of your choice"
}
Warning
The parameter (
hub.mode
) is the actual properties name and not a body point notation.
Info
To better understand this pattern visit this link.
There are multiple events you can subscribe to. Check the following section to understand how they are defined.
Topic
This section explains how the topic is defined.
The structure is the following:
vehicle:$vehicleId:$signalType:$signalName
Parameter | Position | Description |
---|---|---|
vehicle | 1 | Always vehicle string. |
$vehicleId | 2 | The vehicle's id. You can use the wildcard * to subscribe to all the client's vehicles. |
$signalType | 3 | The signal's type: generic or specific . |
$signalName | 4 | The signal's name. You can use the wildcard * to subscribe to all the generic signals. |
e.g. Using vehicle id 26c1097a-45d7-4719-a195-595c252a16f7
and signal position
vehicle:26c1097a-45d7-4719-a195-595c252a16f7:generic:position
Challenge
The endpoint provided at subscription time will be called to check the URL validity.
The request will consist of the following:
You'll substitute https://example.com with your URL.
Headers table:
Header | Value | Description |
---|---|---|
Content-Type | 'application/json' | The body is in JSON format. |
Query parameters table:
Parameter | Type | Description |
---|---|---|
hub.mode | string | Always subscribe . |
hub.topic | string | The topic of interest. |
hub.challenge | string | A random string generated by our system. This value should be returned from your system in a string/text format. |
Example challenge for vehicle:'UUID':generic:position
topic.
Webhook
You receive signals at the endpoint provided at subscription time.
The call will consist of the following:
You'll substitute https://example.com with your URL.
Headers table:
Header | Type | Description |
---|---|---|
X-Idempotency-Key | string | The message identifier. In case of a retry the same ID will be sent. |
X-Hub-Signature | string | The message signature generated from the client provided secret. |
User-Agent | string | 2AA/WebhookPub/SenderHttp : our user agent. |
Content-Type | 'application/json' | The body is in JSON format. |
Body table:
Name | Example | Description |
---|---|---|
topic | vehicle:ebd00051-b465-4ce6-82dd-74fbe9725e95:generic:position | The message identifier. In case of retry it'll be sent the same ID. |
payload | "timestamp": 1610721676241, "data":{"latitude": 3232, "longitude": 5454} | The signal's value. |
User's system has to answer within a predefined timeout (10 seconds), and it has to return Status OK (HTTP 200
).
In case of error, we'll try again two times.
If the user's system fails to answer several times, we'll stop sending messages for a predefined amount of time.
This happens until the user's system can successfully receive messages. After that, the system resumes normal behaviour.
Messages signature calculation
Message's X-Hub-Signature
is generated as follows:
import * as crypto from "crypto";
const generateSignature = (message: string, secret: string, algorithm: string): string => {
if (!secret) {
return "";
}
const hmac = crypto.createHmac(algorithm, secret);
hmac.update(message, "utf8");
return `${algorithm}=${hmac.digest("hex")}`;
}
const signature = generateSignature(body, secret, "sha256");
import hashlib
import hmac
def generate_signature(body: str, secret: str, algorithm) -> str:
if secret is None:
return ""
h = hmac.new(secret.encode('utf-8'), body.encode('utf-8'), algorithm)
return "sha256=" + h.hexdigest()
signature = generate_signature(body, secret, hashlib.sha256)
It uses the HMAC-SHA256
algorithm to create the signature from the JSON body.
The key is the one provided at subscription time.
Info
If you want to test the contents of this guide, please refer to our testing environment.
Do you need some help?
To help you manage to receive signals from our system, we produced some tutorials and cookbooks to help you understand this topic.
Visit:
Updated almost 2 years ago