Wialon não tem webhooks: faça polling assim

Siarhei Havarunou – CEO

·

O Wialon não consegue enviar eventos para a sua URL. Três alternativas que funcionam: polling de avl_evts, ações de notificação e uma ponte com flespi.

Wialon has no webhooks — polling avl_evts, notification requests and a flespi bridge

Todo arquiteto de integrações pergunta isso na primeira semana: “qual é a URL de webhook do Wialon para eventos de viagem?”. Essa URL não existe. O Wialon não tem um webhook de eventos de uso geral: nada registra um callback e recebe o fluxo, e nenhuma chamada de API inscreve o seu endpoint em um item ou em um tipo. O que existe é mais restrito e funciona por regra — uma notificação, uma condição, uma requisição HTTP — e é a Opção B abaixo, não um substituto para um fluxo de eventos. Tudo o que segue é uma alternativa ao webhook que você queria, ordenada da mais simples à mais capaz. Escolha pela latência de que precisa, não pela moda.

Por que a ausência é estrutural, e não um descuido

O modelo de eventos do Wialon é ligado a uma sessão, não a um endpoint. Você faz login, diz à sessão quais itens lhe interessam, e o servidor acumula as mudanças dessa sessão até você vir buscá-las. Nada nesse desenho tem lugar para a sua URL: não há um objeto de assinatura durável ao qual associá-la, nem fila de entrega por trás, nem mecanismo de novas tentativas para acioná-la. Um webhook é a promessa de entregar depois; uma sessão é a promessa de lembrar até você perguntar.

Vale entender isso antes de desenhar a arquitetura, porque mostra exatamente o que as alternativas podem e não podem fazer. Tudo o que é construído sobre a sessão herda o tempo de vida da sessão: cinco minutos ociosos e ela acaba. Tudo o que é construído sobre notificações herda o formato da notificação: uma regra, uma condição, disparar e esquecer. O push durável de verdade precisa vir de uma plataforma construída com uma fila de entrega, que é a terceira opção e a única que custa um segundo sistema.

Opção A: polling de avl_evts (segundos de latência, sem configuração)

A sessão que você já mantém aberta pode informar as próprias mudanças. Inscreva-se com core/update_data_flags e depois faça polling do canal avl_evts: no máximo 10 requisições a cada 10 segundos por sessão, em uma sessão que não faça mais nada. avl_evts é um caminho próprio, {host}/avl_evts?sid=<sid>, e não um svc contra ajax.html; w.events() abaixo o encapsula:

w.call("core/update_data_flags", {
    "spec": [{"type": "type", "data": "avl_unit", "flags": 1, "mode": 0}],
})
while True:
    for e in w.events().get("events", []):
        queue.put(e)  # queue, never process inline
    time.sleep(1)

O que ele vê. Novas mensagens do hardware, edições de propriedades feitas na interface ou por outra integração, e exclusões. Cada evento nomeia o item e o tipo de mudança, e a resposta traz o relógio do servidor: use-o em vez do seu, para que uma máquina com o relógio dessincronizado não produza eventos que parecem chegar antes de acontecer.

O que ele não vê. O histórico. O avl_evts parte do momento em que você se inscreveu, então uma reinicialização é uma lacuna, a menos que outra coisa a preencha. Essa outra coisa é uma leitura em lote de messages/load_interval para o intervalo em que o seu processo ficou fora do ar, e o fato de que você precisa dela de qualquer forma é o argumento mais forte para construir primeiro o caminho em lote e depois o de eventos.

Como ele falha. De três maneiras, e vale escrever código para as três antes do primeiro deploy. A sessão morre após cinco minutos ociosos, então um loop que pausa — uma pausa longa do GC, uma fila bloqueada, um deploy — volta com o erro 1, e a resposta é um novo login e uma nova inscrição, não um loop de novas tentativas. A inscrição é substituída, e não mesclada, quando mode é 0, o que é uma vantagem: reinscrever-se após uma reconexão é uma única chamada idempotente em vez de um cálculo de diferenças. E o teto de dez a cada dez segundos é um orçamento inteiro, então essa sessão não pode fazer mais nada: uma extração que a compartilhe começará a receber o erro 10 no pior momento possível.

Quando é a escolha certa. Uma conta, um processo, latência medida em segundos e um operador que tolera uma lacuna após uma reinicialização. Isso cobre a maioria dos dashboards e dos alertas.

Opção B: ações de notificação (minutos de latência, no lado do servidor)

As notificações do Wialon podem fazer mais do que mandar um e-mail para um despachante. Uma ação de notificação pode disparar uma requisição HTTP para uma URL sua quando a condição de gatilho é atendida: entrada em geocerca, excesso de velocidade, valor de sensor, mensagem do motorista. É o mais perto de um webhook que o Wialon tem, e tratá-lo como tal causa quatro problemas específicos.

  1. Funciona por regra, não como fluxo de eventos. Você configura uma notificação por condição por recurso. Dez condições são dez notificações, cada uma mantida na interface ou via resource/update_notification (veja a referência de notificações). Não existe uma regra “mande-me tudo”, e montar uma com quarenta regras estreitas produz uma superfície de configuração que ninguém vai querer manter daqui a um ano.
  2. A entrega não tem garantia documentada. O Wialon não publica uma política de novas tentativas para uma requisição que o seu endpoint recusa, então projete para entrega no máximo uma vez: torne o endpoint idempotente e concilie com a API, de forma agendada, tudo o que você não puder perder.
  3. Os payloads são templates, não schemas. Você formata a requisição com macros em vez de receber um objeto tipado. Versione por conta própria: coloque um marcador de versão no caminho da URL para que, no dia em que o significado de uma macro mudar, você consiga distinguir o tráfego antigo do novo sem adivinhar.
  4. Nada assina a requisição. Não há cabeçalho com segredo compartilhado nem assinatura a verificar, então o seu endpoint precisa autenticar quem chama de outra forma: um componente longo e aleatório no caminho, uma lista de endereços de origem permitidos, ou ambos. Um endpoint sem autenticação que aceita “o veículo 14 entrou no pátio” é um endpoint ao qual qualquer pessoa que descubra a URL pode mentir.

Há ainda uma sutileza de temporização que pega muita gente: uma notificação tem duas camadas de tempo independentes — a condição própria do gatilho e o agendamento que diz quando a regra está ativa — e ambas precisam ser satisfeitas antes que algo dispare. Uma regra que parece correta e nunca dispara costuma ser uma regra cujo agendamento exclui as horas em que a frota de fato circula.

Use quando o volume de eventos é baixo e cada evento importa individualmente: botão de alarme pressionado, geocerca violada, temperatura fora da faixa. Não a use como uma mangueira de dados: centenas de eventos de excesso de velocidade por hora em chamadas HTTP por regra é o jeito de construir um sistema distribuído a partir de um painel de notificações.

Opção C: ponte com flespi (push real, segunda plataforma)

Quando você precisa de push genuíno de servidor para servidor — streams persistentes, roteamento por canais, tradução de protocolos — a resposta não está no Wialon. O flespi aceita os mesmos rastreadores, expõe assinaturas de streaming reais com uma fila de entrega por trás, e convive com o Wialon no mesmo hardware: o dispositivo envia para um canal do flespi, e o flespi retransmite ao Wialon no protocolo do próprio Wialon, de modo que as telas do gestor de frota continuam funcionando enquanto a sua plataforma recebe um fluxo.

Essa é a arquitetura, e o custo dela é uma decisão de fronteiras. Duas plataformas guardando a mesma telemetria vão divergir na primeira vez que uma delas ficar inacessível, então cada classe de dado precisa de exatamente um dono: as mensagens brutas do dispositivo pertencem ao lado de streaming, enquanto unidades, geocercas, motoristas e tudo o que um operador edita pertencem ao Wialon. Escreva essa tabela antes de redirecionar o primeiro dispositivo; o guia de arquitetura dual-stack é o tratamento completo.

Esta é a resposta corporativa e custa uma segunda plataforma: uma assinatura, uma topologia de canais e alguém que entenda os dois lados. Não recorra a ela quando a Opção A resolveria.

Qual escolher, em uma tabela

NecessidadeEscolhaLatência
”Avise-me em segundos, uma conta”A: polling de avl_evtssegundos
”Avise a minha URL sobre alarmes específicos”B: requisição de notificação~minutos
”Envie tudo em stream para a minha plataforma”C: ponte com flespitempo real
”Dê-me o mês passado, completo”Nenhuma das anteriores — sincronização em loteagendada

O erro mais comum é escolher B para a quarta linha: notificações não são um mecanismo de sincronização. O histórico se move em lotes, de forma agendada, com extração segura frente aos limites de taxa para o seu próprio banco de dados. Os eventos dizem que algo aconteceu; o banco de dados diz tudo o que aconteceu. Construa os dois e não confunda nenhum.

A latência que você pode realmente prometer

Antes de escolher, calcule o custo do caminho inteiro, e não só do transporte. Um rastreador reporta no seu próprio intervalo — normalmente dezenas de segundos em movimento e minutos parado, configurável por dispositivo. Tudo o que você construir por cima herda esse piso. Um loop de avl_evts de um segundo sobre hardware que reporta a cada sessenta é um loop de um segundo entregando uma verdade de sessenta segundos atrás, e nenhuma engenharia de plataforma muda isso.

Isso importa tanto comercial quanto tecnicamente. Um “rastreamento em tempo real” vendido diante de uma expectativa de latência de navegador GPS vai falhar no teste de aceitação, não importa qual opção você tenha escolhido. Escreva o intervalo de reporte do dispositivo na especificação ao lado da latência de entrega, e a conversa passa a ser aritmética em vez de decepção.

Três falhas para projetar contra, qualquer que seja a escolha

Duplicatas. Toda opção pode entregar o mesmo evento lógico duas vezes: um lote reenviado, uma reinscrição que reproduz, uma notificação disparada por duas regras sobrepostas. Dê a cada evento uma chave natural (id do item mais timestamp do servidor mais tipo de evento) e torne o consumidor idempotente. São cinco linhas de código no início e um projeto de limpeza de dados depois.

Lacunas. Toda opção pode perder eventos: a sessão morreu, o endpoint estava fora do ar, o canal foi reconfigurado. A única defesa real é uma leitura em lote agendada que se sobreponha ao caminho ao vivo: execute-a sobre uma janela maior que a sua pior queda e deixe a idempotência absorver a sobreposição.

Ordem. Nada aqui promete ordenação entre itens, e uma máquina de estados orientada a eventos que assuma “saída antes da chegada” acabará vendo os dois invertidos. Ordene pelo timestamp do servidor dentro de uma unidade, e nunca suponha nada sobre a relação entre duas unidades.

O que construir, seja qual for a opção

Um job de reconciliação. Uma vez por noite, compare contagens e agregados-chave entre o Wialon e aquilo que você alimentou — mensagens por unidade, viagens por unidade, eventos por regra — e alerte quando a diferença passar de um limite que você escolheu de propósito. Sem ele, uma integração parada é indistinguível de uma semana tranquila, e você descobre no fechamento do mês, não na manhã em que ela quebrou.

Se a escolha acima está virando arquitetura em vez de um script, é disso que trata a prática de integração: desenho de eventos, garantias de entrega e reconciliação, orçados antes de construir qualquer coisa.

Mais da Asset Track

Vamos conversar

  • “Our client needed a data pipeline. It came back working, plus a few Wialon fixes we had not asked for. That client trusts us more now.”
    Faiz K. Customer Manager · Trakpro Limited