Automação
Webhooks
Receba uma chamada no seu servidor quando uma tarefa termina ou um celular precisa de atenção.
Adicionar um webhook
No painel: Configurações → Conexões → Eventos → Webhooks. Ou pela API:
POST /v1/webhooks
{"url": "https://example.com/clousd", "events": ["run.completed", "run.failed"], "description": "orders bot"}
# → 201 {"webhook": {"id": "wh_3c1a", …}, "secret": "whsec_…"} the secret is shown onceevents vazio significa todos. Uma chave pode ter até dez webhooks; cada um tem o próprio segredo. POST /v1/webhooks/{id}/rotate gera um segredo novo, /toggle pausa as entregas, /test envia um evento de teste agora e GET …/deliveries lista as entregas recentes com o código de resposta e o tempo.
Eventos
| Evento | Quando |
|---|---|
| run.completed | Uma tarefa terminou; o corpo traz a execução com a resposta. |
| run.failed | Uma tarefa não pôde ser concluída; o corpo diz por quê. |
| run.cancelled | Uma tarefa foi interrompida. |
| run.waiting | Uma tarefa parou para fazer uma pergunta ou pedir permissão. |
| device.problem | A verificação de saúde de um celular falhou. |
| device.resolved | O problema foi resolvido. |
Verificar a assinatura
Cada entrega é um POST com corpo JSON e o cabeçalho X-Clousd-Signature: t=<unix time>,v1=<hex>, em que o hex é o HMAC-SHA256 de "<t>.<raw body>" com o segredo do seu webhook como chave. Rejeite carimbos de tempo antigos para barrar repetições.
import hashlib, hmac, time
def valid(body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t, sig = parts.get("t", ""), parts.get("v1", "")
if not t.isdigit() or abs(time.time() - int(t)) > tolerance:
return False
mac = hmac.new(secret.encode(), t.encode() + b"." + body, hashlib.sha256).hexdigest()
return hmac.compare_digest(mac, sig)Novas tentativas
Cada evento é tentado até quatro vezes: na hora, depois de 30 segundos, depois de 5 minutos e depois de 30 minutos. Responda com qualquer 2xx para confirmar. O corpo é {"id", "type", "created", "data"} e o mesmo id vem em X-Clousd-Event-Id: se uma nova tentativa chegar depois de um sucesso lento, ignore o id que você já tratou. Depois de 20 entregas com falha seguidas, o webhook se pausa sozinho; reative-o no painel ou com /toggle.