Pular para o conteúdo

Meta

Uma fonte com o provedor meta recebe tudo o que o seu App da Meta assinar: WhatsApp, Instagram, Messenger, Lead Ads e os demais produtos. É um provedor só porque quem assina os webhooks é o App, com a mesma App Secret, venha a notificação de onde vier.

O App é seu. O Notyfacil não pede login na Meta nem guarda token de acesso: a fonte é a porta de entrada que você cadastra no App, como faria com um servidor próprio.

  1. Crie uma fonte, escolha Meta como provedor e salve. A URL de ingestão e o Verify token aparecem lado a lado no painel da fonte, e também em url e verifyToken na API.

  2. No Meta for Developers, abra o App e copie a App Secret em Configurações do app, Básico. Cole na fonte, no campo App Secret, ou mande por PUT /v1/ingest/sources/{id}/secret.

  3. Cadastre a callback. Em Webhooks, escolha o objeto (Página, Instagram, Usuário, Permissões) e informe a URL de ingestão como URL de callback e o Verify token no campo Verify token. No WhatsApp, o mesmo cadastro fica em WhatsApp, Configuração.

  4. Clique em verificar e salvar. A Meta chama a URL de ingestão com GET, a fonte confere o Verify token e devolve o desafio. O painel passa a mostrar quando a Meta confirmou a URL.

  5. Assine os campos, e não pule este passo: confirmar a URL não faz a Meta entregar nada. Ela manda só o que estiver assinado, como messages no WhatsApp ou leadgen numa Página. No WhatsApp, a assinatura fica na conta (WABA), em WhatsApp, Configuração, na lista de campos do webhook, e não no cadastro da callback.

A Meta agrupa as notificações: um POST pode trazer várias entradas em entry, e cada entrada várias mudanças em changes ou messaging. A fonte repassa o lote inteiro, byte a byte, como chegou. O seu destino precisa percorrer os itens, e não tratar o corpo como uma notificação só.

Todos os corpos têm o mesmo envelope:

{
"object": "whatsapp_business_account",
"entry": [
{ "id": "102290129340398", "changes": [ { "field": "messages", "value": { } } ] }
]
}

object diz de qual produto veio o lote, e é por ele que o seu código decide o que fazer.

Sobre repetição: a Meta não identifica as entregas. Quando ela reenvia um lote que não recebeu 200 a tempo, com os mesmos bytes, a fonte reconhece a repetição e não repassa de novo. Mesmo assim, deduplique pelos ids dos itens, como o id da mensagem do WhatsApp: a Meta não garante que o reenvio repete o lote exatamente igual. Veja deduplicação e ordem.

Os exemplos abaixo usam dados fictícios.

A callback do WhatsApp fica em WhatsApp, Configuração, no App. Além dela, a Meta aceita uma callback alternativa por conta do WhatsApp Business (WABA) e por número de telefone, configurada pela Graph API. É útil para mandar um número de teste para uma fonte de desenvolvimento e o de produção para outra.

O WhatsApp retenta por até 7 dias o que não recebeu 200. O mesmo campo messages traz as mensagens recebidas e as atualizações de status das que você enviou.

{
"object": "whatsapp_business_account",
"entry": [
{
"id": "102290129340398",
"changes": [
{
"field": "messages",
"value": {
"messaging_product": "whatsapp",
"metadata": { "display_phone_number": "5511900000000", "phone_number_id": "106540352242922" },
"contacts": [ { "profile": { "name": "Cliente Exemplo" }, "wa_id": "5511911111111" } ],
"messages": [
{
"from": "5511911111111",
"id": "wamid.HBgNNTUxMTkxMTExMTExMRUCABIYFjNFQjA1",
"timestamp": "1757955600",
"type": "text",
"text": { "body": "Quero saber do meu pedido" }
}
],
"statuses": [
{
"id": "wamid.HBgNNTUxMTkxMTExMTExMRUCABEYEjk5",
"status": "delivered",
"timestamp": "1757955601",
"recipient_id": "5511911111111"
}
]
}
}
]
}
]
}

O Instagram exige uma conta profissional ligada a uma Página do Facebook, e o App precisa ter acesso a essa conta. A callback é a do objeto Instagram, em Webhooks. As mensagens diretas chegam no campo messages, dentro de messaging.

{
"object": "instagram",
"entry": [
{
"id": "17841400000000000",
"time": 1757955600000,
"messaging": [
{
"sender": { "id": "1234567890123456" },
"recipient": { "id": "17841400000000000" },
"timestamp": 1757955600000,
"message": { "mid": "aWdfZAG1faXRlbToxOklHTWVzc2FnZUlE", "text": "Vocês entregam no sábado?" }
}
]
}
]
}

O Messenger entrega pelas Páginas conectadas ao App, com o objeto page. As mensagens chegam em messaging, uma por item.

{
"object": "page",
"entry": [
{
"id": "108000000000000",
"time": 1757955600000,
"messaging": [
{
"sender": { "id": "6500000000000000" },
"recipient": { "id": "108000000000000" },
"timestamp": 1757955600000,
"message": { "mid": "m_AG5Hz2Uq7tuwNEhXfYYKj8mJEM", "text": "Oi, preciso de ajuda" }
}
]
}
]
}

Os leads chegam pelo campo leadgen do objeto page, e o App precisa da permissão leads_retrieval na Página. Para disparar um lead sem anúncio no ar, use a ferramenta de teste de Lead Ads da Meta.

O webhook avisa que o lead existe, mas não traz as respostas do formulário: com o leadgen_id, o seu sistema busca o lead na Graph API.

{
"object": "page",
"entry": [
{
"id": "108000000000000",
"time": 1757955600,
"changes": [
{
"field": "leadgen",
"value": {
"leadgen_id": "900000000000000",
"page_id": "108000000000000",
"form_id": "700000000000000",
"ad_id": "120200000000000000",
"created_time": 1757955600
}
}
]
}
]
}

Páginas (publicações e comentários), Anúncios, Threads e as notificações de usuário e de permissão chegam pelo mesmo caminho: assinados pela mesma App Secret e repassados do mesmo jeito. Não têm guia próprio aqui; o formato de cada um está na documentação da Meta.

  • A URL foi confirmada e nada chega, nem na aba Mensagens nem na aba Recusadas. As duas abas vazias querem dizer que a Meta não entregou: uma entrega recusada apareceria nas Recusadas. Quase sempre são os campos não assinados (veja o passo 5), e no App, em Webhooks, dá para ver as entregas recentes de cada campo, com a resposta de cada uma.
  • A Meta desiste rápido. Uma hora de falhas seguidas e ela cancela a inscrição do App na Página ou na conta do Instagram, e você precisa assinar os campos de novo. Por isso a fonte responde 200 a tudo que aceita, inclusive com a fonte pausada ou a quota esgotada.
  • A assinatura não confere. Quase sempre é a App Secret de outro App, ou um token de acesso colado no lugar dela. A fonte responde 401, e na primeira recusa o Notyfacil manda um e-mail para os destinatários de alerta da fonte, para dar tempo de corrigir antes do corte.
  • Lote grande. A fonte aceita corpos de até 3 MB, o tamanho máximo que a Meta declara.