Este documento explica como integrar e personalizar o SDK no seu app Android.
Primeiros passos
O SDK para dispositivos móveis sem interface para Android permite integrar os recursos de central de atendimento da plataforma CCAI à sua própria interface do Android.
Em vez de apresentar um widget com a marca da CCAI Platform, você:
Adicione os módulos do SDK do Android do CCAI como dependências.
Crie suas próprias telas, fluxos e design visual em Kotlin (recomendado) ou Java.
Use o SDK para:
Inicie e gerencie sessões de chat e voz.
Ofereça opções de e-mail, ligação e desvio.
Oferecer suporte a ações inteligentes, anexos e fluxos pós-sessão (CSAT, pesquisas, agente virtual).
A plataforma CCAI lida com a lógica da central de atendimento (roteamento, filas, canais, configuração, relatórios). Você é responsável por toda a experiência no app (UI, fluxos e branding).
Se você preferir uma UI pré-criada com temas configuráveis, use o SDK padrão para dispositivos móveis.
Requisitos e ambientes compatíveis
Nesta seção, descrevemos os requisitos e os ambientes compatíveis com o SDK para dispositivos móveis sem interface para Android.
Requisitos da plataforma Android
Os seguintes requisitos de plataforma se aplicam ao Android:
Versão mínima do Android: Android 6.0 (nível 23 da API) ou mais recente
SDK de compilação: 36 (recomendado)
Linguagens compatíveis: Kotlin (recomendado) ou Java
Compatibilidade com Java: Java 17+
Gradle / Android Studio: uma versão recente do Plug-in do Android para Gradle e do Android Studio compatível com seu app e a versão do SDK que você está usando.
Versão do Kotlin: 2.0 ou mais recente
Requisitos de instância da plataforma CCAI
Você vai precisar acessar as configurações de desenvolvedor da instância da plataforma CCAI para receber:
Chave da empresa
Código secreto da empresa
URL do host: o nome do host da plataforma CCAI (por exemplo, your_subdomain.ccaiplatform.com)
Esses valores são usados para:
Chave da empresa e URL do host: no app Android para inicializar o SDK.
Código secreto da empresa: no back-end para assinar JSON Web Tokens (JWT) usados para autenticar usuários.
Rede e permissões
Seu app precisa permitir o tráfego de saída para os endpoints da plataforma CCAI e todos os endpoints de provedores de voz que você configurou.
As permissões típicas do Android incluem (a lista real pode variar de acordo com a versão do SDK e seu conjunto de atributos):
Estado da Internet / rede: para todas as comunicações do SDK.
Microfone: para ligações.
Notificações: somente se você usar notificações push (consulte Notificações push abaixo).
Armazenamento / mídia: somente se o app ler fotos, vídeos ou arquivos do armazenamento compartilhado diretamente. Os arquivos do app e o seletor de fotos do sistema não precisam de permissão.
Câmera: para capturar fotos ou vídeos em ações inteligentes.
Captura de tela: para compartilhamento de tela (
MediaProjection).
Declare e solicite permissões de execução de acordo com as diretrizes do SO Android.
Notificações push
O SDK do Android sem interface usa o FCM para enviar:
Notificações de chamadas recebidas.
Algumas mensagens relacionadas a chamadas e ações inteligentes.
Atualizações para ajudar a manter o estado quando o app está em segundo plano.
Você precisará dos seguintes itens:
um projeto do Firebase;
Um google-services.json válido no módulo do app.
Processamento e registro de tokens do FCM no app.
Notificação personalizada e UI de chamada no app.
Como o SDK do Android headless se encaixa no seu app
O SDK para Dispositivos Móveis Headless para Android pode ser visto como três camadas:
Plataforma e SDK da CCAI Platform (processados pela CCAI Platform)
O SDK interage de forma segura com a CCAI Platform e oferece:
Autenticação com JSON Web Tokens (JWT).
Metadados de roteamento de fila e canal (chat, ligação, e-mail, links de desvio externo).
Gerenciamento de estado de sessão em tempo real usando objetos de serviço (
chatService,queueMenuServicee muito mais).O pipeline de transporte seguro para ações inteligentes, anexos de arquivos e compartilhamento de tela.
Lógica de desvio e avaliação de hierarquia pós-sessão.
Seu app Android (UI e lógica, processados por você)
Você controla toda a experiência visual e de navegação:
Pontos de entrada: por exemplo, uma guia Ajuda ou um botão Entre em contato.
Menus: como você mostra as filas (por exemplo, Faturamento, Suporte técnico).
Interface na sessão: seus balões de diálogo, telas de chamada e controles personalizados.
O que o app faz: chama as APIs de serviço do SDK para iniciar e encerrar sessões, observa eventos do SDK usando corrotinas e fluxo do Kotlin e orienta a navegação de componentes.
Configuração do portal de administração da plataforma CCAI
Os administradores da plataforma CCAI configuram as regras de engajamento (horário de funcionamento, canais disponíveis, limites de tempo de espera e pesquisas). O SDK lê essa configuração e a expõe ao app como dados brutos e eventos. Você decide como desenhar essa configuração na tela.
Recuperar credenciais da empresa
Antes de integrar o SDK, consiga as credenciais da sua instância da plataforma CCAI:
Faça login no portal de administração da CCAI Platform com uma conta de administrador.
Acesse Configurações > Configurações do desenvolvedor.
Em Chave da empresa e código secreto, copie:
Chave da empresa
Código secreto da empresa
Anote o URL do host, que é o nome do host da plataforma CCAI (por exemplo,
your_subdomain.ccaiplatform.com).
Você usará:
No app Android: Chave da empresa e URL do host.
No servidor de back-end: código secreto da empresa para assinar JWTs para autenticação do usuário final e dados e contexto personalizados opcionais usados pela plataforma da CCAI.
Adicionar o SDK ao app Android
O SDK Headless usa uma arquitetura modular. Instale o CCAIKit principal
com os módulos de recursos específicos que o app exige (por exemplo,
CCAIChat ou CCAIScreenShare).
Adicionar o repositório Maven da CCAI
Adicione o repositório Maven da CCAI ao settings.gradle.kts (ou build.gradle raiz) do seu projeto:
// settings.gradle.kts
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url = uri("https://sdk.ujet.co/ccaip/android/") }
}
}
Configurar o catálogo de versões do Gradle (recomendado)
OGoogle Cloud recomenda o uso de um catálogo de versões do Gradle para gerenciar dependências
do SDK. Adicione o seguinte ao gradle/libs.versions.toml:
[versions]
ccaiVersion = "3.5.0"
[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" }
Adicionar dependências
No build.gradle.kts do app, adicione o SDK principal e os módulos de recursos
específicos:
// 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)
}
Se você não estiver usando o catálogo de versões, declare as dependências diretamente:
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
}
Inicialização e configuração
Inicialize o SDK durante o lançamento do app. Devido à arquitetura modular do SDK,
inicialize primeiro o sistema principal da CCAI Platform e, em seguida, registre os
provedores de canais específicos (como chat ou screen share).
Implementar a interface CCAIDelegate
O SDK usa uma interface CCAIDelegate para callbacks de autenticação. O método
principal é uma função de suspensão do Kotlin ccaiShouldAuthenticate() que o SDK
chama quando precisa de um JWT.
import com.ccaiplatform.ccaikit.CCAI
import com.ccaiplatform.ccaikit.CCAIDelegate
import kotlinx.coroutines.CancellationException
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: CancellationException) {
throw e
} catch (e: Throwable) {
// Includes NetworkError, which extends Error rather than Exception
null // Return null to signal authentication failure
}
}
}
O snippet anterior mostra o fluxo mínimo de duas etapas (assinar → autenticar → retornar).
Consulte Autenticar usuários finais e transmitir dados personalizados para ver o contrato de autenticação completo, incluindo:
- como assinar o JWT no back-end,
- como o
authenticate(jwt)o troca por um token de autenticação, - armazenamento em cache e invalidação de tokens, além de
- exemplos práticos com tratamento de erros.
Inicializar o SDK na classe do aplicativo
Inicialize o SDK na sua classe Application personalizada usando o objeto singleton
CCAI:
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.ccaiscreenshare.initializeScreenShare // If using screen share
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",
delegate = delegate // Your CCAIDelegate implementation
)
// 2. Initialize the Core SDK
CCAI.initialize(
context = this,
options = initOptions
)
// Optional: set the SDK language (ISO 639 code). See Languages and localization
// in Headless Mobile SDK v3 for Android: Advanced Topics, Localization, and Post-Session Flows.
CCAI.languageService?.languageCode = "en"
// 3. Initialize Chat - minimal
CCAI.initializeChat(context = this)
// Initialize Chat - with optional configuration
// val chatOptions = ChatOptions(
// webFormHandler = null, // Optional suspend handler that renders web forms in your own UI
// downloadTranscriptVisibility = DownloadTranscriptVisibility.SHOW_ALL
// )
// To set a chat greeting, pass Chat(greeting = ...) in the ChatRequest
// 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_SCREEN_SHARE_LICENSE_KEY", // License Key (Settings > Developer Settings > Screen Share)
// domain = "https://your-screen-share-domain.example.com" // Optional: the Screen Share Domain URL
// )
// )
}
}
Referência de configuração do 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
)
Atualizar AndroidManifest.xml
Verifique se a classe de aplicativo personalizada está registrada:
<application
android:name=".MainApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.YourApp">
</application>
Serviços do SDK disponíveis
Após a inicialização, é possível acessar vários serviços pelo objeto singleton
CCAI:
val authService = CCAI.authService
val companyService = CCAI.companyService
val queueMenuService = CCAI.queueMenuService
val languageService = CCAI.languageService
val pushNotificationService = CCAI.pushNotificationService
val smartActionService = CCAI.smartActionService
val endUserService = CCAI.endUserService
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()
Buscar configuração da empresa
Após a inicialização, é possível buscar a configuração no nível da empresa usando o
companyService. Isso é útil para preencher seletores de idioma, exibir o nome da empresa ou ler os detalhes de contato do suporte antes que o usuário entre em uma fila.
// Fetch company details
val company = CCAI.companyService?.get()
// CompanyResponse contains:
// - displayName: String?
// - supportEmail: String?
// - languages: List<LanguageSetting>? (each with lang, name, and enabled)
// - phoneNumber: String?
// ...
Autenticar usuários finais e transmitir dados do cliente
O SDK para dispositivos móveis sem interface para Android usa JSON Web Tokens (JWT) para autenticar usuários e transmitir informações contextuais com segurança para o CRM do agente.
Como funciona
O SDK usa um fluxo de autenticação assíncrona simplificado em duas etapas:
O SDK determina que precisa autenticar o usuário.
Ele chama o método
CCAIDelegate,ccaiShouldAuthenticate(), que é uma função de suspensão.Seu app chama o servidor de back-end para receber um JWT assinado.
Em seguida, o app transmite o JWT assinado para
CCAI.authService?.authenticate(jwt)para trocá-lo por um token de autenticação.O token de autenticação é retornado ao SDK para concluir a conexão.
Implementar o CCAIDelegate para autenticação
O app precisa implementar a interface CCAIDelegate. O SDK chama o primeiro
método de suspensão quando precisa de autenticação.
Interface CCAIDelegate
interface CCAIDelegate {
suspend fun ccaiShouldAuthenticate(): String?
}
Exemplo de implementação (Kotlin)
class MyCCAIDelegate : 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: CancellationException) {
throw e
} catch (e: Throwable) {
// Includes NetworkError, which extends Error rather than Exception
null
}
}
}
Transmitir dados do cliente para o CRM
Se você quiser transmitir dados de contexto ao agente (por exemplo, o SO do dispositivo atual do usuário, a localização ou o nível da conta), seu back-end precisará injetar um objeto custom_data no payload do JWT antes de assiná-lo.
Cada dado personalizado precisa ser formatado como um objeto JSON que contém um
rótulo (o que o agente vê), um valor e um tipo.
Tipos de dados compatíveis
string: texto padrão (por exemplo, "Pixel 8 Pro").number: números inteiros ou flutuantes (por exemplo, 1234 ou 99,99).date: um carimbo de data/hora Unix UTC de 13 dígitos, incluindo milissegundos (por exemplo, 1537399655992).url: formato de URL HTTP/HTTPS padrão.boolean: valor padrão verdadeiro ou falso.
Visibilidade do agente: é possível transmitir dados para a plataforma CCAI
que ficam ocultos para o agente humano, mas disponíveis para roteamento ou
análise de back-end. Para fazer isso, inclua "invisible_to_agent": true no
objeto de dados.
Chaves de CRM reservadas
A CCAI Platform é compatível com chaves reservadas específicas que acionam comportamentos
integrados na plataforma, como sinalizar um usuário como VIP ou avisar um agente
sobre um usuário mal-intencionado. Eles precisam ser formatados como tipos boolean e só serão
aceitos se o payload for assinado usando o método seguro JWT.
reserved_verified_customer: indica se um cliente foi autenticado pelos seus sistemas internos.reserved_bad_actor: sinaliza o usuário para o agente como um possível criador de spam ou conta fraudulenta.reserved_repeat_customer: indica se o cliente entrou em contato com o suporte com frequência recentemente.
Exemplo de payload com chaves reservadas
{
"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"
}
}
}
Gerenciar tokens de autenticação
O SDK oferece métodos para atualizar ou limpar manualmente o token de autenticação armazenado em cache:
// Set a new auth token
CCAI.authService?.updateAuthToken("new_auth_token")
// Clear the current token (for example, on user logout)
CCAI.authService?.updateAuthToken(null)
Esquema de payload do JWT de dados do cliente
Quando o back-end cria o payload final a ser assinado com seu Company
Secret Code, ele precisa seguir estritamente esse esquema. Observe os carimbos de data/hora obrigatórios iat
(emitido em) e exp (expiração).
{
"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"
}
}
}
Ativar notificações push
O SDK usa notificações push para:
Chamadas recebidas.
Determinadas ações inteligentes e eventos relacionados a chamadas.
Manter o estado quando o app está em segundo plano.
Configuração do Firebase
Crie ou use um projeto do Firebase.
Registre seu app Android e faça o download do arquivo
google-services.json.Coloque
google-services.jsonno diretório do módulo do app.No arquivo
build.gradle.ktsno nível raiz, adicione o plug-in dos serviços do Google:// build.gradle.kts (Project) plugins { id("com.google.gms.google-services") version "4.4.2" apply false }No
build.gradle.ktsdo app, aplique o plug-in e adicione as dependênciasFirebase:// 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") }Sincronize o projeto.
Registrar o token do FCM com o SDK
Registre o token de push do FCM pelo pushNotificationService e encaminhe
os payloads de dados do FCM recebidos para o SDK. Seu app é responsável por renderizar qualquer
notificação voltada ao cliente ou UI durante a chamada.
Implementar onMessageReceived
Se você estiver usando o FCM, implemente um listener na classe FirebaseMessagingService
para notificações push. Se eles não forem implementados, o serviço não vai funcionar corretamente.
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)
}
}
}
Implementar onNewToken
Implemente também o método onNewToken para processar atualizações de token. Isso garante
que o SDK para dispositivos móveis sem interface para Android receba o token de notificação push
mais recente:
class MyFirebaseMessagingService : FirebaseMessagingService() {
// ...
override fun onNewToken(token: String) {
// Fetch the updated token from Firebase and update it in CCAI
CCAI.pushNotificationService?.updatePushToken(token)
}
}
Registre o serviço em AndroidManifest.xml.
Adicione o serviço de mensagens do Firebase ao AndroidManifest.xml para que o sistema
possa enviar mensagens push ao seu serviço:
<application>
<service
android:name=".firebase.MyFirebaseMessagingService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
Registro inicial do token
Na inicialização do app (após a inicialização do SDK), registre proativamente o token atual do 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)
}
}
Tratamento de permissões de notificação (Android 13 ou mais recente)
No Android 13 (nível 33 da API) e versões mais recentes, o app precisa da permissão de execução POST_NOTIFICATIONS
para mostrar notificações. O SDK oferece um utilitário integrado
para solicitar essa permissão:
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")
}
Chame isso no início do ciclo de vida do app (por exemplo, durante a integração ou o primeiro lançamento) antes de registrar o token do FCM para que as notificações push possam ser enviadas.