> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymorfa.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Chamadas

> Faça, atenda e encerre chamadas do WhatsApp, altere as configurações de chamadas, fale em chamadas a partir do código do servidor e conecte troncos SIP.

Controle chamadas do WhatsApp a partir do seu servidor com `messaging.voip`.
Para falar e ouvir em uma chamada a partir do código do servidor, use
`CallsClient` de `@polymorfa/sdk/calls`. Para chamadas no navegador, veja o
[guia de chamadas](/pt-br/guides/calls/overview).

| Tarefa | Permissão |
| - | - |
| Verificar uma chamada e ler configurações de chamadas, permissões, troncos SIP e a política de chamadas | `sessions:read` |
| Fazer, atender, recusar e encerrar chamadas; alterar configurações de chamadas, troncos SIP e a política de chamadas | `sessions:manage` |

## Faça uma chamada

```typescript theme={null}
const placed = await messaging.voip.place(
  { session: "<number-id>", to: "+15551234567", participant: "agent-7" },
  { idempotencyKey: "call-order-1042" },
);

console.log(placed.data.data.callId);
```

`session` é o Número que faz a chamada. `participant` indica quem atua na
chamada pelo seu servidor, como `server:agent-7`. O padrão é `default`. Defina
`video: true` para uma chamada de vídeo.

Passe uma chave de idempotência para que o SDK possa tentar novamente a
solicitação sem fazer uma segunda chamada.

## Verifique antes de ligar

```typescript theme={null}
const check = await messaging.voip.check({ session: "<number-id>", to: "+15551234567" });

if (!check.data.data.allowed) {
  console.log("Call would fail:", check.data.data.refusal);
}
```

`check` executa as mesmas verificações que `place` sem fazer a chamada.
`refusal` é `calls_disabled`, `call_recipient_opted_out`,
`call_destination_blocked`, `call_permission_required` ou `call_limit_reached`.
`place` executa as verificações de novo, então uma chamada ainda pode falhar se
algo mudou nesse intervalo.

## Atenda, recuse e encerre chamadas

As chamadas recebidas chegam como webhooks `call.received`. Uma chamada toca
até alguém atender ou recusar. Nada atende automaticamente.

```typescript theme={null}
const accepted = await messaging.voip.accept("<call-id>", {
  exclusive: true,
  participant: "agent-7",
});
console.log(accepted.data.data.answeredBy); // "server:agent-7"

await messaging.voip.reject("<call-id>");
await messaging.voip.end("<call-id>");
```

* `accept` atende uma chamada que está tocando. Aceites posteriores de outros
  participantes entram na chamada, a menos que o primeiro participante tenha
  definido `exclusive: true`. Nesse caso, eles falham com `409 call_claimed`.
* `reject` recusa uma chamada que está tocando. Caso contrário, falha com
  `409 call_not_ringing`.
* `end` encerra a chamada para todos. `leave(callId, { connectionId })` fecha
  uma das suas conexões e mantém a chamada em andamento.
* `addParticipant(callId, { to })` convida outro usuário do WhatsApp.

## Peça permissão para ligar

O WhatsApp exige a permissão de uma pessoa antes que um Número da API oficial
ligue para ela. Leia o estado atual e depois peça a permissão com uma mensagem:

```typescript theme={null}
const permission = await messaging.voip.retrieveCallPermission("<number-id>", "+15551234567");
console.log(permission.data.data.status); // "none", "temporary", "permanent", or "revoked"

if (permission.data.data.status === "none") {
  await messaging.messages.send("<number-id>", {
    conversation: { phoneNumber: "+15551234567" },
    content: { callPermissionRequest: { body: "Can we call you about order 1522?" } },
  });
}
```

O WhatsApp permite um pedido por pessoa a cada 24 horas e dois a cada 7 dias.
Um pedido acima do limite falha com `call_permission_request_limited`. As
mudanças chegam como webhooks `call.permission_changed`. Números com
dispositivos vinculados não usam permissão para ligar.

## Altere as configurações de chamadas de um Número

```typescript theme={null}
const current = await messaging.voip.retrieveCallSettings("<number-id>");

await messaging.voip.updateCallSettings("<number-id>", {
  callsEnabled: true,
  conferenceMode: false,
  expectedRevision: current.data.data.revision,
});
```

Uma atualização altera apenas os campos que você envia.

* `callsEnabled: false` desativa as chamadas do Número. Novas chamadas falham
  com `calls_disabled` e as chamadas recebidas são recusadas. As chamadas em
  andamento continuam.
* `conferenceMode` (padrão `true`) permite que todos os participantes que você
  conectar ouçam uns aos outros. Com `false`, cada um ouve apenas quem ligou
  pelo WhatsApp.
* `inboundRoute: "sip_trunk"` com `sipTrunkId` envia as chamadas recebidas para
  um tronco SIP. `clients` (o padrão) faz tocar seus apps e navegadores.

Um `expectedRevision` desatualizado falha com `409 state_conflict`.

## Fale em uma chamada a partir do código do servidor

`CallsClient` acompanha as chamadas de um Número e entrega o áudio de cada
chamada, por exemplo para executar um agente de voz:

```typescript theme={null}
import { CallsClient } from "@polymorfa/sdk/calls";

const calls = new CallsClient({
  apiKey: process.env.POLYMORFA_KEY!,
  session: "<number-id>",
  participant: "voice-agent",
});

calls.on("incoming", async (call) => {
  await call.answer({ exclusive: true });
  call.audio.on("data", (pcm) => console.log("received", pcm.byteLength, "bytes"));
});

await calls.connect();
```

`call.audio` transporta PCM mono de 16 bits com sinal em
`call.audio.sampleRate`. Escreva o seu próprio áudio com `call.audio.write()`.
O cliente se reconecta depois de uma queda de conexão. Chame `disconnect()`
para parar de acompanhar o Número.

## Conecte um tronco SIP

Um tronco SIP conecta o seu PBX às chamadas de um projeto. Leia o endereço que
você vai configurar no PBX:

```typescript theme={null}
const endpoint = await platform.sipTrunks.endpoint();
if (endpoint.data.status === "hosted") {
  console.log(endpoint.data.host, endpoint.data.transports, endpoint.data.rtp);
}
```

Depois crie o tronco em um cliente de projeto:

```typescript theme={null}
const created = await project.sipTrunks.create({
  name: "Head office PBX",
  direction: "both",
  outbound: { targetUri: "sips:pbx.example.com", transport: "tls" },
  inbound: { session: "<number-id>", allowedAddresses: ["203.0.113.10"] },
});

// Store the inbound password now. The API does not return it again.
console.log(created.data.inboundCredentials);
```

Desative um tronco com `update(trunkId, { enabled: false, expectedRevision })`.
`rotateCredentials(trunkId)` emite uma nova senha de entrada. Um cliente de
equipe passa o ID do projeto como primeiro argumento de `list` e `create`. Veja
[Troncos SIP](/pt-br/guides/calls/sip-trunks).

## Bloqueie países e mantenha uma lista de não ligar

A política de chamadas da equipe bloqueia chamadas para códigos de discagem de
países. Ela precisa de uma chave da equipe:

```typescript theme={null}
const policy = await platform.callPolicy.retrieve();

await platform.callPolicy.update({
  blockedCountryCodes: ["44", "1876"],
  expectedRevision: policy.data.revision,
});
```

`update` substitui a lista inteira. Os códigos têm de 1 a 4 dígitos, sem `+`;
`1876` bloqueia a Jamaica sem bloquear o restante de `+1`. Enquanto houver
algum código bloqueado, chamadas para pessoas cujo número de telefone é
desconhecido também são recusadas.

A lista de não ligar bloqueia chamadas para pessoas específicas:

```typescript theme={null}
const added = await platform.callOptOuts.create({
  phoneNumber: "+14155550123",
  note: "Asked not to be called",
});

for await (const entry of await platform.callOptOuts.list({ limit: 100 })) {
  console.log(entry.id, entry.phoneNumber ?? entry.bsuid);
}

await platform.callOptOuts.delete(added.data.id);
```

Uma chamada para uma pessoa da lista falha com `call_recipient_opted_out`. A
correspondência usa o identificador que você armazenou: uma entrada com número
de telefone não bloqueia uma chamada endereçada por ID de usuário.
`import({ entries })` adiciona até 5.000 entradas de uma vez.

Para histórico e estatísticas de chamadas, veja
[Registros de chamadas](/pt-br/sdks/typescript/call-records).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.