Português · English

Webhooks

Com a permissão webhooks:manage, /v1/webhooks gerencia os webhooks da conta (os mesmos de Configurações → Integrações → Webhooks).

curl -X POST "https://atende.suporteja.com.br/v1/webhooks" -H "Authorization: Bearer $ATENDLLY_API_KEY" -H "Content-Type: application/json" \
  -d '{"url": "https://erp.exemplo.com.br/atendlly", "subscriptions": ["contact_created", "contact_updated", "conversation_status_changed"]}'

A resposta da criação traz o secret de assinatura uma única vez.

Eventos: conversation_created, conversation_status_changed, conversation_updated, contact_created, contact_updated, message_created, message_updated, webwidget_triggered, inbox_created, inbox_updated, conversation_typing_on, conversation_typing_off. Com o Helpdesk: ticket_created, ticket_updated, ticket_status_changed, ticket_sla_warning, ticket_sla_breached, ticket_csat_received. inbox_id (opcional) limita o webhook a uma caixa de entrada.

Verificando a assinatura

Cada entrega traz três cabeçalhos: X-Atendlly-Timestamp, X-Atendlly-Delivery (id único da entrega) e X-Atendlly-Signature. Os nomes de cabeçalho não diferenciam maiúsculas de minúsculas. A assinatura é sha256= + HMAC-SHA256(secret, ".").

import hmac, hashlib

def cabecalho(headers: dict, nome: str) -> str:
    return next(v for k, v in headers.items() if k.lower() == nome.lower())

def valido(secret: str, headers: dict, corpo: bytes) -> bool:
    timestamp = cabecalho(headers, "X-Atendlly-Timestamp")
    esperado = "sha256=" + hmac.new(secret.encode(), timestamp.encode() + b"." + corpo, hashlib.sha256).hexdigest()
    return hmac.compare_digest(esperado, cabecalho(headers, "X-Atendlly-Signature"))

Rejeite entregas com timestamp de mais de 5 minutos e ignore um X-Atendlly-Delivery repetido. Os payloads usam o formato de eventos atual (não os formatos da API v1) e não são mascarados.