Endpoint de interações
O outro caminho de entrega: cada interação vira um POST assinado no seu servidor. Ele substitui o Gateway em vez de somar-se a ele, e é o que serve a quem só responde a comandos.
Por que ele existe
A conexão do Gateway é um processo de pé, e são duas vagas por App. Quem só responde a comando não precisa de fluxo aberto: um endereço HTTP que o Trivo chama quando alguém aciona o seu App resolve o mesmo problema sem manter nada acordado — e sobrevive a reinício, a escala horizontal e a plataforma que dorme sem pedido.
O que não muda é o seu código. O onInteraction é o mesmo nos dois caminhos, e o SDK esconde a diferença de propósito: ela é de transporte, e trocar de caminho não pode ser reescrever o bot.
Ativar: a prova de vida
Salvar o endereço no painel não ativa nada. O portal manda uma sondagem assinada, e o seu handler precisa devolver 2xx com o desafio de volta em até 3 segundos:
// chega
{ "type": "probe", "challenge": "aBcD…" }
// você responde
{ "challenge": "aBcD…" }O eco prova que o seu código rodou e leu o nosso corpo — um servidor que responde 200 a tudo não passa. Ele não prova que você verificou a assinatura: nada que possamos mandar prova isso, porque a verificação acontece na sua máquina e não deixa rastro na resposta. É o interactionResponse.probe do SDK que monta a resposta certa.
O endereço precisa ser https:, na porta 443, sem credencial embutida, e resolver para um endereço público. Fora disso a recusa é ENDPOINT_REJECTED. Quando a sondagem sai e não fecha, a recusa é ENDPOINT_UNREACHABLE, com probe: { code, status, latencyMs } — nunca o corpo que o seu servidor respondeu, para esta rota não virar leitor de endereços que só o Trivo alcança.
Os quatro estados, e o que cada um significa para a entrega
| Estado | Onde a interação chega |
|---|---|
off | Sem endpoint: pelo Gateway. É o padrão. |
probing | Endereço salvo e ainda não provado: continua pelo Gateway. Salvar não ativa nada. |
active | Pelo POST assinado, e só por ele. A exclusão mútua começa aqui, não no salvar. |
suspended | Em lugar nenhum: a interação expira sem entrega, e não cai para o Gateway. |
A moderação da plataforma também pode desligar um endpoint, e nesse caso ele volta a off. E um App sancionado não recebe entrega por caminho nenhum, ativo ou não — Criar e gerenciar um App diz o que cada sanção fecha.
Responder pelo corpo
Você tem 3 segundos para responder 2xx (1 segundo para autocomplete). Não há retentativa: falhou, a interação expira pelo contrato — e não cai para o Gateway. Os dois caminhos nunca são usados para a mesma interação.
Por isso o corpo da sua resposta ao POST é literalmente o mesmo JSON da rota de confirmar: usá-lo economiza uma ida à rede dentro de um prazo de 3 segundos. O interactionResponse do SDK monta os seis — reply, defer, decline, modal, suggest e a resposta da sondagem —, e no autocompletar responder pelo corpo é o que cabe no segundo.
// a sua resposta ao POST do Trivo
{ "type": "reply", "content": "pong" }Um corpo que não case com o esquema não vira erro: você respondeu 2xx, o contador de falhas do endpoint zera, mas a interação continua aberta e expira. Se você não consegue deduplicar entregas, não responda privado pelo corpo — confirme com {"type":"defer"} e mande a resposta pela rota REST.
Referência de transporte
O POST que chega no seu endereço
O que viaja no fio, para transparência, depuração e compatibilidade — não é um segundo jeito de construir App. Se você está escrevendo um App, o SDK já faz isto.
Cada interação chega como um POST no seu endpoint, com o corpo abaixo e cinco cabeçalhos — é o que o InteractionVerifier lê por você:
POST https://o-seu-endereco/trivo
content-type: application/json
x-trivo-app: 1234567890123456789
x-trivo-delivery: 0e5a9c1f-2b3d-4e5f-8a9b-0c1d2e3f4a5b
x-trivo-timestamp: 1756512000
x-trivo-version: 1
x-trivo-signature: ed25519-AbC…=Zm9vYmFy…
{ "type": "interaction", "interaction": { … } }| Cabeçalho | O que é | Assinado |
|---|---|---|
x-trivo-app | O Application ID de destino. | sim |
x-trivo-delivery | O uuid desta entrega. É a sua chave de idempotência. | sim |
x-trivo-timestamp | Segundos unix, em texto. Segundos, e não milissegundos. | sim |
x-trivo-version | A receita do preâmbulo. Hoje, 1. | não (é seletor) |
x-trivo-signature | <key_id>=<base64url>, e duas entradas durante uma rotação. | não (é índice) |
A verificação não é opcional
E não é você que a escreve
Uma entrega que chega no seu endereço só é do Trivo se a assinatura fechar, e errar essa decisão em silêncio é a diferença entre um App e um App que qualquer um aciona. O InteractionVerifier existe para que ela tenha uma implementação só, auditada — e ele cuida do dedupe, da janela de relógio e da rotação de chaves. Assinatura das entregas tem o mecanismo inteiro, e o que a sua configuração precisa declarar.