Phone SDKTích hợp Webrtc Phone

Tích hợp Webrtc Phone

Admin·5/5/2026

Hướng dẫn tích hợp WebRTC phone

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.

Mục lục

  1. Tổng quan

  2. Yêu cầu trước khi bắt đầu

  3. Cài đặt SDK

  4. Tích hợp cơ bản (5 phút)

  5. Giao diện Widget

  6. Tích hợp nâng cao — Headless Mode

  7. Tích hợp CRM — Click-to-Call

  8. Xử lý lỗi

  9. Microphone & Quyền truy cập

  10. Các tính năng trong cuộc gọi

  11. Đa ngôn ngữ

  12. Build & Triển khai

  13. Câu hỏi thường gặp

1. Tổng quan

AlohubPhone SDK v3 là gì?

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.

2. Yêu cầu trước khi bắt đầu

Tài khoản Alohub

Bạn cần có:

  • API KeyLiê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 kỹ thuật

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.

3. Cài đặt SDK

Cách 1: CDN (khuyên dùng)

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>

Cách 2: Tự host

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>

Sự khác biệt giữa Dev và Prod

File

Server

Mục đích

.dev.js

{{protocol}}://{{host}}:{{port}} (dev)

Test, phát triển

.prod.js

{{protocol}}://{{host}} (prod)

Production

4. Tích hợp cơ bản (5 phút)

Bước 1: Thêm SDK vào trang

Đặ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>

Bước 2: Widget tự động xuất hiện

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 đủ

Bước 3: Tùy chỉnh giao diện + xử lý lỗi

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);
  }
});

Vị trí widget

Giá trị

Vị trí

bottom-right

Góc dưới bên phải (mặc định)

bottom-left

Góc dưới bên trái

top-right

Góc trên bên phải

top-left

Góc trên bên trái

5. Giao diện Widget

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"

Trạng thái thanh header

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

6. Tích hợp nâng cao — Headless Mode

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);
    });
  }
});

So sánh 2 chế độ

Có Widget (mặc định)

Headless

Giao diện

Widget tự động

Bạn tự code

DTMF / Mute / Hold

Có trên widget

phone.sendDTMF(), phone.mute(), ...

Events

Đầy đủ

Đầy đủ (giống nhau)

phone.ui

null

7. Tích hợp CRM — Click-to-Call

<!-- 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>

8. Xử lý lỗi

Luồng xử lý lỗi

SDK cung cấp 3 lớp bắt lỗi:

  1. 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

  2. .catch(err) — SIP registration thất bại: REGISTRATION_FAILED, REGISTRATION_TIMEOUT

  3. phone.on('error', fn) — Tất cả lỗi runtime: MIC_NOT_FOUND, MIC_DENIED, CALL_MEDIA_FAILED, CALL_NO_NUMBER, CALL_NOT_READY, ...

Code xử lý lỗi

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"
});

Bảng mã lỗi

Mã lỗi

Nhóm

Mô tả

MIC_NOT_FOUND

mic

Không có microphone

MIC_DENIED

mic

Mic bị từ chối

CALL_MEDIA_FAILED

mic

Mic lỗi khi gọi (JsSIP getusermediafailed)

CALL_NO_NUMBER

call

Thiếu số điện thoại

CALL_NOT_READY

call

Chưa đăng ký SIP

DTMF_INVALID

dtmf

Ký tự DTMF không hợp lệ

TRANSFER_NO_CALL

transfer

Transfer khi không có cuộc gọi

API_CALL_FAILED

api

Gọi qua API thất bại

SIP Error Codes phổ biến

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

9. Microphone & Quyền truy cập

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.

10. Các tính năng trong cuộc gọi

Nhóm

Method

Mô tả

Gọi

phone.call(num, opts?)

Gọi ra (opts: {extraHeaders: [...]})

phone.answer()

Nghe máy

phone.hangup()

Kết thúc / từ chối

DTMF

phone.sendDTMF(tone)

Gửi phím bấm (0-9, *, #, A-D)

Mic

phone.mute() / unmute()

Tắt/bật mic

phone.toggleMute()

Đảo trạng thái

Hold

phone.hold() / unhold()

Giữ máy / tiếp tục

phone.toggleHold()

Đảo trạng thái

Transfer

phone.transfer(target)

Chuyển cuộc gọi (blind transfer)

Trạng thái

phone.isOnCall()

Đang gọi?

phone.isMuted()

Mic đang tắt?

phone.isHeld()

Đang giữ máy?

phone.getCallInfo()

Chi tiết cuộc gọi

Kết nối

phone.unregister()

Logout SIP (giữ WebSocket)

phone.disconnect()

Ngắt hoàn toàn

phone.destroy()

Hủy instance + xóa UI + xóa credentials

11. Đa ngôn ngữ

Code

Ngôn ngữ

Ví dụ giao diện

vi

Tiếng Việt (mặc định)

Số điện thoại, Kết thúc, Nghe máy

en

English

Phone Number, Hang Up, Answer

ja

日本語

電話番号, 終了, 応答

ko

한국어

전화번호, 종료, 받기

zh

中文

电话号码, 挂断, 接听

th

ภาษาไทย

หมายเลขโทรศัพท์, วางสาย, รับสาย

// 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
});

12. Build & Triển khai

Build từ source

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.js

CSP (Content Security Policy)

Nế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;

13. Câu hỏi thường gặp

Q: SDK có hoạt động với tổng đài khác không?

Không. SDK v3 chỉ hoạt động với tổng đài Alohub.

Q: Microphone bị từ chối thì sao?

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.

Q: Có hỗ trợ React / Vue / Angular không?

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.

Q: Cuộc gọi thất bại vì lý do gì?

Lắng nghe event failed — trả về sipCodesipReason (ví dụ: 480 "Temporarily Unavailable").

Q: Làm sao logout?

phone.unregister() (chỉ SIP) | phone.disconnect() (hoàn toàn) | phone.destroy() (hủy + xóa UI).

Q: Dùng được trong iframe không?

Có, thêm allow="microphone" vào thẻ <iframe>.

Q: Có giới hạn số cuộc gọi đồng thời không?

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 v3Liên hệ Alohub[email protected]

Bài viết này có hữu ích không?
Cập nhật: 5/5/2026