Pular para o conteúdo principal

O que é

O CHANNEL_DISCONNECTED é um evento de conta do Omni Z-API: chega ao webhook global do workspace (o webhook de template, sem instância) e avisa que um canal do workspace foi desconectado, com o motivo em código. Com ele, quem integra vários canais não precisa assinar o DISCONNECTED canal por canal para saber de uma queda.
O DISCONNECTED do webhook de canal não muda. O corpo, as regras e os formatos (DEFAULT, Z_API e CHATWOOT) continuam os mesmos, e ele não traz o código do motivo. Quem já assina DISCONNECTED no canal continua recebendo como hoje. O CHANNEL_DISCONNECTED é um aviso a mais, só no webhook global.

Como assinar

Inclua CHANNEL_DISCONNECTED em events ao criar ou atualizar o webhook global:
  • Só no webhook global. O webhook de canal e o padrão de instância recusam o evento com 422.
  • Só no formato DEFAULT. O webhook global já é DEFAULT.
  • Não depende de outros eventos. O mesmo webhook pode assinar só CHANNEL_DISCONNECTED, ou junto com os eventos de template e de cobrança.
  • No painel, assinar o evento exige a permissão Ver a cobrança, a mesma dos eventos de cobrança (Owner e Manager, veja Time e papéis).

O que o seu servidor recebe

O corpo é o evento:
O corpo nunca traz telefone, id do número ou da conta no provedor, token nem credencial. O reason vai como o provedor escreveu e pode conter o número do canal (por exemplo, Disconnected from <número> no Z-API): é o mesmo texto que o painel e o DISCONNECTED do canal já mostram.

Origem

O aviso sai para as três origens. Com origin USER ou BILLING, o reasonCode vem sempre null.

Códigos do motivo

reasonCode pode vir null. Isso acontece quando o motivo não tem código, por exemplo numa queda de sessão do WhatsApp Web, e sempre que origin é USER ou BILLING. Nesses casos, use origin e, se precisar, o texto de reason.
Novos códigos podem surgir. A lista pode crescer sem aviso prévio. Trate um código que você não conhece como um motivo genérico de desconexão, sem quebrar a sua integração.

Um aviso por desconexão

  • Uma vez por queda. Repetições da mesma desconexão (reentregas do provedor, callbacks repetidos) não geram outro aviso. O próximo aviso sai quando o canal reconectar e cair de novo, com outro id.
  • O código do primeiro evento. Se um evento posterior da mesma queda trouxer outro motivo, o painel passa a mostrar o novo, mas o webhook global não recebe outro aviso.

Um aviso por canal

Uma conta do WhatsApp Business (WABA) pode ter vários canais. Quando a Meta desconecta a conta inteira (por exemplo, com PARTNER_REMOVED), sai um aviso para cada canal, cada um com o próprio instanceId, no webhook global do workspace dono de cada canal. Isso é diferente do aviso de restrição da conta (ACCOUNT_RESTRICTION), que sai uma vez por WABA, com a lista de canais atingidos. A diferença é proposital: a desconexão é o estado de cada canal, e a restrição é um estado da conta, que não desconecta os canais.

Junto com os eventos de cobrança

Quando o canal é desconectado pela cobrança, o webhook global recebe o CHANNEL_DISCONNECTED com origin BILLING e o evento de cobrança do caminho: Não há ordem garantida entre o evento de cobrança e o CHANNEL_DISCONNECTED. Cada evento chega só a quem o assinou.

Boas práticas

  • A ordem não é garantida. Ordene pelo disconnectedAt e descarte repetição pelo id.
  • Automatize pelo reasonCode, nunca pelo texto de reason.
  • Trate reasonCode null e códigos desconhecidos.

Limitações

  • O código do motivo aparece só neste aviso. A leitura do canal pela API (GET /v1/channels/{id}) não o traz.
  • Não há aviso retroativo. Um canal que já estava desconectado quando o aviso entrou no ar só gera aviso na próxima queda, depois de reconectar.
  • Algumas desconexões não passam pelo fluxo de eventos do provedor e não geram aviso: por exemplo, a desconexão do WhatsApp Web confirmada pelo provedor sem evento de retorno, e o corte por cobrança de um canal do WhatsApp Web sem assinatura ativa.