> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Enviando áudio gerado pelo Twilio

> **Note**
>
> **Guia prático** · Pressupõe que você tenha concluído o [início rápido da ElevenAPI](/docs/pt/eleven-api/quickstart) e tenha uma conta na Twilio.

Neste guia, você aprenderá a enviar uma mensagem gerada por IA em uma chamada telefônica usando a Twilio e a ElevenLabs. Esse processo permite enviar mensagens de voz de alta qualidade diretamente para quem liga para você.

## Crie contas na Twilio e no ngrok

Usaremos a Twilio e o ngrok neste guia, então crie suas contas nessas plataformas.

* [twilio.com](https://www.twilio.com)
* [ngrok.com](https://ngrok.com)

## Crie o servidor com Express

### Inicialize seu projeto

Crie uma nova pasta para o projeto

```
mkdir elevenlabs-twilio
cd elevenlabs-twilio
npm init -y
```

### Instale as dependências

```
npm install @elevenlabs/elevenlabs-js express express-ws twilio
```

### Instale as dependências de desenvolvimento

```
npm i @types/node @types/express @types/express-ws @types/ws dotenv tsx typescript
```

### Crie seus arquivos

```ts
// src/app.ts
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import "dotenv/config";
import express, { Response } from "express";
import ExpressWs from "express-ws";
import { Readable } from "stream";
import VoiceResponse from "twilio/lib/twiml/VoiceResponse";
import { type WebSocket } from "ws";

const app = ExpressWs(express()).app;
const PORT: number = parseInt(process.env.PORT || "5000");

const elevenlabs = new ElevenLabsClient();
const voiceId = "aMSt68OGf4xUZAnLpTU8";
const outputFormat = "ulaw_8000";
const text = "This is a test. You can now hang up. Thank you.";

function startApp() {
  app.post("/call/incoming", (_, res: Response) => {
    const twiml = new VoiceResponse();

    twiml.connect().stream({
      url: `wss://${process.env.SERVER_DOMAIN}/call/connection`,
    });

    res.writeHead(200, { "Content-Type": "text/xml" });
    res.end(twiml.toString());
  });

  app.ws("/call/connection", (ws: WebSocket) => {
    ws.on("message", async (data: string) => {
      const message: {
        event: string;
        start?: { streamSid: string; callSid: string };
      } = JSON.parse(data);

      if (message.event === "start" && message.start) {
        const streamSid = message.start.streamSid;
        const response = await elevenlabs.textToSpeech.convert(voiceId, {
          modelId: "eleven_flash_v2_5",
          outputFormat: outputFormat,
          text,
        });

        const readableStream = Readable.from(response);
        const audioArrayBuffer = await streamToArrayBuffer(readableStream);

        ws.send(
          JSON.stringify({
            streamSid,
            event: "media",
            media: {
              payload: Buffer.from(audioArrayBuffer as any).toString("base64"),
            },
          })
        );
      }
    });

    ws.on("error", console.error);
  });

  app.listen(PORT, () => {
    console.log(`Local: http://localhost:${PORT}`);
    console.log(`Remote: https://${process.env.SERVER_DOMAIN}`);
  });
}

function streamToArrayBuffer(readableStream: Readable) {
  return new Promise((resolve, reject) => {
    const chunks: Buffer[] = [];

    readableStream.on("data", (chunk) => {
      chunks.push(chunk);
    });

    readableStream.on("end", () => {
      resolve(Buffer.concat(chunks).buffer);
    });

    readableStream.on("error", reject);
  });
}

startApp();
```

```env
# .env
SERVER_DOMAIN=
ELEVENLABS_API_KEY=
```

## Entenda o código

### Lide com a chamada recebida

Quando você liga para seu número, a Twilio faz uma solicitação POST ao endpoint `/call/incoming`.
Em seguida, usamos twiml.connect para informar à Twilio que queremos processar a chamada pelo nosso websocket, definindo a URL como nosso endpoint `/call/connection`.

```ts
function startApp() {
  app.post('/call/incoming', (_, res: Response) => {
    const twiml = new VoiceResponse();

    twiml.connect().stream({
      url: `wss://${process.env.SERVER_DOMAIN}/call/connection`,
    });

    res.writeHead(200, { 'Content-Type': 'text/xml' });
    res.end(twiml.toString());
  });
```

### Crie o texto em fala

Aqui, ouvimos as mensagens que a Twilio envia ao nosso endpoint websocket. Quando recebemos um evento de mensagem `start`, geramos áudio usando o [SDK TypeScript](https://github.com/elevenlabs/elevenlabs-js) da ElevenLabs.

```ts
  app.ws('/call/connection', (ws: WebSocket) => {
    ws.on('message', async (data: string) => {
      const message: {
        event: string;
        start?: { streamSid: string; callSid: string };
      } = JSON.parse(data);

      if (message.event === 'start' && message.start) {
        const streamSid = message.start.streamSid;
        const response = await elevenlabs.textToSpeech.convert(voiceId, {
          modelId: 'eleven_flash_v2_5',
          outputFormat: outputFormat,
          text,
        });
```

### Envie a mensagem

Ao receber o áudio da ElevenLabs, nós o convertemos em um array buffer e o enviamos à Twilio pelo websocket.

```ts
const readableStream = Readable.from(response);
const audioArrayBuffer = await streamToArrayBuffer(readableStream);

ws.send(
  JSON.stringify({
    streamSid,
    event: "media",
    media: {
      payload: Buffer.from(audioArrayBuffer as any).toString("base64"),
    },
  })
);
```

## Aponte o ngrok para sua aplicação

A Twilio exige uma URL acessível publicamente. Usaremos o ngrok para encaminhar a porta local da nossa aplicação e expô-la como uma URL pública.

Execute o seguinte comando no terminal:

```
ngrok http 5000
```

Copie o domínio do ngrok (sem https\://) para usar nas variáveis de ambiente.

![](/docs/_fern-img/830a701ecee4b2bd32f44a891806a91e00f27dcf263c5917fa20a91a3353d6a1.webp)

## Atualize suas variáveis de ambiente

Atualize o arquivo `.env` com seu domínio do ngrok e a chave de API da ElevenLabs.

```
# .env
SERVER_DOMAIN=*******.ngrok.app
ELEVENLABS_API_KEY=*************************
```

## Inicie a aplicação

Execute o seguinte comando para iniciar o app:

```
npm run dev
```

## Configure a Twilio

Siga os guias da Twilio para criar um novo número. Depois de criá-lo, acesse a aba "Configure" em Phone Numbers -> Manage -> Active numbers

Na seção "A call comes in", insira a URL completa da sua aplicação (não se esqueça de adicionar o caminho `/call/incoming`):

Ex.: https\://**\*\*\***&#x6E;grok.app/call/incoming

![](/docs/_fern-img/8f57f550bca8ac451980d98482ff5877c4f8fac30035e712cd0375a6527686ff.webp)

## Faça uma chamada telefônica

Ligue para seu número. Você deverá ouvir uma mensagem usando a voz da ElevenLabs.

## Dicas para implantar em produção

Ao executar a aplicação em produção, defina a variável de ambiente `SERVER_DOMAIN` com o domínio do seu servidor. Não se esqueça também de atualizar a URL na Twilio para apontar para seu servidor de produção.

## Conclusão

Agora você deve ter uma compreensão básica de como integrar a Twilio às vozes da ElevenLabs. Se tiver outras dúvidas ou sugestões para melhorar esta publicação, selecione o botão "Suggest edits" ou "Raise issue" abaixo.