Tích hợp cuộc gọi thoại WhatsApp vào hệ thống hỗ trợ khách hàng
Để tích hợp cuộc gọi thoại WhatsApp qua UnifyPort, backend chuẩn bị cuộc gọi với media_type: "voice", rồi chuyển liên kết trình duyệt riêng tư cho nhân viên phụ trách. Cuộc gọi chỉ bắt đầu quay số khi nhân viên mở liên kết và nhấn Start call. Backend liên kết call_id trả về với tác vụ hỗ trợ và theo dõi kết quả qua sự kiện cuộc gọi.
Bài này hướng dẫn cuộc gọi đi một đối một, do nhân viên chủ động bắt đầu trong bản thử nghiệm kín. UnifyPort dùng giao diện không chính thức; đây không phải hướng dẫn tích hợp Meta WhatsApp Business Calling API. Xem thông báo thử nghiệm cuộc gọi để biết tổng quan và cách đăng ký.
1. Chuẩn bị tài khoản và chọn cuộc trò chuyện
Liên hệ hỗ trợ kỹ thuật để xin quyền gọi cho không gian làm việc. Tạo API key không tự bật tính năng: is_beta là cờ quyền truy cập chỉ đọc, không phải thiết lập có thể bật qua metadata của không gian làm việc.
Trước khi hiển thị thao tác gọi, kiểm tra tài khoản nhắn tin WhatsApp đã được ủy quyền và runtime_status là running. Chọn cuộc trò chuyện riêng thuộc cùng tài khoản và giữ nguyên conversation_id do API trả về. Không thay bằng số điện thoại hoặc tự ghép mã định danh của nhà cung cấp.
Trong ứng dụng, gắn không gian làm việc, tài khoản, cuộc trò chuyện và tác vụ hỗ trợ đã chọn với thao tác này. Backend phải kiểm tra quyền của nhân viên. Tin nhắn mới hoặc việc chuyển sang cuộc trò chuyện khác không được âm thầm đổi người nhận của cuộc gọi đã chuẩn bị.
Trong quy trình dưới đây, API key luôn nằm trên máy chủ. Trình duyệt chỉ nhận liên kết riêng tư cần thiết cho cuộc gọi.
2. Chuẩn bị cuộc gọi thoại ở backend
Thay các giá trị mẫu bằng API key của không gian làm việc, tài khoản đã kết nối và cuộc trò chuyện đã chọn, rồi chạy trên máy chủ:
curl -X POST 'https://api.unifyport.ai/v1/calls' \
-H 'X-Api-Key: <YOUR_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"account_id": "acc_example",
"to": { "id": "<conversation_id>", "type": "user" },
"media_type": "voice"
}'
Tài liệu tạo cuộc gọi quy định phản hồi thành công là 201 Created, với cấu trúc như dưới đây. Các giá trị chỉ để minh họa, không phải xác nhận của cuộc gọi thật:
{
"request_id": "req_example",
"data": {
"call_id": "call_example",
"direction": "outbound",
"media_type": "voice",
"state": "preparing",
"join_url": "https://calls.example.com/call/call_example#ticket=example-only",
"expires_at": "2026-10-27T08:02:00Z"
}
}
Lưu data.call_id cùng tài khoản, cuộc trò chuyện và tác vụ đã chọn; giữ request_id để điều tra sự cố. Xem data.join_url là thông tin bí mật: chuyển nguyên vẹn cho đúng nhân viên phụ trách, không ghi URL đầy đủ vào log, hệ thống phân tích hay tin nhắn công khai.
201 và preparing chỉ cho biết liên kết đã sẵn sàng. Chúng không có nghĩa điện thoại khách hàng đang đổ chuông hoặc khách hàng đã nghe máy.
3. Để nhân viên bắt đầu cuộc gọi trong trình duyệt
Hiển thị khách hàng đã chọn và trạng thái “Sẵn sàng bắt đầu” trong giao diện nghiệp vụ. Chỉ cung cấp join_url cho đúng nhân viên. Trên trang gọi, nhân viên cho phép truy cập micrô và nhấn Start call trước expires_at.
Thời hạn chuẩn bị mặc định là hai phút kể từ lúc tạo, nhưng máy chủ có thể điều chỉnh. Đọc expires_at thay vì tự tính một thời hạn cố định. Thời hạn này không giới hạn độ dài cuộc gọi đã kết nối. Quyền micrô là bắt buộc; quyền camera là tùy chọn.
Chặn gửi lặp trong lúc chờ phản hồi tạo cuộc gọi. Nếu mất phản hồi, hiển thị kết quả chưa xác định và truy vấn cuộc gọi hiện tại trước khi cân nhắc tạo lại. Chỉ vô hiệu hóa nút không đủ để phối hợp nhiều nhân viên, nên backend cũng phải xử lý xung đột ở cấp tài khoản.
4. Liên kết Webhook với tác vụ hỗ trợ
Nếu endpoint Webhook dùng danh sách sự kiện cụ thể, thêm hai tên dưới đây nhưng giữ lại các đăng ký khác vẫn cần. Đây chỉ là đoạn trường dữ liệu, không phải toàn bộ yêu cầu tạo endpoint:
{
"subscribed_events": ["call.answered", "call.ended"]
}
Với không gian làm việc có quyền thử nghiệm, *, danh sách rỗng hoặc việc bỏ qua danh sách cũng bao gồm các sự kiện cuộc gọi được phép nhận. Đăng ký bằng ký tự đại diện không cấp quyền nhận sự kiện cuộc gọi cho không gian làm việc ngoài chương trình thử nghiệm.
| Dữ liệu quan sát được | Cách ứng dụng xử lý |
|---|---|
data.call_id trong phản hồi tạo | Liên kết cuộc gọi với tác vụ hỗ trợ đã chọn |
data.call.id trong call.answered | Ghi nhận cuộc gọi đã kết nối |
data.call.id, data.reason, data.duration_seconds trong call.ended | Ghi lý do kết thúc và thời lượng đã kết nối |
Trước khi xử lý sự kiện có chữ ký, cấu hình signing_secret cho endpoint và giữ bí mật này trên máy chủ.
Xác minh chữ ký bằng nội dung yêu cầu gốc và loại trùng theo id ở lớp bao sự kiện, theo quy định phân phối Webhook. Đối chiếu account_id và data.call.id của sự kiện với liên kết đã lưu. Sự kiện đến muộn hoặc lặp không được khiến giao diện đưa cuộc gọi đã kết thúc trở lại trạng thái đang gọi.
Lưu riêng bằng chứng đã kết nối: duration_seconds được làm tròn xuống, nên chỉ có 0 không chứng minh rằng cuộc gọi chưa được trả lời. Lỗi đồng bộ khi tạo có thể không sinh sự kiện kết thúc; cần ghi nhận lỗi HTTP riêng. Xem payload đầy đủ tại tài liệu sự kiện kết nối và sự kiện kết thúc. Cuộc gọi kết thúc không tự động có nghĩa tác vụ hỗ trợ đã được giải quyết.
5. Truy vấn hoặc kết thúc cuộc gọi được quản lý
Khi cần khôi phục trạng thái hoặc tìm lại mã cuộc gọi bị mất, dùng endpoint lấy cuộc gọi hiện tại:
curl --get 'https://api.unifyport.ai/v1/calls/active' \
-H 'X-Api-Key: <YOUR_API_KEY>' \
--data-urlencode 'account_id=acc_example'
data: {} nghĩa là tài khoản hiện không có cuộc gọi do UnifyPort quản lý. Đây không phải lịch sử cuộc gọi, không xác nhận kết quả lần thử trước và không phát hiện được cuộc gọi trong ứng dụng WhatsApp gốc. Phản hồi cũng không cấp lại join_url dùng một lần.
Khi nhân viên quyết định kết thúc một cuộc gọi đã xác định, dùng call_id đã lưu và tài khoản tương ứng:
curl -X POST 'https://api.unifyport.ai/v1/calls/call_example/hangup' \
-H 'X-Api-Key: <YOUR_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{"account_id":"acc_example"}'
Endpoint ngắt cuộc gọi trả về trạng thái cuối ended hoặc failed; gửi lại yêu cầu có thể trả về trạng thái cuối đã có. Không tiếp tục ngắt chỉ vì nhận failed, và không kết thúc cuộc gọi của nhân viên khác chỉ để giải quyết xung đột khi tạo.
Các vấn đề thường gặp khi tích hợp
| Tình huống | Bước tiếp theo |
|---|---|
403 beta_feature_not_enabled | Nhờ hỗ trợ kiểm tra quyền của không gian làm việc; sửa metadata không bật được quyền |
| Liên kết chuẩn bị hết hạn | Ngừng dùng lại; kiểm tra cuộc gọi hiện tại rồi để nhân viên quyết định rõ ràng có chuẩn bị lần mới hay không |
| Trình duyệt không dùng được micrô | Kiểm tra quyền micrô của trang gọi trước khi kỳ vọng quay số thành công |
| Yêu cầu tạo xung đột với cuộc gọi đang có | Truy vấn cuộc gọi được quản lý, xác định nhân viên phụ trách và mục đích trong ứng dụng |
| Yêu cầu tạo hoặc ngắt bị hết thời gian chờ | Giữ kết quả chưa xác định, đối chiếu trạng thái hiện tại và sự kiện đã nhận trước khi thử lại |
Kiểm tra trọn vẹn một quy trình hỗ trợ
Trong cuộc trò chuyện thử nghiệm đã được đồng ý, kiểm tra kết nối và ngắt bình thường, liên kết chuẩn bị hết hạn, từ chối quyền micrô, nhấn lặp, xung đột tài khoản và mất phản hồi HTTP. Đảm bảo sự kiện gửi lại không tạo bản ghi tác vụ trùng và URL cuộc gọi đầy đủ không vào log. Đây là các bước nghiệm thu cho tích hợp của bạn, không phải kết quả thực nghiệm mà bài viết tuyên bố đã hoàn thành.
Có thể tự động gọi một danh sách số điện thoại không?
Không. Quy trình cần conversation_id thuộc tài khoản và thao tác nhấn Start call của con người trong trình duyệt.
Tích hợp này có nhận cuộc gọi đến được không?
Chưa có trong bản thử nghiệm hiện tại. call.incoming là hợp đồng dự phòng; việc xuất hiện trong danh mục sự kiện không mở quyền nhận cuộc gọi đến. Gọi nhóm, ghi âm, chuyển giọng nói thành văn bản, tích hợp SIP/PBX và nhân viên thoại AI cũng nằm ngoài phạm vi thử nghiệm này.
Nhóm nên bắt đầu từ đâu?
Nếu chưa có quyền, liên hệ hỗ trợ kỹ thuật để đăng ký, kèm ID không gian làm việc và tình huống hỗ trợ dự kiến. Không gửi API key hay liên kết gọi riêng tư. Sau khi được bật, làm theo tài liệu tạo cuộc gọi để kiểm tra một cuộc trò chuyện đã chọn trước khi đưa thao tác vào quy trình hỗ trợ.
Biến tích hợp nhắn tin thành một pipeline sản phẩm ổn định.
Bắt đầu bằng cách gửi qua một API, rồi đưa mọi tin nhắn inbound trở lại hệ thống kinh doanh bằng sự kiện chuẩn.