---
title: "Use dados do aplicativo em uma sequência de voz"
description: "Solicite dados tipados a um receptor HTTPS durante uma chamada, ramifique com base neles em uma etapa posterior, trate falhas técnicas de forma explícita e mantenha respostas privadas separadas dos dados de chamada retidos."
canonical: "https://bird.com/pt-br/documentacao/guides/voice/sequences/code/webhooks"
---

# Use dados do aplicativo em uma sequência de voz

Use `voice.webhook` quando seu aplicativo tiver dados de que a chamada precisa: o status de um pedido, uma equipe ou a confirmação de um agendamento. A etapa retorna esses dados em `success`, e uma etapa Branch posterior escolhe o caminho com base neles.

## Defina a resposta

Defina `config.output_schema` como um schema de objeto para os dados retornados. A etapa tem duas saídas: `success` transporta dados nesse schema e `failure` trata problemas técnicos. Se a configuração for omitida, a saída é um objeto vazio.

A entrada contém um HTTPS `url` estático e um `data` de objeto opcional. Os dados aceitam um objeto literal, `$literal` ou um `$expr` de objeto inteiro. URLs dinâmicas, cabeçalhos definidos por você e credenciais não são aceitos.

## Verifique as solicitações

O Bird assina cada solicitação, inclusive as continuações, com o segredo de callback do seu espaço de trabalho, usando cabeçalhos [Standard Webhooks](https://www.standardwebhooks.com/): `webhook-id`, `webhook-timestamp` e `webhook-signature`. A assinatura cobre o ID, o timestamp e o corpo exato. Nas 24 horas seguintes à troca de um segredo, `webhook-signature` traz uma entrada `v1,` para cada segredo ativo, então qualquer um dos dois segredos passa na verificação. As chamadas podem levar cerca de um minuto para começar a assinar com o novo segredo, então continue aceitando o anterior até o fim desse período de sobreposição. Sua resposta não é assinada: o Bird valida o certificado TLS do seu receptor, e a conexão HTTPS autentica o que ele retorna.

Verifique os cabeçalhos sobre o corpo bruto com a chamada verify de uma biblioteca Standard Webhooks antes de fazer o parsing. O `webhooks.unwrap` dos SDKs faz o parsing de eventos da plataforma e não serve para essas solicitações. Primeiro, gere um novo segredo em **Webhooks → Direct callbacks**, porque o segredo inicial nunca é exibido. A assinatura mostra que alguém que possui o segredo do seu espaço de trabalho assinou a solicitação. Seus receptores de callback SMS têm o mesmo segredo e também podem assinar, então mantenha-o apenas em receptores de sua confiança. Qualquer pessoa que possa editar as sequências do espaço de trabalho escolhe a URL e `data`. Confira se `target_url` é a sua própria URL para recusar uma solicitação que o Bird assinou para outro receptor, e autorize as ações de negócio no seu receptor. A autorização do cliente nunca é repassada.

As solicitações de webhook da sequência não apresentam certificado de cliente, mesmo quando seu espaço de trabalho exige mTLS. Configure o receptor para aceitar conexões sem certificado de cliente e, em vez disso, autentique a solicitação assinada.

Compare o `webhook-timestamp` assinado, um timestamp Unix em segundos, com um relógio de servidor sincronizado. Rejeite solicitações com mais de cinco minutos no passado ou no futuro. Elimine duplicatas por `webhook-id` antes de executar efeitos colaterais. Sempre que possível, armazene o ID e o resultado de forma atômica junto com a ação, e retorne o resultado salvo quando a solicitação se repetir. Cada continuação tem seu próprio ID. Use uma chave de idempotência de negócio separada se solicitações distintas não puderem repetir a mesma ação.

## Retorne dados

O receptor retorna esta estrutura de resposta fechada:

```json
{
  "schema_version": 1,
  "type": "outcome",
  "output": { "status": "confirmed", "message": "Your appointment is confirmed." }
}
```

`output` precisa corresponder ao schema configurado. A resposta retorna dados, não uma porta, um ID de nó ou novos comandos. Uma continuação é `{"schema_version":1,"type":"continue","url":"https://example.com/voice/next"}` na origem canônica da URL original.

Para rotear com base nos dados, conecte `success` a uma etapa `logic.branch` com casos como `steps.decision.output.status == 'confirmed'`. Declare o campo como uma string `enum` no schema para que o receptor só possa retornar esses valores.

A solicitação contém a identidade da execução, da sessão e da chamada, a identidade da sequência admitida e do nó, seu `data` materializado e `results`. Mantenha a entrada de negócio em `data`. Um resultado privado direto de Gather pode aparecer uma única vez em `results`, e gravações concluídas trazem um ID quando disponível. Essas observações não se tornam campos de expressão automaticamente.

## Ler a solicitação recebida pelo receptor

Uma execução de teste de rascunho envia este formato. Os IDs e timestamps abaixo são fictícios; a solicitação real usa a execução admitida e a ocorrência atual do nó:

```json
{
  "schema_version": 1,
  "method": "POST",
  "target_url": "https://example.com/decision",
  "run_id": "vsr_01k5yb7p000000000000000000",
  "sequence": {
    "id": "vsq_01k5yb7p000000000000000000",
    "version_id": null,
    "draft_revision": 1,
    "entry_node_id": "start",
    "mode": "test"
  },
  "session_id": "vcs_01k5yb7p000000000000000000",
  "call": { "id": "vcl_01k5yb7p000000000000000000", "orig": null, "dest": null },
  "node": { "id": "decision", "occurrence_id": "00000000-0000-4000-8000-000000000001" },
  "data": { "appointment_id": "appointment_123" },
  "results": []
}
```

Em uma execução publicada, `version_id` identifica a versão selecionada e `draft_revision` é nulo. Em uma chamada que executou uma [definição inline](/docs/guides/voice/create-calls), `id`, `version_id` e `draft_revision` são todos nulos. `mode` pode ser `test` ou `production`. Origem e destino usam objetos de participante da chamada anuláveis. Verifique a assinatura antes de confiar nesses campos de identidade.

Uma observação de Gather em `results` tem `type: "gather"`, `node_id`, o UUID `command_id`, `digits` e `reason`. Uma observação de gravação tem `type: "recording"`, o UUID `command_id`, `state` e um `recording_id` quando disponível. Use os dígitos privados apenas na solicitação a que se destinam; eles não se tornam saídas de expressão retidas. As solicitações de continuação mantêm a mesma ocorrência do nó, e as observações já entregues são removidas de `results`.

## Tratar falhas

Uma amostra técnica usa a porta `failure` com `{"code":"webhook_unavailable"}` ou `{"code":"webhook_invalid_response"}`. Uma falha conectada segue o caminho de recuperação; uma falha não conectada faz a execução falhar. Um `success` não conectado encerra a execução normalmente. As solicitações de webhook reais têm um prazo de três segundos e não são tentadas novamente de forma automática. O Preview não faz nenhuma solicitação.

O prazo de três segundos inclui a leitura do segredo de assinatura. Conecte `failure` a um caminho de recuperação para que a chamada possa continuar quando o receptor estiver indisponível ou retornar uma resposta inválida. Uma solicitação que excedeu o tempo limite pode já ter causado um efeito colateral no receptor.

Trate `data`, a identidade da chamada e os dígitos do Gather como privados. Restrinja o acesso ao receptor e ao segredo, evite registrar corpos ou segredos em logs e retenha a entrada do chamador apenas pelo tempo que sua aplicação precisar. Não coloque dados privados nem credenciais em URLs, porque o rastreamento da chamada retém a URL completa, incluindo a query. A URL e os dados configurados e a saída validada ficam retidos no histórico de execução; os dígitos transitórios do Gather são excluídos da entrada capturada da etapa. Retorne apenas os dados de que a sequência precisa.

Leia os dados retornados em `steps.decision.output` e os erros técnicos em `steps.decision.error.code`. Se os dois caminhos se encontrarem, proteja o wrapper com `has(steps.decision.output)` ou `has(steps.decision.error)` antes de usá-lo. Um 200 HTTP do seu receptor só indica um resultado válido depois que o corpo passa pelo contrato.

## Related resources

- [Voice sequences](/docs/guides/voice/sequence-builder) (docs)
