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:

POST
https://adapter.2hire.io/api/v1/webhook

Body parameters table:

ParameterTypeDescription
'hub.mode'subscribe OR unsubscribesubscribe to subscribe to the channel, unsubscribe in the other case.
'hub.topic'stringThe topic of interest.
'hub.callback'stringYou'll receive webhooks at this URL.
'hub.secret'stringThe 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:

GET
https://example.com

You'll substitute https://example.com with your URL.


Headers table:

HeaderValueDescription
Content-Type'application/json'The body is in JSON format.

Query parameters table:

ParameterTypeDescription
hub.modestringAlways subscribe.
hub.topicstringThe topic of interest.
hub.challengestringA 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

ParameterPositionDescription
vehicle1Always vehicle string.
$vehicleId2The vehicle's id. You can use the wildcard * to subscribe to all the client's vehicles.
$signalType3The signal's type: generic or specific.
$signalName4The 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:

POST
https://example.com

You'll substitute https://example.com with your URL.


Headers table:

HeaderTypeDescription
X-Idempotency-KeystringThe message identifier. In case of a retry the same ID will be sent.
X-Hub-SignaturestringThe message signature generated from the client provided secret.
User-Agentstring2AA/WebhookPub/SenderHttp : our user agent.
Content-Type'application/json'The body is in JSON format.

Body table:

NameExampleDescription
topicvehicle:ebd00051-b465-4ce6-82dd-74fbe9725e95:generic:positionThe 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.


Did this page help you?