> 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.

# 注册 Twilio 通话

> **高级**
>
> 本指南介绍一种高级集成模式，适用于需要完全控制 Twilio 基础设施的开发者。如需更简单的设置，建议使用会自动处理配置的 [原生 Twilio 集成](/docs/zh/eleven-agents/phone-numbers/twilio-integration/native-integration)。

## 何时使用各方案

开始前，请了解原生集成和注册通话方案之间的权衡：

| 功能            | 原生集成          | 注册通话      |
| ------------- | ------------- | --------- |
| 设置难度          | 更简单           | 更复杂       |
| 通话转接          | 支持            | 不支持       |
| 自定义 Twilio 逻辑 | 有限            | 完全控制      |
| 电话号码管理        | 通过 ElevenLabs | 通过 Twilio |

## 概述

注册通话端点允许你在使用 ElevenLabs 智能体进行对话的同时，继续使用自己的 Twilio 基础设施。你无需将 Twilio 号码导入 ElevenLabs，而是可以完全控制 Twilio 设置，并使用 ElevenLabs API 注册通话、接收用于将通话连接到智能体的 [TwiML](https://www.twilio.com/docs/voice/twiml)。

以下情况适合使用此方案：

* 需要保留现有的 Twilio 基础设施和 workflow
* 希望以编程方式控制通话路由和处理
* 在连接智能体前，需要通过自定义 Twilio 逻辑处理复杂通话流程
* 需要将 ElevenLabs 智能体集成到现有电话系统

## 工作原理

1. 服务器通过 Twilio 接收来电或发起去电
2. 服务器调用 ElevenLabs 注册通话端点，并提供智能体和通话详情
3. ElevenLabs 返回通过 WebSocket 将通话连接到智能体的 TwiML
4. 将此 TwiML 返回给 Twilio 以建立连接

> **Note**
>
> 使用注册通话端点时，无法使用通话转接功能，因为 ElevenLabs 无法直接访问 Twilio 账户凭据。

## 前提条件

* 一个 [ElevenLabs 账户](https://elevenlabs.io)
* 一个已配置的 ElevenLabs 对话式 AI 智能体（[在此创建](/docs/zh/eleven-agents/quickstart)）
* 一个拥有有效电话号码的 [Twilio 账户](https://www.twilio.com/try-twilio)
* 智能体已配置 μ-law 8000 Hz 音频格式（参见[智能体配置](#agent-configuration)）

## 智能体配置

使用注册通话端点前，请将智能体配置为使用 Twilio 支持的正确音频格式。

#### 配置 TTS 输出

1. 前往智能体设置
2. 打开 Voice 部分
3. 从下拉菜单中选择“μ-law 8000 Hz”

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

#### 设置输入格式

1. 前往智能体设置
2. 打开 Advanced 部分
3. 为输入格式选择“μ-law 8000 Hz”

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

## API 参考

注册通话端点接受以下参数：

| 参数                                    | 类型     | 必填 | 说明                             |
| ------------------------------------- | ------ | -- | ------------------------------ |
| `agent_id`                            | string | 是  | 处理通话的智能体 ID                    |
| `from_number`                         | string | 是  | 来电号码                           |
| `to_number`                           | string | 是  | 目标电话号码                         |
| `direction`                           | string | 否  | 通话方向：`inbound`（默认）或 `outbound` |
| `conversation_initiation_client_data` | object | 否  | 动态变量和配置覆盖                      |

该端点会返回应直接传递给 Twilio 的 TwiML。

## 实现

```python
import os
from fastapi import FastAPI, Request
from fastapi.responses import Response
from elevenlabs import ElevenLabs

app = FastAPI()

elevenlabs = ElevenLabs()
AGENT_ID = os.getenv("ELEVENLABS_AGENT_ID")

@app.post("/twilio/inbound")
async def handle_inbound_call(request: Request):
    form_data = await request.form()
    from_number = form_data.get("From")
    to_number = form_data.get("To")

    # Register the call with ElevenLabs
    twiml = elevenlabs.conversational_ai.twilio.register_call(
        agent_id=AGENT_ID,
        from_number=from_number,
        to_number=to_number,
        direction="inbound",
        conversation_initiation_client_data={
            "dynamic_variables": {
                "caller_number": from_number,
            }
        }
    )

    # Return the TwiML directly to Twilio
    return Response(content=twiml, media_type="application/xml")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
```

```typescript
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import express from "express";

const app = express();
app.use(express.urlencoded({ extended: true }));

const elevenlabs = new ElevenLabsClient();
const AGENT_ID = process.env.ELEVENLABS_AGENT_ID;

// Handle incoming Twilio calls
app.post("/twilio/inbound", async (req, res) => {
  const { From: fromNumber, To: toNumber } = req.body;

  // Register the call with ElevenLabs
  const twiml = await elevenlabs.conversationalAi.twilio.registerCall({
    agentId: AGENT_ID,
    fromNumber,
    toNumber,
    direction: "inbound",
    conversationInitiationClientData: {
      dynamicVariables: {
        caller_number: fromNumber,
      },
    },
  });

  // Return the TwiML directly to Twilio
  res.type("application/xml").send(twiml);
});

app.listen(8000, () => {
  console.log("Server running on port 8000");
});
```

## 去电

对于去电，请通过 Twilio 发起通话，并将 webhook URL 指向服务器；服务器随后向 ElevenLabs 注册：

```python
from twilio.rest import Client
import os
from fastapi import Request
from fastapi.responses import Response
from elevenlabs import ElevenLabs

# Initialize clients
twilio_client = Client(
    os.getenv("TWILIO_ACCOUNT_SID"),
    os.getenv("TWILIO_AUTH_TOKEN")
)
elevenlabs = ElevenLabs()
AGENT_ID = os.getenv("ELEVENLABS_AGENT_ID")

def initiate_outbound_call(to_number: str):
    call = twilio_client.calls.create(
        from_=os.getenv("TWILIO_PHONE_NUMBER"),
        to=to_number,
        url="https://your-server.com/twilio/outbound"
    )
    return call.sid

@app.post("/twilio/outbound")
async def handle_outbound_webhook(request: Request):
    form_data = await request.form()
    from_number = form_data.get("From")
    to_number = form_data.get("To")

    twiml = elevenlabs.conversational_ai.twilio.register_call(
        agent_id=AGENT_ID,
        from_number=from_number,
        to_number=to_number,
        direction="outbound",
    )

    return Response(content=twiml, media_type="application/xml")
```

```typescript
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import Twilio from "twilio";

// Initialize clients
const twilioClient = new Twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
const elevenlabs = new ElevenLabsClient();
const AGENT_ID = process.env.ELEVENLABS_AGENT_ID;

// Initiate an outbound call
async function initiateOutboundCall(toNumber: string) {
  const call = await twilioClient.calls.create({
    from: process.env.TWILIO_PHONE_NUMBER,
    to: toNumber,
    url: "https://your-server.com/twilio/outbound",
  });
  return call.sid;
}

// Handle the Twilio webhook for outbound calls
app.post("/twilio/outbound", async (req, res) => {
  const { From: fromNumber, To: toNumber } = req.body;

  const twiml = await elevenlabs.conversationalAi.twilio.registerCall({
    agentId: AGENT_ID,
    fromNumber,
    toNumber,
    direction: "outbound",
  });

  res.type("application/xml").send(twiml);
});
```

## 个性化对话

使用 `conversation_initiation_client_data` 参数传递动态变量并覆盖智能体配置：

```json
{
  "agent_id": "your-agent-id",
  "from_number": "+1234567890",
  "to_number": "+0987654321",
  "direction": "inbound",
  "conversation_initiation_client_data": {
    "dynamic_variables": {
      "customer_name": "John Doe",
      "account_type": "premium",
      "order_id": "ORD-12345"
    }
  }
}
```

> **Info**
>
> 有关动态变量和覆盖的更多信息，请参阅[动态变量](/docs/zh/eleven-agents/customization/personalization/dynamic-variables)和[覆盖](/docs/zh/eleven-agents/customization/personalization/overrides)文档。

## Twilio 配置

将 Twilio 电话号码配置为指向服务器：

#### 创建公共 URL

本地开发时，可使用 [ngrok](https://ngrok.com) 公开服务器：

```bash
ngrok http 8000
```

#### 配置 Twilio 号码

1. 前往 [Twilio Console](https://console.twilio.com)
2. 前往 Phone Numbers > Manage > Active numbers
3. 选择电话号码
4. 在“Voice Configuration”下，将 webhook URL 设为服务器端点（例如 `https://your-ngrok-url.ngrok.app/twilio/inbound`）
5. 将 HTTP 方法设为 POST

![](/docs/_fern-img/510d09d492b0c6ac9966f8fe39a9da685df79e8108f6fbc55fe502f48f650084.webp)

## 限制

使用注册通话端点而非原生集成时：

* **不支持通话转接**：由于 ElevenLabs 无法访问 Twilio 凭据，因此无法使用转接功能
* **需手动配置**：必须自行配置音频格式并处理 TwiML 路由
* **不会导入控制台**：以此方式注册的电话号码不会显示在 ElevenLabs 电话号码控制台中