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.