Tài liệu này mô tả giao thức WebSocket để AI Voice Bot tích hợp với Voice Gateway của Alohub. Vendor cung cấp một WebSocket server theo spec dưới đây — Gateway sẽ kết nối đến khi cuộc gọi bắt đầu và trao đổi audio/control event trong suốt cuộc gọi.
Lưu ý: Mô hình tham chiếu theo Twilio Media Streams. Mỗi cuộc gọi tương ứng với 1 WebSocket connection độc lập, không reuse. Liên hệ Alohub để được hỗ trợ tích hợp.
Voice Gateway là WebSocket client, khởi tạo connection tới bot khi cuộc gọi mới bắt đầu
AI Voice Bot là WebSocket server, lắng nghe connection, xử lý audio, trả audio phản hồi
Mỗi cuộc gọi = 1 WebSocket connection độc lập, không reuse
Vendor cung cấp URL WebSocket, Gateway truyền api_key qua query param:
wss://bot.vendor.com/ws/voice?api_key=<KEY>Bot verify api_key trong handshake. Nếu sai → đóng WS với close code 1008.
Yêu cầu | Giá trị |
|---|---|
Protocol | WebSocket (RFC 6455) |
Scheme |
|
Message format | JSON, text frames, UTF-8 |
Audio transport | Base64 trong field |
Timeout | Giá trị mặc định |
|---|---|
Connect timeout | 5 giây |
Idle timeout (không có media) | 30 giây |
Max session duration | 900 giây |
Khi cuộc gọi kết thúc, Gateway gửi event stop rồi đóng WS với close code 1000 (normal). Vendor không cần reconnect.
Thuộc tính | Giá trị |
|---|---|
Codec | PCM signed 16-bit little-endian ( |
Sample rate | 8000 Hz |
Channels | 1 (mono) |
Frame size | 20ms/chunk (160 samples = 320 bytes) |
Transport | Base64 string trong JSON |
Lưu ý: Audio format cố định ở v1. Gateway và bot đều phải dùng đúng format này.
Ở v1, bot hoạt động theo mô hình half-duplex: bot phát xong audio response thì Gateway mới forward audio của caller lên. Bot không cần xử lý barge-in.


Mọi message là JSON UTF-8 gửi qua WebSocket text frame.
Gửi 1 lần duy nhất khi WS connection được thiết lập thành công.
{
"event": "connected",
"sequence_number": 0
}Gửi 1 lần duy nhất sau connected. Chứa metadata cuộc gọi. Vendor nên cache thông tin này trong suốt session.
{
"event": "start",
"sequence_number": 1,
"start": {
"stream_sid": "MZxxxxxxxxxxxxxxxx",
"call_sid": "call-abc123",
"media_format": {
"encoding": "pcm_s16le",
"sample_rate": 8000,
"channels": 1
},
"metadata": {
"phone_number": "0900000000",
"direction": "outbound",
"custom": {
"key1": "value1",
"key2": "value2"
}
}
}
}Field | Type | Mô tả |
|---|---|---|
| string | ID duy nhất của WebSocket stream |
| string | ID cuộc gọi, dùng để log/trace |
| object | Luôn là PCM 8kHz mono s16le ở v1 |
| string | Số điện thoại của caller |
| string |
|
| object | Dynamic fields tuỳ cấu hình từng bot — schema định nghĩa khi đăng ký bot |
Audio từ caller stream lên bot. Gửi liên tục ~20ms/chunk.
{
"event": "media",
"sequence_number": 42,
"media": {
"track": "inbound",
"chunk": 41,
"timestamp": 1776326027630,
"payload": "<base64_pcm_data>"
}
}Field | Type | Mô tả |
|---|---|---|
| string | Luôn |
| int | Số thứ tự chunk, bắt đầu từ 0 |
| int | Unix ms |
| string | Base64 của raw PCM bytes (320 bytes/chunk) |
Echo lại marker mà bot đã gửi — Gateway gửi mark lại cho bot khi audio tương ứng đã phát xong cho caller nghe.
{
"event": "mark",
"sequence_number": 80,
"mark": {
"name": "greeting_done"
}
}Cuộc gọi kết thúc. Gateway gửi rồi đóng WS.
{
"event": "stop",
"sequence_number": 999,
"stop": {
"reason": "caller_hangup",
"call_sid": "call-abc123"
}
}
| Mô tả |
|---|---|
| Caller cúp máy |
| Bot yêu cầu dừng |
| Cuộc gọi đã transfer thành công |
| Idle timeout |
| Lỗi hệ thống |
Audio response bot phát cho caller nghe.
{
"event": "media",
"media": {
"payload": "<base64_pcm_data>"
}
}Phải là PCM 8kHz mono s16le (đúng với start.media_format)
Chunk size nên 20–100ms để giảm latency
Không cần chunk / timestamp — Gateway tự sequence
Đặt checkpoint. Gateway sẽ echo lại khi audio trước nó đã phát xong cho caller.
{
"event": "mark",
"mark": {
"name": "question_1_done"
}
}Bot dùng để biết khi nào caller đã nghe xong audio, từ đó bật ASR lắng nghe phản hồi.
Chuyển cuộc gọi sang agent hoặc queue.
{
"event": "transfer",
"transfer": {
"target": "agent_extension_or_queue",
"context": "default",
"on_complete": "hangup_bot"
}
}Field | Type | Mô tả |
|---|---|---|
| string | Extension / queue ID / phone number |
| string | Routing context, nhận từ Gateway khi đăng ký |
| string |
|
Sau khi nhận transfer, Gateway sẽ: phát nốt audio trong buffer (drain) → thực hiện transfer → gửi stop với reason transferred cho bot → đóng WS.
Kết thúc cuộc gọi chủ động từ bot.
{
"event": "stop",
"stop": {
"reason": "conversation_complete"
}
}Gateway sẽ phát nốt audio trong buffer rồi kết thúc cuộc gọi.
Code | Ý nghĩa |
|---|---|
| Normal closure |
| Protocol error — JSON sai format, thiếu field bắt buộc |
| Policy violation — |
| Internal error |
| Audio format mismatch |
| Timeout |
Gateway sẽ đóng WS với code 1002 nếu:
Message không phải JSON hợp lệ
Thiếu field event
event không nằm trong danh sách whitelist
media.payload không phải base64 hợp lệ
Audio decode fail > 5 lần liên tiếp
Log đầy đủ call_sid và stream_sid trong mọi log line
Validate JSON trước khi process, không crash WS handler
Rate limit audio output: không gửi > 2x realtime
Graceful shutdown: khi gửi stop / transfer, chờ Gateway đóng WS
File | Mô tả |
|---|---|
| Bot tham chiếu — Python asyncio + websockets |
| Bot tham chiếu — Node.js (ws) |
| Mock Gateway để vendor tự test bot local |
WS server verify api_key từ query param
Handle được connected, start, media, mark, stop
Gửi được media response đúng PCM 8kHz mono s16le
Implement mark để sync khi caller đã nghe xong
Implement transfer khi cần chuyển agent
Log đầy đủ call_sid, stream_sid
Graceful shutdown
Test với mock_gateway.py pass
Gửi URL + api_key cho team tích hợp
Smoke test 10 cuộc gọi trên staging
Q: Bot có thể gửi audio nhiều chunk một lần không?
A: Được, nhưng tổng audio duration không quá 500ms/message để tránh jitter.
Q: Dùng binary frame thay JSON được không?
A: Không hỗ trợ ở v1.
Q: Latency kỳ vọng?
A: End-to-end (caller nói → bot phản hồi): mục tiêu < 800ms. Network round-trip Gateway↔Bot nền < 100ms.
Q: Có hỗ trợ barge-in (caller ngắt lời bot) không?
A: Không, v1 chạy half-duplex — bot phát xong Gateway mới forward audio caller lên. Sẽ hỗ trợ ở v2.
Q: Khi nào Gateway đóng WS?
A: Sau khi gửi stop, hoặc caller hangup, hoặc timeout, hoặc lỗi protocol.
Q: Có hỗ trợ sample rate khác 8kHz hoặc codec khác PCM không?
A: Không ở v1. Cố định PCM 8kHz mono s16le.
Q: Bot có cần handle DTMF không?
A: Không, v1 không forward DTMF lên bot.
Liên hệ team tích hợp để:
Review implementation
Cấu hình api_key và URL trên staging/production
Debug cuộc gọi thật (cần cung cấp call_sid)
Thông tin liên hệ: Vui lòng Liên hệ Alohub để được hỗ trợ tích hợp và nhận thông tin xác thực.