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.
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 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 protocol visit this link.
To subscribe, your endpoint must be able to respond to a challenge performed at subscription time.
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 with the subscription URL being https://example.com
:
https://example.com?hub.mode=subscribe&hub.topic=vehicle:'UUID':generic:position&hub.challenge=thisIsARandomString
Example of your system response:
thisIsARandomString
Topic
To receive signals updates you have to subscribe to a channel.
The topic is the channel identifier.
Special characters, such as wildchar *
, can be used to target more than one element.
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
You have to subscribe to specific signals individually.
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.
Updated 10 months ago