N-Ways
Documentação para programadoresWebhooks

Webhooks

Eventos enviados para o seu servidor à medida que acontecem: um estafeta à porta, uma entrega concluída, um veículo que não se mexe.

Nesta página
Nota:

Os webhooks vêm com o seguimento de frota. Referência dos webhooks

Eventos

EventoQuandodata
task.createdFoi criada uma entregatask
task.assignedA entrega foi atribuída a um veículo (ou outro assumiu-a)task
task.arrivingO estafeta está a menos de arrivingS da tarefa (3 minutos por omissão) ou a menos de 250 m do ponto de entregatask
task.completedMarcada como entreguetask
task.failedMarcada como falhadatask
vehicle.offlineUm veículo não enviou nada durante offlineAfterS (10 minutos por omissão), uma vez por silênciovehicle
task.updatedAlterou a entrega (PATCH /tasks/{id}); changed lista os campostask, changed
task.startedUm motorista N-Ways iniciou a entrega (ligação de motoristas)task
delivery.ratedO cliente avaliou a entrega (1 a 5 estrelas, visível apenas para a sua empresa)task, rating
zone.entered, zone.exitedUm veículo entrou ou saiu de uma das suas zonasvehicle, zone
connection.approved, connection.declinedUm motorista N-Ways aceitou ou recusou o seu conviteconnection ou invite
connection.revoked, connection.endedO motorista deixou de partilhar consigo, ou a sua empresa terminou a ligaçãoconnection
driver.availability_changedUm motorista ligado ativou ou desativou Disponível para siconnection
dispatch.offered, .accepted, .declined, .expired, .withdrawnUm pedido de entrega a um motorista N-Ways, e o que lhe aconteceuoffer, task

Equipas de ERP (SAP, Odoo, Microsoft Dynamics): veja Ligar o seu ERP para a correspondência de campos, a verificação de assinaturas em C#, Groovy e Python, e a reconciliação com a API de exportação.

Os alertas (uma área abandonada, uma zona em que se entrou, um veículo em silêncio ou parado) chegam também como eventos asset.*, e podem seguir por e-mail, notificação, Google Sheets, Telegram ou Excel: veja Alertas e reencaminhamento.

Adicionar um ponto de receção

Indique um endereço HTTPS no seu servidor e os eventos que pretende receber (nenhum na lista significa todos). A resposta contém o secret de assinatura do ponto de receção: só é mostrado agora, por isso guarde-o.

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

POST /webhooks/{id}/test envia um evento ping para verificar que funciona; GET /webhooks/{id}/deliveries mostra o que foi enviado, as respostas do seu servidor e a próxima nova tentativa.

O que chega, e como verificar que vem de nós

Cada evento é um POST com um corpo JSON (id, type, createdAt, data) e estes cabeçalhos:

CabeçalhoValor
X-NWays-EventO tipo de evento
X-NWays-DeliveryO identificador deste envio (dlv_…), o mesmo em cada nova tentativa
X-NWays-Signaturet=<unix seconds>,v1=<hex>, em que v1 é o HMAC-SHA256 de "<t>.<raw body>" com o segredo do seu ponto de receção

Verifique a assinatura sobre o corpo em bruto, antes de o analisar, e recuse uma marca temporal com mais de 5 minutos de diferença:

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(`Encomenda ${event.data.task.id}: o estafeta está a chegar`)
    res.writeHead(204).end() // responda depressa; faça o trabalho demorado depois
  })
}).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", ""))

Novas tentativas e ordem

  • Responda com qualquer código 2xx em menos de 10 segundos. Qualquer outra resposta leva a nova tentativa após 30 segundos, 2 minutos, 10 minutos, 30 minutos, 1, 3, 6 e 12 horas, e depois o envio é marcado como falhado.
  • Um evento pode chegar mais de uma vez ou fora de ordem: guarde os id dos eventos já tratados, e confie no status da tarefa em vez da ordem de chegada dos eventos.
  • Os redirecionamentos não são seguidos, e o endereço tem de ser público.
  • Um segredo foi divulgado? POST /webhooks/{id}/rotate-secret dá um novo de imediato.