本文說明如何在 Android 應用程式中整合及自訂 SDK。
開始使用
Android 適用的無頭行動 SDK 可讓您將 CCAI 平台的客服中心功能整合到內建的 Android UI 中。
您不必顯示 CCAI 平台品牌的 Widget,而是:
將 CCAI Android SDK 模組新增為依附元件。
以 Kotlin (建議) 或 Java 建構自己的畫面、流程和視覺設計。
使用 SDK 執行下列操作:
開始及管理即時通訊和語音工作階段。
提供電子郵件、語音通話和轉移選項。
支援智慧動作、附件和會後流程 (客戶滿意度調查、問卷調查、虛擬服務專員)。
CCAI 平台會處理客服中心邏輯 (路徑、佇列、管道、設定、報表)。您擁有完整的應用程式體驗 (使用者介面、流程和品牌)。
如要使用可設定主題的預先建構 UI,請改用標準行動版 SDK。
需求條件和支援的環境
本節說明 Android 版無頭行動 SDK 的需求和支援環境。
Android 平台規定
Android 適用下列平台需求:
最低 Android 版本:Android 6.0 (API 級別 23) 以上版本
編譯 SDK:36 (建議)
支援的語言:Kotlin (建議) 或 Java
Java 相容性:Java 17 以上版本
Gradle / Android Studio:與應用程式和所用 SDK 版本相容的最新 Android Gradle 外掛程式和 Android Studio 版本
Kotlin 版本:1.6.0 以上
CCAI 平台執行個體需求條件
您需要存取 CCAI 平台執行個體的「開發人員設定」,才能取得下列資訊:
公司金鑰
公司密碼
主機網址:CCAI 平台的主機名稱 (例如 your_subdomain.ccaiplatform.com)
這些值可用於:
公司金鑰和主機網址:在 Android 應用程式中初始化 SDK。
公司密碼:在後端簽署 JSON Web Token (JWT),用於驗證使用者。
網路和權限
您的應用程式必須允許輸出流量前往 CCAI 平台端點,以及您設定的任何語音供應商端點。
常見的 Android 權限包括 (實際清單可能因 SDK 版本和功能集而異):
網際網路 / 網路狀態:用於所有 SDK 通訊。
麥克風:用於語音通話。
通知:適用於 Firebase 雲端通訊 (FCM) 推播通知。
儲存空間 / 媒體:用於附件。
相機:在智慧動作中拍攝相片或影片。
螢幕畫面擷取:用於分享螢幕畫面 (
MediaProjection)。
請按照 Android 作業系統指南宣告及要求執行階段權限。
推播通知
Headless Android SDK 會使用 FCM 傳送下列內容:
來電通知。
特定智慧動作和通話相關訊息。
更新:協助在應用程式背景執行時維持狀態。
你需要:
Firebase 專案。
應用程式模組中有效的 google-services.json。
在應用程式中處理及註冊 FCM 權杖。
應用程式中的自訂通知和通話使用者介面。
無頭 Android SDK 如何整合至應用程式
Android 適用的無頭行動 SDK 可視為三層:
CCAI 平台和 SDK (由 CCAI 平台處理)
SDK 會與 CCAI Platform 平台安全地互動,並提供下列功能:
使用 JSON Web Token (JWT) 進行驗證。
佇列和管道路徑中繼資料 (即時通訊、語音通話、電子郵件、外部轉向連結)。
使用服務物件 (
chatService、queueMenuService等) 管理即時工作階段狀態。智慧動作、檔案附件和螢幕分享的安全傳輸管道。
轉移邏輯和工作階段後階層評估。
Android 應用程式 (UI 和邏輯 - 由您處理)
你可以全面掌控視覺和導覽體驗:
進入點:例如「說明」分頁或「與我們聯絡」按鈕。
選單:顯示佇列的方式 (例如「帳單」、「技術支援」)。
通話期間的使用者介面:自訂訊息泡泡、通話畫面和控制項。
應用程式的用途:呼叫 SDK 服務 API 來啟動及結束工作階段、使用 Kotlin Coroutines 和 Flow 觀察 SDK 事件,以及驅動元件導覽。
CCAI 平台管理員入口網站設定
CCAI Platform 管理員會設定參與規則 (營業時間、可用管道、等待時間門檻和問卷調查)。SDK 會讀取這項設定,並以原始資料和事件的形式向應用程式公開。您決定如何在畫面上繪製該設定。
擷取公司憑證
整合 SDK 前,請先從 CCAI Platform 執行個體取得憑證:
使用管理員帳戶登入 CCAI 平台管理員入口。
依序前往「設定」>「開發人員設定」。
在「公司金鑰和密碼」下方,複製:
公司金鑰
公司密碼
記下 Host URL,也就是 CCAI 平台的主機名稱 (例如
your_subdomain.ccaiplatform.com)。
您將使用:
在 Android 應用程式中:公司金鑰和主機網址。
在後端伺服器中:公司密碼,用於簽署 JWT,以驗證使用者身分,以及 CCAI Platform 使用的選用自訂資料和環境。
將 SDK 新增至 Android 應用程式
Headless SDK 採用模組化架構,您會連同應用程式所需的特定功能模組 (例如 CCAIChat 或 CCAIScreenShare),一併安裝核心 CCAIKit。
新增 CCAI Maven 存放區
將 CCAI Maven 存放區新增至專案的 settings.gradle.kts (或根層級 build.gradle):
// settings.gradle.kts
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url = uri("https://sdk.ujet.co/ccaip/android/") }
}
}
設定 Gradle 版本目錄 (建議)
Google Cloud 建議使用 Gradle 版本目錄管理 SDK 依附元件。請將以下內容新增到 gradle/libs.versions.toml:
[versions]
ccaiVersion = "3.3.1"
[libraries]
ccai-kit = { group = "com.ccaiplatform.android", name = "CCAIKit", version.ref = "ccaiVersion" }
ccai-chat = { group = "com.ccaiplatform.android", name = "CCAIChat", version.ref = "ccaiVersion" }
ccai-chat-red = { group = "com.ccaiplatform.android", name = "CCAIChatRed", version.ref = "ccaiVersion" }
ccai-call = { group = "com.ccaiplatform.android", name = "CCAICall", version.ref = "ccaiVersion" }
ccai-call-red = { group = "com.ccaiplatform.android", name = "CCAICallRed", version.ref = "ccaiVersion" }
ccai-screenshare = { group = "com.ccaiplatform.android", name = "CCAIScreenShare", version.ref = "ccaiVersion" }
新增依附元件
在應用程式層級的 build.gradle.kts 中,新增核心 SDK 和特定功能模組:
// app/build.gradle.kts
android {
compileSdk = 36
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
dependencies {
// 1. Core (always required)
implementation(libs.ccai.kit)
// 2. Chat (required for chat sessions)
implementation(libs.ccai.chat)
implementation(libs.ccai.chat.red) // media layer paired with CCAIChat
// 3. Voice (required for instant calls, voicemail, and scheduled calls)
implementation(libs.ccai.call)
implementation(libs.ccai.call.red) // media/transport layer paired with CCAICall
// 4. Screen Share (optional)
// implementation(libs.ccai.screenshare)
}
如果未使用版本目錄,可以直接宣告依附元件:
val ccaiVersion = "3.3.1"
dependencies {
implementation("com.ccaiplatform.android:CCAIKit:$ccaiVersion")
implementation("com.ccaiplatform.android:CCAIChat:$ccaiVersion")
implementation("com.ccaiplatform.android:CCAIChatRed:$ccaiVersion")
implementation("com.ccaiplatform.android:CCAICall:$ccaiVersion") // Voice calls
implementation("com.ccaiplatform.android:CCAICallRed:$ccaiVersion") // Twilio VoIP backend
implementation("com.ccaiplatform.android:CCAIScreenShare:$ccaiVersion") // Optional, for screen share
}
初始化和設定
在應用程式啟動期間初始化 SDK。由於 SDK 採用模組化架構,請先初始化核心 CCAI 平台系統,然後註冊特定管道供應商 (例如 chat 或 screen share)。
實作 CCAIDelegate 介面
SDK 會使用 CCAIDelegate 介面進行驗證回呼。主要方法是 Kotlin 暫停函式 ccaiShouldAuthenticate(),SDK 需要 JWT 時會呼叫此函式。
import com.ccaiplatform.ccaikit.CCAIDelegate
class MyCCAIDelegate : CCAIDelegate {
/**
* Called by the SDK when it needs a signed JWT for authentication.
* This is a suspend function - you can make network calls here.
*
* @return The auth token returned by `authService.authenticate(jwt)`,
* or null on failure. This is what the SDK expects - not the raw JWT.
*/
override suspend fun ccaiShouldAuthenticate(): String? {
return try {
// 1. Call your backend server to get a signed JWT
val jwt = MyBackendApi.getSignedJwt() ?: return null
// 2. Exchange the JWT for an auth token using authService - this is
// what the SDK expects to be returned (not the raw JWT).
CCAI.authService?.authenticate(jwt)
} catch (e: Exception) {
null // Return null to signal authentication failure
}
}
}
上述程式碼片段顯示最簡單的兩步驟流程 (登入 → 驗證 → 傳回)。
- 如何在後端簽署 JWT,
authenticate(jwt)如何將其換成驗證權杖,- 權杖快取和失效,以及
- 提供錯誤處理的範例。
在應用程式類別中初始化 SDK
使用 CCAI 單例模式物件,在自訂應用程式類別中初始化 SDK:
import android.app.Application
import com.ccaiplatform.ccaikit.CCAI
import com.ccaiplatform.ccaikit.InitOptions
import com.ccaiplatform.ccaichat.initializeChat
import com.ccaiplatform.ccaichat.model.ChatOptions
import com.ccaiplatform.ccaicall.initializeCall
import com.ccaiplatform.ccaikit.initializeScreenShare
import com.ccaiplatform.ccaikit.models.screenShare.ScreenShareOptions
class MainApplication : Application() {
private val delegate = MyCCAIDelegate()
override fun onCreate() {
super.onCreate()
// 1. Build InitOptions
val initOptions = InitOptions(
key = "YOUR_COMPANY_KEY",
urlHost = "your_subdomain.ccaiplatform.com",
languageCode = "en", // Optional: ISO 639 code
delegate = delegate // Your delegate implementation
)
// 2. Initialize the core SDK
CCAI.initialize(
context = this,
options = initOptions
)
// 3. Initialize chat (minimal)
CCAI.initializeChat(context = this)
// Initialize chat (with optional configuration)
// val chatOptions = ChatOptions(
// webFormInterface = null, // Implement to intercept and render custom web forms within your own UI
// downloadTranscriptVisibility = DownloadTranscriptVisibility.SHOW_ALL,
// greeting = "Hello! How can I help you?"
// )
// CCAI.initializeChat(
// context = this,
// options = chatOptions
// )
// 4. Initialize call (required whenever your app uses voice or scheduled calls)
CCAI.initializeCall(context = this)
// 5. Initialize screen share (optional)
// CCAI.initializeScreenShare(
// context = this,
// options = ScreenShareOptions(
// key = "YOUR_COMPANY_KEY",
// domain = "your_subdomain.ccaiplatform.com"
// )
// )
}
}
InitOptions 設定參考資料
data class InitOptions(
/// The company key used for authentication
var key: String,
/// The host URL for CCAI platform (for example, "my-unique-instance.uc1.ccaiplatform.com")
var urlHost: String,
/// The preferred language code for localization (defaults to "en")
var languageCode: String? = "en",
/// Listener that handles authentication
var delegate: CCAIDelegate? = null,
/// Whether to cache the authentication token (defaults to true)
var cacheAuthToken: Boolean = true
)
更新「AndroidManifest.xml」
確認已註冊自訂應用程式類別:
<application
android:name=".MainApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.YourApp">
</application>
可用的 SDK 服務
初始化後,您就可以透過 CCAI 單例物件存取各種服務:
val authService = CCAI.authService
val companyService = CCAI.companyService
val queueMenuService = CCAI.queueMenuService
val optionsService = CCAI.optionsService
val languageService = CCAI.languageService
val pushNotificationService = CCAI.pushNotificationService
val chatService = CCAI.chatService // Only available after initializeChat()
val screenShareService = CCAI.screenShareService // Only available after initializeScreenShare()
val rateService = CCAI.rateService // For CSAT ratings and survey submission
val callService = CCAI.callService // Only available after initializeCall()
正在擷取公司設定
初始化後,您可以使用 companyService 擷取公司層級的設定。這項功能有助於填入語言選擇器、顯示公司名稱,或在使用者進入佇列前讀取支援聯絡資訊。
// Fetch company details
val company = CCAI.companyService?.get()
// CompanyResponse contains:
// - displayName: String
// - supportEmail: String?
// - languages: List<String>
// - phoneNumber: String?
// ...
驗證使用者身分並傳遞自訂資料
Android 適用的無頭行動裝置 SDK 會使用 JSON Web Token (JWT) 驗證使用者,並安全地將情境資訊傳遞至服務專員的 CRM。
運作方式
SDK 採用簡化的兩步驟非同步驗證流程:
SDK 判斷需要驗證使用者。
它會呼叫您的
CCAIDelegate方法 -ccaiShouldAuthenticate()- 這是暫停函式。應用程式會使用 `Company
應用程式會使用
Company Secret Code,在後端伺服器上遠端簽署 JWT。接著,應用程式會將簽署的 JWT 傳遞至
CCAI.authService?.authenticate(jwt),換取驗證權杖。系統會將驗證權杖傳回 SDK,完成連線。
實作 CCAIDelegate 進行驗證
應用程式必須實作 CCAIDelegate 介面。SDK 需要驗證時,會呼叫第一個暫停方法。
CCAIDelegate 介面
interface CCAIDelegate {
suspend fun ccaiShouldAuthenticate(): String?
}
導入範例 (Kotlin)
class CCAIDelegate : CCAIDelegate {
override suspend fun ccaiShouldAuthenticate(): String? {
// 1. Sign JWT remotely on your backend server
val jwt = signJWTRemotely() ?: return null
// 2. Authenticate JWT using authService to get an auth token
return try {
CCAI.authService?.authenticate(jwt)
} catch (e: Exception) {
null
}
}
}
完整範例,包含 JWT 簽署 (僅供參考和測試)
class AuthController : CCAIDelegate {
override suspend fun ccaiShouldAuthenticate(): String? {
// First, sign JWT with company secret (do this on your backend in production)
val jwt = Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS384, companySecret?.encodeToByteArray())
.compact()
// Then authenticate JWT using authService to get an auth token
return try {
CCAI.authService?.authenticate(jwt)
} catch (e: Exception) {
null
}
}
}
將自訂資料傳遞至 CRM
如要將情境資料傳遞給代理程式 (例如使用者的目前裝置 OS、位置或帳戶層級),後端必須先將 custom_data 物件插入 JWT 酬載,再簽署該酬載。
每筆自訂資料都必須格式化為 JSON 物件,內含標籤 (代理程式看到的內容)、值和類型。
支援的資料類型
string:標準文字 (例如「Pixel 8 Pro」)。number:整數或浮點數 (例如 1234 或 99.99)。date:13 位數的世界標準時間 Unix 時間戳記,包括毫秒 (例如 1537399655992)。url:標準 HTTP/HTTPS 網址格式。boolean:標準的 true 或 false 值。
服務專員可見度:您可以選擇將資料傳遞至 CCAI Platform 平台,這些資料會對真人服務專員隱藏,但可用於路徑或後端分析。如要這麼做,請在資料物件中加入 "invisible_to_agent": true。
保留的 CRM 金鑰
CCAI Platform 支援特定保留鍵,可觸發平台內建行為,例如將使用者標示為 VIP,或向服務專員發出惡意行為人警告。這些必須格式化為 boolean 型別,且只有在酬載使用安全的 JWT 方法簽署時,系統才會接受。
reserved_verified_customer:指出客戶是否已通過內部系統的驗證。reserved_bad_actor:向服務專員檢舉使用者為疑似垃圾內容或詐欺帳戶。reserved_repeat_customer:指出這位顧客最近是否經常與支援團隊聯絡。
含有保留鍵的酬載範例
{
"iat": 1537399656,
"exp": 1537400256,
"custom_data": {
"reserved_verified_customer": {
"label": "Verified Customer",
"value": true,
"type": "boolean"
},
"reserved_bad_actor": {
"label": "Bad Actor",
"value": false,
"type": "boolean"
},
"reserved_repeat_customer": {
"label": "Repeat Customer",
"value": false,
"type": "boolean"
}
}
}
管理驗證權杖
SDK 提供手動更新或清除快取驗證權杖的方法:
// Set a new auth token
CCAI.authService?.updateAuthToken("new_auth_token")
// Clear the current token (for example, on user logout)
CCAI.authService?.updateAuthToken(null)
自訂資料 JWT 酬載結構定義
後端建構要以 Company
Secret Code 簽署的最終酬載時,必須嚴格遵守這個結構定義。請注意強制性 iat (發行時間) 和 exp (到期時間) 時間戳記。
{
"iat": 1537399656,
"exp": 1537400256,
"custom_data": {
"os_version": {
"label": "OS Version",
"value": "14.0",
"type": "string"
},
"membership_tier": {
"label": "Membership Tier",
"value": "Platinum",
"type": "string"
},
"ssn_last_four": {
"label": "SSN",
"value": "1234",
"type": "string",
"invisible_to_agent": true
},
"reserved_verified_customer": {
"label": "Verified Customer",
"value": true,
"type": "boolean"
}
}
}
啟用推播通知
SDK 會使用推播通知執行下列操作:
來電。
特定智慧操作和通話相關事件。
在應用程式於背景執行時維持狀態。
Firebase 設定
建立或使用現有的 Firebase 專案。
註冊 Android 應用程式,並下載
google-services.json檔案。將
google-services.json放在應用程式模組目錄中。在根層級
build.gradle.kts中,新增 Google 服務外掛程式:// build.gradle.kts (Project) plugins { id("com.google.gms.google-services") version "4.4.2" apply false }在應用程式層級的
build.gradle.kts中,套用外掛程式並新增Firebase依附元件:// app/build.gradle.kts plugins { id("com.google.gms.google-services") } dependencies { // Firebase BoM for version management implementation(platform("com.google.firebase:firebase-bom:33.5.1")) implementation("com.google.firebase:firebase-messaging") }同步處理專案。
向 SDK 註冊 FCM 權杖
透過 pushNotificationService 註冊 FCM 推送權杖,並將傳入的 FCM 資料酬載轉送至 SDK。應用程式必須負責顯示任何面向消費者的通知或通話中 UI。
導入 onMessageReceived
如果您使用 FCM,請在 FirebaseMessagingService 類別中實作推播通知的監聽器。如果未導入這些項目,服務就無法正常運作。
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.ccaiplatform.ccaikit.CCAI
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class MyFirebaseMessagingService : FirebaseMessagingService() {
private val scope = CoroutineScope(Dispatchers.IO)
override fun onMessageReceived(remoteMessage: RemoteMessage) {
scope.launch {
// Forward CCAI platform push notifications to the SDK.
CCAI.pushNotificationService?.handlePushNotification(remoteMessage.data)
// Render any customer-facing notification UI in your own app code.
MyNotificationRenderer.showIfNeeded(application, remoteMessage.data)
}
}
}
導入 onNewToken
此外,請實作 onNewToken 方法來處理權杖更新。這樣可確保 Android 版 Headless Mobile SDK 收到最新的推播通知權杖:
class MyFirebaseMessagingService : FirebaseMessagingService() {
// ...
override fun onNewToken(token: String) {
// Fetch the updated token from Firebase and update it in CCAI
CCAI.pushNotificationService?.updatePushToken(token)
}
}
在 AndroidManifest.xml 中註冊服務
將 Firebase 訊息服務新增至 AndroidManifest.xml,讓系統能將推播訊息傳送至您的服務:
<application>
<service
android:name=".firebase.MyFirebaseMessagingService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
初始權杖註冊
在應用程式啟動時 (SDK 初始化後),主動註冊目前的 FCM 權杖:
import com.google.firebase.messaging.FirebaseMessaging
// In your Application.onCreate(), after CCAI.initialize()
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
if (task.isSuccessful) {
val token = task.result
CCAI.pushNotificationService?.updatePushToken(token)
}
}
處理通知權限 (Android 13 以上版本)
在 Android 13 (API 級別 33) 中,上述應用程式必須要求 POST_NOTIFICATIONS 執行階段權限。SDK 提供內建公用程式,可執行這項操作:
import com.ccaiplatform.ccaikit.util.PermissionUtil
// Request notification permissions from the user
PermissionUtil.requestPermissionsForNotifications(activity)
// Check if permissions have been granted
val isGranted = PermissionUtil.isPermissionsForNotificationsGranted(context)
if (isGranted) {
Log.d("CCAI", "Push notifications permitted")
}
在應用程式生命週期中盡早呼叫此函式 (例如在新手上路或首次啟動期間),然後再註冊 FCM 權杖,這樣才能傳送推播通知。