Tài liệu dành cho nhà phát triển muốn tích hợp điện thoại WebRTC của Alohub vào website/ứng dụng web.
AlohubPhone SDK v3 là thư viện JavaScript cho phép nhúng điện thoại WebRTC trực tiếp vào website. Nhân viên có thể gọi và nhận cuộc gọi ngay trên trình duyệt mà không cần cài phần mềm.
Bạn cần có:
✅ API Key — Liên hệ Alohub để được cấp API Key
✅ userName — Tên đăng nhập tài khoản Alohub (ví dụ: admin.alohub)
Yêu cầu | Chi tiết |
|---|---|
Trình duyệt | Chrome 60+, Firefox 55+, Edge 79+, Safari 11+, CocCoc |
HTTPS | Bắt buộc trên production (localhost được miễn) |
Microphone | Cần quyền truy cập microphone |
Lưu ý: SDK chỉ hoạt động với tổng đài Alohub. Không thể sử dụng với tổng đài khác. Liên hệ Alohub để đăng ký tổng đài.
Thêm 1 dòng script vào trang HTML:
<!-- Production -->
<script src="https://2.alohub.vn/sdk/v3/alohub-phone.prod.min.js"></script><!-- Development (server test) -->
<script src="https://app.alohub.vn/sdk/v3/alohub-phone.dev.min.js"></script>Download file alohub-phone.prod.min.js, đặt vào thư mục static, thêm script tag:
<script src="/assets/js/alohub-phone.prod.min.js"></script>File | Server | Mục đích |
|---|---|---|
|
| Test, phát triển |
|
| Production |
Đặt đoạn code sau trước thẻ </body>:
<script src="https://2.alohub.vn/sdk/v3/alohub-phone.prod.min.js"></script>
<script>
AlohubPhone.init({
apiKey: 'YOUR_API_KEY', // Thay bằng API key thật
userName: 'your.username', // Thay bằng username thật
});
</script>Sau khi thêm code, widget điện thoại xuất hiện ở góc dưới bên phải của trang web. Widget hiển thị:
Header: Trạng thái kết nối (dot xanh lá = online) + số extension
Ô nhập số: Nhập số điện thoại cần gọi + nút gọi
Bàn phím: Bấm "Hiện bàn phím" để hiện numpad đầy đủ
AlohubPhone.init({
apiKey: 'YOUR_API_KEY',
userName: 'your.username',
// Giao diện
theme: 'dark', // 'light' (mặc định) hoặc 'dark'
position: 'bottom-left', // Vị trí widget (xem bảng bên dưới)
language: 'vi', // vi, en, ja, ko, zh, th
// Hành vi
autoAnswer: false, // false = hiện popup khi có cuộc gọi đến
debug: true, // true = hiện log trong console
// Callbacks
onReady: function(phone) {
console.log('Sẵn sàng! Mic:', phone.getMicPermission());
},
onError: function(e) {
console.error('[' + e.code + ']', e.message);
},
onAuthFailed: function(e) {
console.error('Xác thực thất bại:', e.code, e.message);
}
});Giá trị | Vị trí |
|---|---|
| Góc dưới bên phải (mặc định) |
| Góc dưới bên trái |
| Góc trên bên phải |
| Góc trên bên trái |
SDK cung cấp 5 màn hình tự động chuyển đổi theo trạng thái cuộc gọi:
Màn hình | Khi nào | Hiển thị |
|---|---|---|
1. Dial | Mặc định | Ô nhập số + nút gọi + "Hiện bàn phím" |
2. Dial + Bàn phím | Bấm "Hiện bàn phím" | Numpad 0-9, *, # với chữ ABC/DEF + nút xóa ⌫ + nút Gọi lớn |
3. Ringing | Gọi ra | Số đang gọi + nút "Kết thúc" đỏ |
4. Incoming | Có cuộc gọi đến | Số gọi đến + nút "Từ chối" đỏ / "Chấp nhận" xanh |
5. Answering | Đang nghe máy | Số + timer + "Kết thúc" + "Hiện bàn phím" + "Chuyển cuộc gọi" |
Dot | Trạng thái | Khi nào |
|---|---|---|
🟢 Xanh lá | Online | SIP đã đăng ký, sẵn sàng gọi |
🟡 Vàng (nhấp nháy) | Đang kết nối | Đang kết nối WebSocket/SIP |
🔴 Đỏ | Offline | Mất kết nối / đăng ký thất bại |
🔵 Xanh dương (nhấp nháy) | Đang gọi | Đang trong cuộc gọi |
Khi bạn muốn tự thiết kế giao diện riêng, dùng headless: true. SDK sẽ không tạo UI nào cả, chỉ cung cấp API và events.
AlohubPhone.init({
apiKey: 'YOUR_API_KEY',
userName: 'your.username',
headless: true, // ← Không tạo UI widget
onReady: function(phone) {
// phone là instance SDK — điều khiển hoàn toàn bằng code
console.log('Sẵn sàng!');
phone.on('incoming', function(data) {
showMyPopup('Cuộc gọi từ: ' + data.remoteNumber);
});
phone.on('answered', function(data) {
showMyCallScreen(data.remoteNumber);
});
phone.on('ended', function(data) {
hideMyCallScreen();
saveCallLog(data);
});
phone.on('error', function(e) {
showMyError(e.code, e.message);
});
}
});Có Widget (mặc định) | Headless | |
|---|---|---|
Giao diện | Widget tự động | Bạn tự code |
DTMF / Mute / Hold | Có trên widget |
|
Events | Đầy đủ | Đầy đủ (giống nhau) |
| Có |
|
<!-- Nút gọi trong CRM -->
<button class="btn-call" data-phone="0901234567">📞 Gọi</button>
<script>
var phone = null;
AlohubPhone.init({
apiKey: 'YOUR_API_KEY',
userName: 'your.username',
headless: true,
onReady: function(p) {
phone = p;
// Ghi log cuộc gọi khi kết thúc
phone.on('ended', function(data) {
fetch('/api/call-logs', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
phone: data.remoteNumber,
duration: data.duration,
direction: data.direction
})
});
});
}
});
// Click-to-Call với extra SIP headers
document.querySelectorAll('.btn-call').forEach(function(btn) {
btn.addEventListener('click', function() {
if (phone) phone.call(this.dataset.phone, {
extraHeaders: ['X-CRM-INFO: lead|123']
});
});
});
</script>SDK cung cấp 3 lớp bắt lỗi:
onAuthFailed(e) — Xác thực thất bại (trước khi SDK sẵn sàng): MISSING_API_KEY, MISSING_USERNAME, INVALID_API_KEY, DOMAIN_NOT_WHITELISTED
.catch(err) — SIP registration thất bại: REGISTRATION_FAILED, REGISTRATION_TIMEOUT
phone.on('error', fn) — Tất cả lỗi runtime: MIC_NOT_FOUND, MIC_DENIED, CALL_MEDIA_FAILED, CALL_NO_NUMBER, CALL_NOT_READY, ...
phone.on('error', function(e) {
// e.code — Mã lỗi chuẩn (AlohubPhone.ERROR.*)
// e.type — Nhóm: 'mic', 'call', 'dtmf', 'transfer'
// e.message — Mô tả chi tiết
switch (e.code) {
case AlohubPhone.ERROR.MIC_NOT_FOUND:
alert('Không tìm thấy microphone!');
break;
case AlohubPhone.ERROR.MIC_DENIED:
alert('Microphone bị từ chối.');
phone.requestMicPermission(); // Yêu cầu lại
break;
case AlohubPhone.ERROR.CALL_MEDIA_FAILED:
alert('Lỗi microphone khi gọi.');
break;
case AlohubPhone.ERROR.CALL_NOT_READY:
alert('Điện thoại chưa sẵn sàng.');
break;
}
});
// Cuộc gọi thất bại — có SIP code chi tiết
phone.on('failed', function(e) {
console.log(e.sipCode, e.sipReason);
// 480 "Temporarily Unavailable"
// 486 "Busy Here"
});Mã lỗi | Nhóm | Mô tả |
|---|---|---|
| mic | Không có microphone |
| mic | Mic bị từ chối |
| mic | Mic lỗi khi gọi (JsSIP |
| call | Thiếu số điện thoại |
| call | Chưa đăng ký SIP |
| dtmf | Ký tự DTMF không hợp lệ |
| transfer | Transfer khi không có cuộc gọi |
| api | Gọi qua API thất bại |
SIP Code | Ý nghĩa |
|---|---|
480 | Temporarily Unavailable — Người nhận không online |
486 | Busy Here — Đang bận |
487 | Request Terminated — Cuộc gọi bị hủy |
603 | Decline — Người nhận từ chối |
404 | Not Found — Số không tồn tại |
SDK tự động xin quyền mic sau khi SIP registered. Nếu bị từ chối, có thể yêu cầu lại:
// Kiểm tra trạng thái (đồng bộ)
phone.getMicPermission(); // 'granted' | 'denied' | 'unknown'
// Yêu cầu lại (hiện popup browser)
phone.requestMicPermission().then(function(status) {
console.log('Mic:', status); // 'granted' hoặc 'denied'
});
// Lắng nghe thay đổi
phone.on('micPermission', function(e) {
if (e.status === 'denied') {
alert('Vui lòng cho phép microphone!');
}
});Lưu ý: Nếu user đã bấm "Chặn" trên browser,
requestMicPermission()sẽ bị từ chối ngay mà không hiện popup. User phải vào Settings > Site Settings > Microphone để bỏ chặn.
Nhóm | Method | Mô tả |
|---|---|---|
Gọi |
| Gọi ra (opts: |
| Nghe máy | |
| Kết thúc / từ chối | |
DTMF |
| Gửi phím bấm (0-9, *, #, A-D) |
Mic |
| Tắt/bật mic |
| Đảo trạng thái | |
Hold |
| Giữ máy / tiếp tục |
| Đảo trạng thái | |
Transfer |
| Chuyển cuộc gọi (blind transfer) |
Trạng thái |
| Đang gọi? |
| Mic đang tắt? | |
| Đang giữ máy? | |
| Chi tiết cuộc gọi | |
Kết nối |
| Logout SIP (giữ WebSocket) |
| Ngắt hoàn toàn | |
| Hủy instance + xóa UI + xóa credentials |
Code | Ngôn ngữ | Ví dụ giao diện |
|---|---|---|
| Tiếng Việt (mặc định) | Số điện thoại, Kết thúc, Nghe máy |
| English | Phone Number, Hang Up, Answer |
| 日本語 | 電話番号, 終了, 応答 |
| 한국어 | 전화번호, 종료, 받기 |
| 中文 | 电话号码, 挂断, 接听 |
| ภาษาไทย | หมายเลขโทรศัพท์, วางสาย, รับสาย |
// Cài đặt khi khởi tạo
AlohubPhone.init({ apiKey: '...', userName: '...', language: 'en' });
// Đổi ngôn ngữ runtime
phone.ui.setLanguage('ja');
// Custom ngôn ngữ riêng (ví dụ tiếng Đức)
phone.ui.setLanguage({
call: 'Anrufen',
hangup: 'Auflegen',
answer: 'Annehmen',
reject: 'Ablehnen'
// Các key thiếu sẽ fallback về tiếng Việt
});cd v3/
node build.js --dev # → dist/alohub-phone.dev.js
node build.js --prod # → dist/alohub-phone.prod.js
node build.js # → cả hai
# Minify (cần cài terser)
npm install terser
node build.js # → thêm dist/*.min.jsNếu website dùng CSP, thêm:
Content-Security-Policy:
connect-src wss://*.alohub.vn https://*.alohub.vn;
media-src blob:;
script-src 'self' https://cdn.alohub.vn;Không. SDK v3 chỉ hoạt động với tổng đài Alohub.
Gọi phone.requestMicPermission() để yêu cầu lại. Nếu đã bị block, user phải vào browser Settings > Site Settings > Microphone > bỏ block.
Có. SDK là vanilla JS, hoạt động trên mọi framework. Dùng headless: true rồi tích hợp vào component.
Lắng nghe event failed — trả về sipCode và sipReason (ví dụ: 480 "Temporarily Unavailable").
phone.unregister() (chỉ SIP) | phone.disconnect() (hoàn toàn) | phone.destroy() (hủy + xóa UI).
Có, thêm allow="microphone" vào thẻ <iframe>.
Mỗi instance SDK hỗ trợ 1 cuộc gọi. Cuộc gọi đến khi đang gọi sẽ emit event callWaiting và tự động từ chối.
AlohubPhone SDK v3 — Liên hệ Alohub — [email protected]