---
title: "Gọi thoại qua trợ lý"
locale: vi
url: https://tlg.builera.app/docs/agent-playbooks/make-a-call
verified: 2026-10-27
app_version: "2.4"
---

# Gọi thoại qua trợ lý

Quay số hoặc nghe một cuộc gọi thoại Telegram 1:1 từ trợ lý AI, với tiếng phát ở tab trình duyệt sẵn sàng và người xác nhận trước khi đổ chuông.


## Mục tiêu

Bạn bắt đầu, nghe, từ chối hoặc cúp một cuộc gọi thoại Telegram 1:1 thay cho người dùng. Bạn **không** mang tiếng: tiếng đi giữa máy chạy và một tab trình duyệt của người dùng.

## Quyền cần

- Phạm vi `calls` cho `calls.start`, `calls.answer`, `calls.decline`, `calls.hangup`, `calls.endpoints`.
- `messages.read` cho `calls.readiness`, `calls.list`, `calls.get`.
- Tài khoản phải nằm trong phạm vi kết nối. Phạm vi `calls` không có sẵn trong mẫu Vận hành hay Thiết lập: người dùng phải bật riêng hoặc chọn Toàn quyền.

## Hỏi người trước khi

Cuộc gọi làm điện thoại của một người thật đổ chuông. Hỏi người dùng gọi ai, từ tài khoản nào, để làm gì. Không tự gọi chỉ vì có trong danh sách.

## Kiểm trước

1. Gọi `whoami` để chắc có phạm vi `calls`.
2. Gọi `calls.endpoints`. Danh sách rỗng nghĩa là không có tab nào bật **Sẵn sàng nhận cuộc gọi do Agent quay**: nhờ người dùng mở app và bật công tắc này (ở trang **Kết nối AI** hoặc trong **Cài đặt cuộc gọi**). Không có tab thì `calls.start` trả `audio_endpoint_required` và không đổ chuông.
3. Gọi `calls.readiness` với `conversationId`. Nếu `ready` là `false`, đọc mã lý do ở bảng dưới và dừng.

## Các bước

1. Gọi `calls.start` với `conversationId`. Lần đầu luôn trả `confirmation_required` kèm `confirm_token`.

> [!IMPORTANT]
> Điểm dừng — hỏi người
>
> Nhắc lại người được gọi và tài khoản gọi. Chỉ khi người dùng đồng ý, gọi lại `calls.start` với cùng input cộng `confirm_token`. Mỗi token dùng một lần.

2. Nhận `callId` và theo dõi bằng `operations_get` cho việc quay số, rồi `calls.get` (hoặc sự kiện `calls.*`) cho trạng thái cuộc gọi: `ringing` → `exchanging_keys` → `active` → `ended`.
3. Để nghe một cuộc gọi đến đang `ringing`, gọi `calls.answer` với `callId`; tiếng ra tab sẵn sàng. Nếu đã có người bấm nghe, bạn nhận `already_answered`.
4. Gọi `calls.hangup` để kết thúc, hoặc `calls.decline` cho cuộc gọi đến chưa nghe. Hai thao tác này luôn chạy được và không tính hạn mức.

## Kiểm sau

Đọc `calls.get`: `state = ended` và `end_reason` cho biết kết quả (`hangup`, `remote_hangup`, `declined`, `missed`, `busy`, `failed`, `media_unreachable`…). Chỉ báo người dùng "đã nói chuyện" khi cuộc gọi từng ở `active` và có thời lượng.

## Khi lỗi

| Mã | Ý nghĩa | Làm gì |
|---|---|---|
| `proxy_no_udp` | Proxy của tài khoản không chở được tiếng (HTTP, hoặc SOCKS5 chưa xác nhận UDP) | Báo người dùng cần proxy SOCKS5 có UDP; không thử lại |
| `audio_endpoint_required` | Không có tab sẵn sàng | Nhờ người dùng bật **Sẵn sàng nhận cuộc gọi do Agent quay** |
| `account_unavailable` | Tài khoản chưa đăng nhập, tạm dừng, proxy lỗi hoặc máy tắt | Dừng, báo người dùng |
| `worker_outdated` | Máy chạy cũ hơn 1.0.49 | Chờ máy tự cập nhật |
| `not_private_chat` | Không phải chat riêng với một người | Chọn chat riêng khác |
| `peer_opted_out` | Người đó đã yêu cầu không liên hệ | Không gọi |
| `quota_exceeded` | Tài khoản An toàn đã đủ 10 cuộc hôm nay hoặc gọi quá sát nhau | Chờ, không đổi tài khoản để lách |
| `account_busy`, `node_calls_full` | Tài khoản hoặc máy đang đủ cuộc gọi | Thử lại sau |
| `calls_disabled` | Gọi đang tắt toàn hệ thống | Chờ |
| `already_answered`, `call_ended`, `call_not_found` | Cuộc gọi đã có người nghe, đã kết thúc hoặc không thuộc phạm vi | Đọc lại `calls.get` |

Kết thúc `media_unreachable` nghĩa là bắt máy được nhưng tiếng không qua được proxy. Không quay lại ngay; báo người dùng kiểm tra proxy.

## Điều kiện dừng

Dừng khi cuộc gọi đã `ended`, khi người dùng không xác nhận, hoặc khi gặp bất kỳ mã lỗi nào ở trên ngoài `account_busy` / `node_calls_full`.

