N-Ways
Documentation développeursWebhooks

Webhooks

Des événements envoyés à votre serveur dès qu’ils arrivent : un livreur devant la porte, une livraison faite, un véhicule qui ne bouge plus.

Sur cette page
Remarque :

Les webhooks sont fournis avec le suivi de flotte. Référence des webhooks

Événements

ÉvénementQuanddata
task.createdUne livraison a été crééetask
task.assignedLa livraison a été confiée à un véhicule (ou un autre l’a reprise)task
task.arrivingLe livreur est à moins de arrivingS de la tâche (3 minutes par défaut) ou à moins de 250 m du point de livraisontask
task.completedMarquée comme livréetask
task.failedMarquée comme échouéetask
vehicle.offlineUn véhicule n’a rien envoyé pendant offlineAfterS (10 minutes par défaut), une fois par silencevehicle
task.updatedVous avez modifié la livraison (PATCH /tasks/{id}) ; changed liste les champstask, changed
task.startedUn chauffeur N-Ways a commencé la livraison (connexion de chauffeurs)task
delivery.ratedLe client a noté la livraison (1 à 5 étoiles, visible seulement par votre entreprise)task, rating
zone.entered, zone.exitedUn véhicule est entré dans l’une de vos zones ou en est sortivehicle, zone
connection.approved, connection.declinedUn chauffeur N-Ways a accepté ou refusé votre invitationconnection ou invite
connection.revoked, connection.endedLe chauffeur a arrêté le partage, ou votre entreprise a mis fin à la connexionconnection
driver.availability_changedUn chauffeur connecté s’est mis disponible pour vous, ou ne l’est plusconnection
dispatch.offered, .accepted, .declined, .expired, .withdrawnUne demande de livraison à un chauffeur N-Ways, et ce qu’elle est devenueoffer, task

Équipes ERP (SAP, Odoo, Microsoft Dynamics) : voyez Connecter votre ERP pour la correspondance des champs, la vérification des signatures en C#, Groovy et Python, et le rapprochement avec l’API d’export.

Les alertes (zone quittée, zone franchie, véhicule silencieux ou arrêté) arrivent aussi en événements asset.*, et peuvent partir par e-mail, notification, Google Sheets, Telegram ou Excel : voir Alertes et transmission.

Ajouter un point de réception

Indiquez une adresse HTTPS sur votre serveur, et les événements qu’elle veut recevoir (aucun dans la liste veut dire tous). La réponse contient le secret de signature du point de réception : il n’est affiché que cette fois, alors conservez-le.

cURL
curl -X POST "https://nways.ng/maps/v1/fleet/webhooks" \
  -H "X-NWays-Api-Key: VOTRE_CLE_SERVEUR" -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/nways/events", "events": ["task.arriving", "task.completed", "task.failed"]}'

POST /webhooks/{id}/test envoie un événement ping pour vérifier que tout marche ; GET /webhooks/{id}/deliveries montre ce qui a été envoyé, les réponses de votre serveur et la prochaine nouvelle tentative.

Ce qui arrive, et vérifier que ça vient de nous

Chaque événement est un POST avec un corps JSON (id, type, createdAt, data) et ces en-têtes :

En-têteValeur
X-NWays-EventLe type d’événement
X-NWays-DeliveryL’identifiant de cet envoi (dlv_…), le même à chaque nouvelle tentative
X-NWays-Signaturet=<unix seconds>,v1=<hex>, où v1 est le HMAC-SHA256 de "<t>.<raw body>" avec le secret de votre point de réception

Vérifiez la signature sur le corps brut, avant de l’analyser, et refusez un horodatage décalé de plus de 5 minutes :

Node.js
import { createHmac, timingSafeEqual } from 'node:crypto'
import { createServer } from 'node:http'

const SECRET = process.env.NWAYS_WEBHOOK_SECRET

function verified(raw, header) {
  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')))
  if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false
  const want = createHmac('sha256', SECRET).update(`${parts.t}.${raw}`).digest('hex')
  return want.length === parts.v1?.length && timingSafeEqual(Buffer.from(want), Buffer.from(parts.v1))
}

createServer((req, res) => {
  let raw = ''
  req.on('data', (c) => (raw += c))
  req.on('end', () => {
    if (!verified(raw, req.headers['x-nways-signature'] ?? '')) return res.writeHead(401).end()
    const event = JSON.parse(raw)
    if (event.type === 'task.arriving') console.log(`Commande ${event.data.task.id} : le livreur arrive`)
    res.writeHead(204).end() // répondez vite ; faites le travail lent ensuite
  })
}).listen(8080)
Python
import hashlib
import hmac
import os
import time

SECRET = os.environ["NWAYS_WEBHOOK_SECRET"].encode()


def verified(raw: bytes, header: str) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(",") if "=" in p)
    if abs(time.time() - int(parts.get("t", 0))) > 300:
        return False
    want = hmac.new(SECRET, parts["t"].encode() + b"." + raw, hashlib.sha256).hexdigest()
    return hmac.compare_digest(want, parts.get("v1", ""))

Nouvelles tentatives et ordre

  • Répondez par n’importe quel code 2xx en moins de 10 secondes. Toute autre réponse donne lieu à une nouvelle tentative après 30 secondes, 2 minutes, 10 minutes, 30 minutes, 1, 3, 6 et 12 heures, puis l’envoi est marqué comme échoué.
  • Un événement peut arriver plusieurs fois ou dans le désordre : gardez les id des événements déjà traités, et fiez-vous au status de la tâche plutôt qu’à l’ordre d’arrivée des événements.
  • Les redirections ne sont pas suivies, et l’adresse doit être publique.
  • Un secret a fuité ? POST /webhooks/{id}/rotate-secret en donne un nouveau immédiatement.