Skip to content

Hướng dẫn sử dụng

Hướng dẫn tích hợp VBot SDK trên Android.

Lắng nghe các sự kiện (Listener)

Kế thừa ClientListener (open class), override phương thức cần dùng rồi addListener:

kotlin
private var listener = object : ClientListener() {
    // Kết nối tài khoản thành công
    override fun onUserConnected(displayName: String) {
    }

    // Lắng nghe trạng thái đăng ký tài khoản
    override fun onAccountRegistrationState(status: AccountRegistrationState, reason: String) {
        // status: None, Ok, Error, Progress
    }

    // Lắng nghe các trạng thái cuộc gọi thay đổi
    override fun onCallState(state: CallState) {
        // state: Null, Calling, Incoming, Early, Connecting, Confirmed, Disconnected
    }

    // Nguyên nhân và bên kết thúc cuộc gọi
    override fun onCallEnded(reason: VBotEndCallReason, endedBy: VBotCallEndParty) {
        // reason.code / reason.key / reason.description
        // endedBy: caller, callee, system, server, carrier hoặc unknown
    }

    // Fire khi có cuộc gọi ĐẾN — dùng để map cuộc gọi với hệ thống của bạn
    override fun onExternalCallId(externalCallId: String) {
    }

    // Trạng thái mic thay đổi
    override fun onCallMuteStateChanged(muted: Boolean) {
    }

    // Mất kết nối socket
    override fun onNetworkUnreachable() {
    }

    // Lắng nghe lỗi phát sinh
    override fun onErrorCode(erCode: Int, message: String) {
    }
}

// Đăng ký lắng nghe sự kiện
client.addListener(listener)

// Hủy đăng ký lắng nghe sự kiện khi giải phóng
client.removeListener(listener)

addListener/removeListener an toàn thread. Có thể đăng ký nhiều listener.

Hotline

kotlin
// Lấy danh sách hotline (Hàm suspend, cần chạy trong CoroutineScope)
val hotlines = client.getHotlines()   // null → xem onErrorCode

// Trả về danh sách Hotline bao gồm:
// - name: Tên hotline
// - phoneNumber: Số điện thoại hotline

Gọi đi

Để thực hiện cuộc gọi đi, sử dụng hàm startOutgoingCall:

kotlin
val externalCallId = generateId() // tuỳ chọn, tối đa 32 ký tự [a-z0-9], để map với hệ thống của bạn
client.startOutgoingCall(hotline = "1900xxxx", phone = "0901234567", externalCallId = externalCallId) { _, error ->
    if (error != null) {
        // thất bại trước khi đổ chuông (vd: anotherCallInProgress)
    }
}

Trong đó:

  • hotline: Số hotline được sử dụng làm tổng đài gọi đi (có thể để rỗng nếu không dùng đầu số).
  • phone: Số điện thoại cần gọi.
  • externalCallId: id tuỳ chọn, gửi kèm header X-exc-id.
  • Completion VBotCompletion<Unit>tuỳ chọn — có overload không completion.
Lưu ý về giá trị externalCallId:
Giá trị externalCallId được truyền vào cần thỏa mãn các điều kiện sau:
  • Độ dài tối đa: 32 ký tự.
  • Chỉ sử dụng các ký tự chữ thường (az) và chữ số (09).
  • Không chứa các ký tự đặc biệt, chữ in hoa hoặc khoảng trắng.

Gọi đến

Khi nhận được payload cuộc gọi từ Firebase Cloud Messaging (FCM), bạn chuyển giao payload này cho SDK để hiển thị cuộc gọi đến (xem chi tiết ở mục Push Notification).

kotlin
// Đẩy payload cuộc gọi đến cho SDK xử lý (payload cần chứa key "transId" và "offCall")
client.notificationCall(payloadHashMap)

// Chấp nhận / Trả lời cuộc gọi đến
client.answerCall()

// Từ chối cuộc gọi đến (true = báo bận / Busy Here)
client.declineIncomingCall(isBusy = true)

Thao tác trong cuộc gọi

kotlin
// Kết thúc cuộc gọi hiện tại
client.endCall()

// Bật/Tắt micro (Mute)
client.muteCall(enable = true)
client.isCallMute()              // trạng thái mic

// Bật/Tắt loa ngoài (Speaker)
client.onOffSpeaker(enable = true)
client.isSpeakerOn()             // trạng thái loa

// Gửi phím DTMF
client.sendDTMF("1")

// Thời lượng cuộc gọi (giây) hoặc null
client.getDuration()

// Lấy thông tin URI/Tên người gọi đến
val remoteName = client.callName()

// Kiểm tra đang có cuộc gọi hoạt động không
client.hasActiveCall()

Xem thêm

VBotEndCallReason

Enum nguyên nhân kết thúc cuộc gọi, nhận qua onCallEnded(reason, endedBy). Truy cập giá trị số qua reason.code, tên ổn định qua reason.key và mô tả qua reason.description. endedByVBotCallEndParty (caller, callee, system, server, carrier, unknown).

CasecodeÝ nghĩa
normaly1000Cuộc gọi kết thúc bình thường
busy1001Máy bận
timeOut1004Hết thời gian chờ kết nối
noPushToken1018Chưa đăng ký push notification
notReadyForStartCall2002Chưa sẵn sàng để gọi đi / khởi tạo không thành công
invalidPhoneNumber2004Số điện thoại không hợp lệ
noDataFromServer2005Không có dữ liệu từ máy chủ
endCallBeforeServerStartCall2006Cuộc gọi kết thúc khi chưa kết nối
noCallCreated2007Lỗi khi khởi tạo cuộc gọi
dataInvalid2008Dữ liệu không hợp lệ
noVBotUser2009Không tìm thấy thông tin tài khoản
authenticatedFailed2010Xác thực thất bại
anotherCallInProgress2011Đang có cuộc gọi khác
decline2013Từ chối cuộc gọi
temporarilyUnavailable2014Không liên lạc được
reportNewIncomingCallFailed2016Không thể tiếp nhận cuộc gọi đến
alertDataNotFound2017Dữ liệu thông báo không hợp lệ
setupEndpointFailed2019Khởi tạo dịch vụ gọi thất bại
requestCallKitActionFailed2020Thực thi hành động cuộc gọi thất bại
noAccount2022Tài khoản chưa được cấu hình
incomingCallTimeout2023Cuộc gọi đến hết thời gian chờ
incorrectInformation2024Thông tin không chính xác
unauthenticated2025Chưa xác thực
insufficientBalance2026Số dư không đủ
recipientBlocksCalls2027Người nhận chặn cuộc gọi
destinationNotFound2028Không tìm thấy số đích
callIntervalNotAllowed2029Không được phép gọi trong khung giờ này
memberNotActivated2030Thành viên chưa kích hoạt
memberNotInProject2031Thành viên không thuộc dự án
doNotDisturb2032Không làm phiền
destinationGone2033Số đích không còn tồn tại
recipientAbsent2034Người nhận vắng mặt
packageExpired2035Gói cước đã hết hạn
hotlineTelcoNotSupported2036Hotline không hỗ trợ nhà mạng
telcoNotFound2037Không tìm thấy nhà mạng
invalidParameter2038Tham số không hợp lệ
projectExpired2039Dự án đã hết hạn
callerCanceled2040Người gọi đã hủy
connectionError2041Lỗi kết nối
transmissionError2042Lỗi đường truyền
unknownError9996Lỗi chưa xác định
microphonePermissionDenied9999Chưa cấp quyền microphone
kotlin
override fun onCallEnded(reason: VBotEndCallReason, endedBy: VBotCallEndParty) {
    when (reason) {
        VBotEndCallReason.normaly -> {
            // Cuộc gọi kết thúc bình thường
        }
        VBotEndCallReason.busy,
        VBotEndCallReason.decline,
        VBotEndCallReason.temporarilyUnavailable -> {
            // Đầu bên kia không nhận cuộc gọi
        }
        else -> {
            Log.d("VBot", "Cuộc gọi kết thúc: ${reason.key}, bởi ${endedBy.key}")
        }
    }
}
SIPendedBy
400–402, 405–408, 412–413, 416, 500server
403, 409, 411, 486, 603callee
404, 410, 414, 480, 502carrier
415system
487caller

VBotError

Lỗi trả về qua completion của các hàm connect, disconnect, startOutgoingCall:

kotlin
class VBotError(val code: Int, val message: String)

Với startOutgoingCall, code trùng giá trị code trong bảng VBotEndCallReason ở trên. Với các hàm gọi API máy chủ, code là mã lỗi API trả về.

kotlin
client.startOutgoingCall(hotline = "1900xxxx", phone = "0901234567") { _, error ->
    if (error == null) return@startOutgoingCall

    if (error.code == VBotEndCallReason.anotherCallInProgress.code) {
        // Đang có cuộc gọi khác
    }
    Log.d("VBot", "Gọi đi thất bại: ${error.message}")
}

Đối chiếu với iOS SDK

VBotEndCallReason trên Android dùng cùng tên case và cùng bộ mã số với iOS SDK, nên logic xử lý mã lỗi dùng chung được cho cả hai nền tảng.