Hướng dẫn
Tích hợp tổng đài vào phần mềm của bạn
Bấm gọi từ phần mềm của bạn, hiện thông tin khách khi có cuộc gọi đến, lưu lịch sử, ghi âm và tóm tắt. Khoảng 30 phút cho bản chạy được.
1Tạo API key có quyền Tổng đài
Trong app: Thiết lập › Ứng dụng & API › API key → nhóm Call → bật
call.partner.originate(gọi thay),call.calls.view,call.recordings.view. Nên khoanh Tổng đài viên được gọi thay nếu API key chỉ phục vụ một nhóm.2Bấm gọi từ phần mềm của bạn
Tổng đài viên đổ chuông trước, nhấc máy xong mới quay sang khách. Chỉ định tổng đài viên bằng đúng một trong
agentId,agentEmail,extension. Số khách viết kiểu nào cũng được, kết quả luôn trả số E.164. GửiIdempotency-Keyđể bấm lặp không tạo hai cuộc gọi. Mã khách bên bạn gửi ởcontactRef.curlcurl -X POST "https://api.nextx.vn/api/v1/call/partner/calls" \ -H "X-Api-Key: <API_KEY>" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 6f1c2b0e-0a7d-4e4f-9b1a-2f3c4d5e6f70" \ -d '{ "agentEmail": "agent@your-company.com", "to": "0901234567", "contactRef": "CUS-00123", "metadata": { "ticket": "T-889" } }' # 201 → { "callId": "…", "status": "initiated", "to": "+84901234567", "agent": { … } }3Đăng ký webhook Call và verify signature
Thiết lập › Ứng dụng & API › Webhooks → Call → dán URL → Xác minh và lưu → bật các sự kiện cần. Verify signature theo chuẩn Standard Webhooks bằng thư viện có sẵn cho Node, Python, Go, PHP, Java, C#. Trả
2xxtrong 5 giây, việc nặng đưa vào hàng đợi.Node.js (Express)import { Webhook } from "standardwebhooks"; // npm i standardwebhooks const wh = new Webhook(process.env.NEXTX_WEBHOOK_SECRET); // "whsec_…" app.post("/hooks/call", express.raw({ type: "application/json" }), (req, res) => { const raw = req.body.toString("utf8"); const event = JSON.parse(raw); // the URL verification ping uses a one-time secret: answer it BEFORE checking the signature if (event.type === "endpoint.verification") return res.json({ challenge: event.challenge }); try { wh.verify(raw, req.headers); // webhook-id / webhook-timestamp / webhook-signature } catch { return res.sendStatus(401); } queue.add(event); // handle it in the background res.sendStatus(200); });4Popup cuộc gọi đến và lưu lịch sử
call.ringingtới khi khách đang gọi: tra khách theofromrồi bật popup.call.completed/call.missedmang trạng thái cuối (completed,busy,no-answer,failed,canceled,abandoned) vàhangupCausetheo Q.850. Webhook có thể tới hơn một lần hoặc lệch thứ tự: chống trùng theoid, sắp lại theosequence.workerasync function handle(event) { if (await db.processed.exists(event.id)) return; // delivered at least once const call = event.data.object; // callId, status, from, to (E.164), agent, sequence… if (call.sequence < (await db.callSequence(call.callId))) return; // a later stage already arrived switch (event.type) { case "call.ringing": showPopup(call.agent?.email, await customers.findByPhone(call.from)); break; case "call.answered": markInProgress(call.contactRef, call.agent); break; case "call.completed": case "call.missed": saveCallLog(call.contactRef, call.status, call.talkSec, call.hangupCause); break; } await db.processed.insert(event.id); }5Ghi âm và tóm tắt
Khi nhận
call.recording_ready, gọi API để lấy link tải có hạn 15 phút (webhook không bao giờ chứa link). Khi nhậncall.summary_ready, đọc tóm tắt cuộc gọi.curl# on call.recording_ready — the link is valid for 15 minutes, ask again when it expires curl "https://api.nextx.vn/api/v1/call/partner/calls/<callId>/recording" \ -H "X-Api-Key: <API_KEY>" # → { "url": "https://…", "expiresAt": "…", "contentType": "audio/wav" } # on call.summary_ready curl "https://api.nextx.vn/api/v1/call/calls/<callId>/summary" -H "X-Api-Key: <API_KEY>"6Thử trên sandbox
Dùng
to=sandbox:echo: tổng đài viên đổ chuông, nhấc máy sẽ nghe âm thử khoảng 10 giây rồi tự cúp, không gọi ra nhà mạng. Bạn nhận đủ chuỗi webhook như cuộc gọi thật. Mỗi khoá được tạo tối đa 60 cuộc gọi/phút.curl (sandbox)curl -X POST "<SANDBOX_API_URL>/api/v1/call/partner/calls" \ -H "X-Api-Key: <SANDBOX_API_KEY>" -H "Content-Type: application/json" \ -d '{ "extension": "1021", "to": "sandbox:echo", "contactRef": "TEST-1" }'