Esta página explica como usar o SDK do Android.
Acessar o app de exemplo
Para baixar o app de exemplo do Android, clique em App de exemplo do Android.
Para criar um app de exemplo usando o SDK para dispositivos móveis do Android, você precisa do seguinte:
Chave e secret da empresa no portal da plataforma CCAI.
Android 5.0 (nível 21 da API, Lollipop) ou mais recente.
Firebase Cloud Messaging ou Google Cloud Messaging para a notificação push.
O app foi migrado para o AndroidX.
Requisitos de upgrade do SDK do Twilio
Exige que o SDK do Twilio siga versões específicas se o SDK do Android for integrado diretamente usando nosso pacote. Caso contrário, isso pode ser ignorado.
// Twilio VoIP SDK
api 'com.twilio:voice-android:6.1.1'
// Twilio Conversations SDK
api 'com.twilio:conversations-android:3.1.0'
Além disso, as regras do ProGuard já estão incluídas no SDK do Android para garantir que a biblioteca Twilio Programmable Voice não seja removida pelo ProGuard e possa ser usada para resolver problemas caso o ProGuard remova a biblioteca por acidente.
-keep class com.twilio.** { *; }
-keep class tvo.webrtc.** { *; }
-dontwarn tvo.webrtc.**
-keep class com.twilio.voice.** { *; }
-keepattributes InnerClasses
Para oferecer suporte às versões mais recentes do Twilio, a partir da versão 0.34.0 do SDK do Android, o SDK não é mais compatível com aplicativos destinados ao Java 7. Para usar esta e as próximas versões, os desenvolvedores precisam fazer upgrade dos aplicativos para o Java 8. Confira o exemplo de código abaixo:
android {
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
Receber a chave e o secret da empresa
Faça login no Admin Portal usando as credenciais de administrador.
Acesse Configurações > Configurações do desenvolvedor > Chave da empresa e código secreto.
Recupere o token da empresa e o código secreto da empresa.
Instalação
Adicione o repositório do SDK do Android à configuração do Gradle para o projeto raiz.
build.gradle (projeto)
allprojects {
repositories {
google()
jcenter()
maven {
url "https://sdk.ujet.co/android/"
}
}
}
build.gradle (módulo: app)
dependencies {
// Replace x.y.z with latest version of CCAI Platform SDK
def ujetSdkVersion = "x.y.z"
implementation "co.ujet.android:ujet-android:$ujetSdkVersion"
// CCAI Platform supports co-browse for Web SDK version 0.46.0 or
// higher.
// To use co-browse, declare the following dependency.
implementation "co.ujet.android:cobrowse:$ujetVersion"
}
Configurar as configurações da empresa
Insira as configurações da empresa como metadados no arquivo AndroidManifest.xml.
AndroidManifest.xml
<application>
// ...
<!-- Company Settings -->
<meta-data android:name="co.ujet.android.subdomain" android:value="@string/ujet_subdomain"/>
<meta-data android:name="co.ujet.android.companyKey" android:value="@string/ujet_company_key"/>
<meta-data android:name="co.ujet.android.companyName" android:value="@string/ujet_company_name"/>
// ...
</application>
strings.xml
<resources>
<string name="ujet_subdomain">YOUR_SUBDOMAIN</string>
<string name="ujet_company_key">YOUR_COMPANY_KEY</string>
<string name="ujet_company_name">YOUR_COMPANY_NAME</string>
</resources>
Assinatura JWT
As informações de um usuário final precisam ser assinadas como JWT no seu servidor por motivos de segurança.
O app de exemplo contém APIManager para testes. Você precisa colocar UJET_COMPANY_SECRET em mock/APIManager.java. O APIManager precisa implementar um método que inicia uma chamada assíncrona para assinar o token de autenticação JWT e retornar o token.
Em produção, é necessário implementar o processo de assinatura no servidor.
public class APIManager {
public static final String UJET_COMPANY_SECRET = "Please input your UJET_COMPANY_SECRET from Ujet developer admin page";
// ...
}
Inicializar o SDK
Inicialize o SDK no método onCreate da classe de aplicativo Android.
public class ExampleApplication extends Application implements UjetRequestListener {
@Override
public void onCreate() {
super.onCreate();
Ujet.init(this);
}
// ...
}
Autenticação de usuário final
O usuário final é o consumidor que entra em contato com sua equipe de suporte ao cliente pelo aplicativo.
Para autenticar o usuário final no aplicativo, apresentamos um mecanismo de assinatura JWT.
O SDK do Android pede para assinar o payload quando precisa de autenticação. Se a assinatura for bem-sucedida, o aplicativo vai trocar o JWT assinado pelo token de autenticação do usuário final.
Em ExampleApplication, implemente a interface UjetRequestListener
para assinar o token de autenticação e dados personalizados.
public class ExampleApplication extends Application implements UjetRequestListener {
@Override
public void onCreate() {
super.onCreate();
Ujet.init(this);
}
@Override
public void onSignPayloadRequest(Map<String, Object> payload, UjetPayloadType ujetPayloadType, UjetTokenCallback tokenCallback) {
if (ujetPayloadType == UjetPayloadType.AuthToken) {
// In production, you should implement this on your server.
// The server must implement a method that initiates an asynchronous call
to sign and return a JWT auth token.
APIManager.getHttpManager()
.getAuthToken(payload, UjetPayloadType.AuthToken, new UjetTokenCallback() {
@Override
public void onSuccess(@Nullable final String authToken) {
tokenCallback.onToken(authToken);
}
@Override
public void onFailure(@Nullable final String authToken) {
tokenCallback.onError();
}
});
}
}
}
Para mais informações, consulte autenticação de usuário final.
Configurar notificações push
Nesta seção, você vai aprender a ativar as notificações push em dispositivos móveis.
Preparar o Firebase
Prepare um projeto do Firebase.
Se você já tiver um projeto, use o seu e pule este processo.
Crie um projeto do Firebase no Console do Firebase.
Faça o download do google-services.json em Configurações > GERAL no Console do Firebase.

- Acesse Configurações > CLOUD MESSAGING no console do Firebase para encontrar a chave do servidor.

Adicionar uma chave de conta de serviço
É necessário adicionar uma chave de conta de serviço ao app para dispositivos móveis para receber notificações push. Para receber uma chave de conta de serviço, consulte Autenticar com uma conta de serviço.
Para adicionar uma chave de conta de serviço ao seu app para dispositivos móveis, siga estas etapas:
No portal da plataforma CCAI, clique em Configurações > Configurações do desenvolvedor. Se o menu Configurações não aparecer, clique em Menu.
Acesse o painel Apps para dispositivos móveis.
Clique em Editar ao lado do app. A caixa de diálogo Editar app para dispositivos móveis vai aparecer.
No campo Conta de serviço, insira a chave da conta de serviço e clique em Salvar.
Configuração do cliente Android
Copie
google-services.jsonpara o diretório do app, por exemplo,PROJECT_ROOT/app/google-services.json.Extraia o token
FCMusando o seguinte código:FirebaseMessaging.getInstance().getToken() .addOnCompleteListener(task -> { if (!task.isSuccessful() || task.getResult() == null) { Log.w("FCM", "Couldn't get FCM token"); return; } String token = task.getResult(); Log.i("FCM", "FCM token: " + token); });FirebaseMessagingServiceé chamado, que é registrado no manifesto se o token for atualizado. Para mais informações, consulte Configurar um app cliente do Firebase Cloud Messaging no Android.public class YourFirebaseMessagingService extends FirebaseMessagingService { /** * There are two scenarios when onNewToken is called: * 1) When a new token is generated on initial app startup * 2) Whenever an existing token is changed * Under #2, there are three scenarios when the existing token is changed: * A) App is restored to a new device * B) User uninstalls/re-installs the app * C) User clears app data */ @Override public void onNewToken(String token) { Log.i("FCM", "FCM token updated: " + token); } }Implemente
UjetRequestListener.onRequestPushTokenna classe Application.UjetRequestListener.onRequestPushTokenprecisa retornar o tokenFCM/GCM.public class YourApplication extends Application implements UjetRequestListener { /** * Return your FCM/GCM token */ @Override public String onRequestPushToken() { return yourToken(); // As shown in the previous step, you can get your token using FirebaseMessaging.getInstance().getToken().addOnCompleteListener(task -> { }) } }Gerencie a notificação push. Se você quiser que Contact Center AI Platform (CCAI Platform) processe as próprias mensagens push, transmita os dados diretamente para
UjetPushHandler.handle().O aplicativo só processa mensagens com o campo
ujet_noti_type(ounoti_type, para compatibilidade com versões anteriores) definido.Caso contrário, você pode optar por enviar apenas mensagens com
ujet_noti_typeparaUjetPushHandler.handle()para processamento.
Confira abaixo um exemplo de mensagem de notificação push:
{ "call_id" : 12345, "ujet_noti_type" : "connect_call", "noti_type" : "connect_call", "call_type" : "ScheduledCall", "fail_reason" : "none", "fail_details" : "none" }
Processar mensagem do FCM
public class YourFirebaseMessagingService extends FirebaseMessagingService {
private UjetPushHandler ujetPushHandler;
@Override
public void onCreate() {
super.onCreate();
this.ujetPushHandler = new UjetPushHandler(this);
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (ujetPushHandler.handle(remoteMessage)) {
// Handled by CCAI Platform
} else {
// Handle your push notification message in here
}
}
}
Processar mensagem do GCM
public class YourGcmListenerService extends GcmListenerService {
private UjetPushHandler ujetPushHandler;
@Override
public void onCreate() {
super.onCreate();
this.ujetPushHandler = new UjetPushHandler(this);
}
@Override
public void onMessageReceived(String s, Bundle bundle) {
if (ujetPushHandler.handle(bundle)) {
// Handled by CCAI Platform
} else {
// Handle your message
}
}
}
Processar mensagens do GCM no GcmReceiver (método antigo)
public class YourGcmReceiver extends WakefulBroadcastReceiver {
private UjetPushHandler ujetPushHandler;
@Override
public void onReceive(Context context, Intent intent) {
ujetPushHandler = new UjetPushHandler(context);
if (ujetPushHandler.handle(intent.getExtras())) {
// Handled by CCAI Platform
} else {
// Handle your message
}
}
}
Inicie o aplicativo
Adicione a seguinte linha onde você quer iniciar o aplicativo (sem parâmetros):
Ujet.start(new UjetStartOptions.Builder().build());
Também é possível iniciar o SDK do Android sem a tela de abertura.
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setSkipSplashEnabled(true)
.build();
Ujet.start(ujetStartOptions);
Você também pode iniciar o SDK do Android em um ponto específico do menu com essa tecla usando um ponto de acesso direto:
String menuKey = "MENU_KEY";
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setMenuKey(menuKey)
.build();
Ujet.start(ujetStartOptions);
O menuKey pode ser criado com um ponto de acesso direto no portal da CCAI Platform (com a função de administrador).
Acesse Configurações > Fila.
Selecione qualquer fila na estrutura de menu.
Marque Criar ponto de acesso direto.
Insira a chave no formulário de texto.
Clique em Salvar.

Também é possível iniciar o SDK do Android com um ID de tíquete específico para transmiti-lo ao CRM. Esse ID será aberto quando um chat ou uma ligação for conectado.
String ticketId = "TICKET_ID";
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setTicketId(ticketId)
.build();
Ujet.start(ujetStartOptions);
Enviar dados personalizados para seu CRM
Os dados personalizados podem ser enviados aos representantes de suporte e aparecem no tíquete de suporte da chamada/chat recebido.
Há dois métodos para enviar dados personalizados:
Método assinado: assinatura de dados predefinida com JWT.
Método não assinado: dados predefinidos com JSON simples (não recomendado).
Usar o método assinado para enviar dados personalizados
Para enviar dados personalizados usando o método assinado, implemente um método de assinatura.
Primeiro, recupere os dados personalizados para o app host e envie-os ao servidor para assinatura. No seu servidor, é possível adicionar mais dados usando um formulário definido. Assine-os com o segredo da empresa e retorne-os por JWT.
public class ExampleApplication extends Application implements UjetRequestListener {
@Override
public void onCreate() {
super.onCreate();
Ujet.init(this);
}
@Override
public void onSignPayloadRequest(Map<String, Object> payload, UjetPayloadType ujetPayloadType, UjetTokenCallback tokenCallback) {
// ...
if (ujetPayloadType == UjetPayloadType.CustomData) {
/**
* These codes are for providing signed custom data.
* Add some data from app, and add more sensitive data from server and sign it.
*/
UjetCustomData appCustomData = new UjetCustomData();
appCustomData.put("model", "Model", "MODEL1234");
appCustomData.put("customer_id", "Customer ID", 12345);
appCustomData.put("temperature", "Temperature", 70.5f);
appCustomData.put("purchase_date", "Purchase Date", new Date());
appCustomData.put("battery", "Battery", "52%");
appCustomData.put("location", "Location", "San Francisco, CA, United States");
appCustomData.putURL("dashboard_url", "Dashboard URL", "https://internal.dashboard.com/12345");
payload.put("custom_data", appCustomData.getData());
tokenCallback.onToken(APIManager.getHttpManager().getSignedCustomData(payload));
}
// ...
}
}
Usar o método sem assinatura para enviar dados personalizados
O Google recomenda usar o método assinado para enviar dados personalizados no seu aplicativo. Para mais informações, consulte Como usar o método assinado para enviar dados personalizados.
É possível enviar dados não assinados iniciando o SDK do Android com opções de início para definir
dados personalizados usando UjetStartOptions.Builder#setUnsignedCustomData e
UjetTokenCallback deve chamar onToken(null).
HashMap<String, Object> jsonData = new HashMap<>();
// Convert json string into hashmap object and store it in jsonData
UjetCustomData customData = new UjetCustomData();
customData.putObject("external_chat_transfer", jsonData); // Use `external_chat_transfer` key to send chat transcript data
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setUnsignedCustomData(customData)
.build();
Ujet.start(ujetStartOptions);
Usar dados personalizados não assinados para enviar uma transcrição de chat externa
É possível enviar a transcrição da conversa externa para a plataforma de CCAI usando
dados personalizados não assinados quando ela é iniciada. Use
UjetCustomData.putObject("external_chat_transfer", hashMapObject) para definir os
dados da transcrição em formato JSON da seguinte maneira:
HashMap<String, Object> jsonData = new HashMap<>();
// Convert json string into hashmap object and store it in jsonData
UjetCustomData customData = new UjetCustomData();
customData.putObject("external_chat_transfer", jsonData); // Use `external_chat_transfer` key to send chat transcript data
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setUnsignedCustomData(customData)
.build();
Ujet.start(ujetStartOptions);
Formato JSON:
greeting_override: stringagent: dicionárioname: stringavatar: string [URL do avatar do agente, opcional]
transcript: matrizsender: string ["end_user" or "agent"]timestamp: string [por exemplo, "2021-03-15 12:00:00Z"]content: matriztype: string [um de texto, mídia]text: string [obrigatória para o tipo de texto]media: dicionário [obrigatório para o tipo de mídia]type: string [uma de imagem, vídeo]url: string [URL público que aponta para o arquivo de mídia]
Exemplo de JSON:
{
"greeting_override": "Please hold while we connect you with a human agent.",
"agent": {
"name": "Name",
"avatar": "avatar url"
},
"transcript": [
{
"sender": "agent",
"timestamp": "2021-03-15 12:00:15Z",
"content": [
{
"type": "text",
"text": "**Suggestions shown:**\n\n* Help with batch or delivery\n* Help with metrics or order feedback\n* Help with Instant Cashout"
}
]
},
{
"sender": "end_user",
"timestamp": "2021-03-15 12:00:16Z",
"content": [
{
"type": "text",
"text": "Help with batch or delivery"
}
]
}
]
}
Você pode usar o Markdown no tipo de texto. Os seguintes formatos são compatíveis:
Negrito
Itálico
Sublinhado
Quebras de linha
Lista com marcadores
Lista numerada
Links
Formato de dados personalizado
Esta seção mostra o formato dos dados personalizados que podem ser transmitidos no JWT.
JSON codificado para JWT
O JSON precisa incluir iat e exp para validar o JWT. O objeto dos dados personalizados é o valor da chave custom_data.
{
"iat" : 1537399656,
"exp" : 1537400256,
"custom_data" : {
"location" : {
"label" : "Location",
"value" : "1000 Stockton St, San Francisco, CA, United States",
"type" : "string"
},
"dashboard_url" : {
"label" : "Dashboard URL",
"value" : "http://(company_name)/dashboard/device_user_ID",
"type" : "url"
},
"contact_date" : {
"label" : "Contact Date",
"value" : 1537399655992,
"type" : "date"
},
"membership_number" : {
"label" : "Membership Number",
"value" : 62303,
"type" : "number"
},
"model" : {
"label" : "Model",
"value" : "iPhone",
"type" : "string"
},
"os_version" : {
"label" : "OS Version",
"value" : "12.0",
"type" : "string"
},
"last_transaction_id" : {
"label" : "Last Transaction ID",
"value" : "243324DE-01A1-4F71-BABC-3572B77AC487",
"type" : "string"
},
"battery" : {
"label" : "Battery",
"value" : "-100%",
"type" : "string"
},
"bluetooth" : {
"label" : "Bluetooth",
"value" : "Bluetooth not supported",
"type" : "string"
},
"wifi" : {
"label" : "Wi-Fi",
"value" : "Wi-Fi not connected",
"type" : "string"
},
"ssn" : {
"invisible_to_agent" : true,
"label" : "Social Security Number",
"value" : "102-186-1837",
"type" : "string"
}
}
}
A chave é um identificador exclusivo dos dados. O tipo é o tipo do valor.
string- String JSON
number- número inteiro, ponto flutuante
date- Formato de carimbo de data/hora Unix UTC com 13 dígitos. (contém milissegundos)
url- Formato do URL HTTP
O rótulo é o nome de exibição na página do CRM.
Impedir a exibição de dados personalizados
É possível usar a propriedade invisible_to_agent com um objeto de dados personalizado para impedir que dados personalizados assinados ou não assinados sejam mostrados no adaptador do agente. No exemplo anterior, o CPF do usuário final não é
mostrado no adaptador do agente porque "invisible_to_agent" : true está incluído no
objeto ssn.
Ao incluir a propriedade "invisible_to_agent" : true com um objeto de dados personalizado, você pode esperar o seguinte comportamento:
- Os dados personalizados são incluídos no arquivo de metadados da sessão.
- Os dados personalizados não são incluídos nos registros do CRM.
Para mais informações, consulte Ver dados da sessão no adaptador do agente.
Propriedades de dados reservadas
É possível enviar propriedades de dados reservados para a Contact Center AI Platform (plataforma CCAI) como dados personalizados assinados quando uma sessão começa. Para mais informações, consulte Enviar propriedades de dados reservadas.
Confira a seguir um exemplo de propriedades de dados reservadas em dados personalizados:
{
"custom_data": {
"reserved_verified_customer": {
"label": "Verified Customer",
"value": "VERIFIED_CUSTOMER_BOOLEAN": ,
"type": "boolean"
},
"reserved_bad_actor": {
"label": "Bad Actor",
"value": "VERIFIED_BAD_ACTOR_BOOLEAN": ,
"type": "boolean"
},
"reserved_repeat_customer": {
"label": "Repeat Customer",
"value": "REPEAT_CUSTOMER_BOOLEAN": ,
"type": "boolean"
}
}
}
Substitua:
VERIFIED_CUSTOMER_BOOLEAN: "True" se você considerar que esse usuário final é um cliente legítimo.VERIFIED_BAD_ACTOR_BOOLEAN: verdadeiro se você considerar que esse usuário final pode ser um usuário de má-fé.REPEAT_CUSTOMER_BOOLEAN: verdadeiro se você determinou que esse usuário final já entrou em contato com sua central de atendimento.
Configuração do SDK
É possível configurar várias opções antes de iniciar o SDK do Android. Consulte a
classe UjetOption. As opções "Número de telefone alternativo" e "Sensibilidade da rede" descritas na tabela a seguir só funcionam quando a chave Ativar fallback da PSTN está ativada no portal da plataforma CCAI em Configurações > Configurações do desenvolvedor > MMA > Editar. Quando a chave Ativar substituição por PSTN está desativada, não fazemos substituição por PSTN. A plataforma CCAI usa a sensibilidade de rede padrão (0,85) para verificar as conexões de rede.
| Opção | Descrição | Valor | Valor padrão |
|---|---|---|---|
| Nível do registro | Nível de registro a ser impresso no Logcat. | Número inteiro. O mesmo vale para o nível de registro do Android. (Mín.: 2, Máx.: 7) | 5 (Log.Warn) |
| Idioma padrão | O código de idioma padrão. | String. Um código de idioma ISO 639. (por exemplo, "en" para inglês) | null |
| Número de telefone alternativo | O número de telefone é usado como substituto quando a Internet não está disponível ou o número de telefone do representante da empresa não existe no portal do administrador. | String. Número de telefone. | null |
| Gerenciador de exceções não capturadas ativado | Ative o gerenciador de exceções não identificadas. Se true, o app vai processar todas as exceções não capturadas do SDK no momento da execução usando Thread.setDefaultUncaughtExceptionHandler. No entanto, se a mesma exceção ocorrer duas vezes, o app vai falhar. |
Booleano. | true |
| Sensibilidade à rede | A sensibilidade para verificar o estado da rede. | Dobro entre 0 e 1, em que 0 é o menos sensível e 1 é o mais sensível. Um valor de 1 sempre vai voltar para uma chamada PSTN. Se for usar, recomendamos começar com um valor de .97. O valor do Portal em Configurações > Configurações do desenvolvedor > Apps para dispositivos móveis > Fallback substitui esse valor. |
0.85 |
| Modo escuro ativado | Ative o tema do modo escuro. Se true, o SDK vai aplicar um tema de modo escuro quando o usuário ativar esse modo. Caso contrário, a ação será ignorada. |
Booleano. | false |
| Canal único ativado | Opção de configuração para mostrar ou ignorar a tela de seleção de um único canal. Se true, o SDK vai mostrar uma única tela de seleção de canais em vez de selecionar automaticamente o canal, mesmo que apenas um esteja ativado na fila do menu. |
Booleano. | false |
| Minimizar automaticamente a visualização da chamada | Opção de configuração para minimizar automaticamente a UI da tela de chamada inicial por padrão ou esperar que o usuário faça isso. | Booleano. | false |
| Borda do ícone do agente ativada | Opção de configuração para mostrar ou remover uma borda circular ao redor do ícone do agente. | Booleano. | false |
| Tamanho de fonte estático na visualização do seletor | Opção de configuração para ajustar ou desativar automaticamente o tamanho do texto do item do seletor. | Booleano. | false |
| Ocultar anexo de mídia no chat | Opção de configuração para mostrar ou ocultar o ícone de anexo de mídia na UI do chat. | Booleano. | false |
Ignorar permissão READ_PHONE_STATE |
Se definido como true, o SDK não vai solicitar a permissão READ_PHONE_STATE. Se você não quiser usar chamadas de IVR no app, defina essa flag como true para evitar solicitar essa permissão. Além disso, seu aplicativo precisa remover explicitamente a permissão android.permission.READ_PHONE_STATE para o SDK da plataforma CCAI. Não recomendamos definir isso como true, porque essa permissão é necessária para que as chamadas de URA no app funcionem. |
Booleano | false |
| Chave de licença do Cobrowse.io (se aplicável) | Opção de configuração para configurar a biblioteca Cobrowse.io. Para encontrar sua chave de licença do Cobrowse, faça login em https://cobrowse.io/dashboard/settings e acesse a seção Chave de licença. |
String | null |
| Título do cabeçalho do chat personalizado | Opção de configuração para personalizar o texto do título do cabeçalho do chat na UI. | String | null |
| Personalizar respostas rápidas da UI do chat | Opção de configuração para personalizar respostas rápidas do agente virtual na interface do chat. As respostas rápidas do agente virtual são agrupadas por padrão, mas, se você quiser mostrá-las individualmente, use essa opção de configuração para definir QuickReplyButtonsStyle.INDIVIDUAL. | UjetStylesOptions | QuickReplyButtonsStyle.GROUPED |
| Personalizar vários atributos UI interface do chat | Opção de configuração para personalizar vários atributos, como fonte, cor de plano de fundo, ícone etc. | UjetStylesOptions | null |
| Ocultar barra de status | Opção de configuração para mostrar ou ocultar a barra de status. Se o valor for verdadeiro, o SDK vai ocultar a barra de status. | Booleano | false |
| Definir o ícone de carregamento drawable res | Opção de configuração para personalizar a visualização do spinner de carregamento em todo o app. Se não estiver disponível ou for nula, vamos usar a visualização de carregamento padrão. | Número inteiro | null |
| Orientação paisagem desativada | Desative a orientação paisagem. Se o valor for verdadeiro, a orientação paisagem não será aplicada. | Booleano | false |
| Ocultar o botão inline "Iniciar nova conversa" no chat | Opção de configuração para mostrar ou ocultar o botão inline "Iniciar nova conversa" na UI do chat. | Booleano | false |
| Mostrar botão para pular CSAT | Opção de configuração para mostrar ou ocultar o botão "Pular" na caixa de diálogo de CSAT | Booleano | false |
| Bloquear o encerramento do chat pelo usuário final | Opção de configuração para mostrar ou ocultar o botão "Encerrar chat" na UI de chat | Booleano | false |
| Ocultar o download da transcrição do chat | Mostrar ou ocultar o botão "Baixar transcrição do chat" no menu de ações e na interface do usuário do chat. Se você adicionar um espaço à string ujet_common_hide, o texto Hide vai desaparecer, e apenas a seta para trás vai aparecer. |
Número inteiro. Valores:
|
0
|
| Desativar as notificações push no nível global | Definir UjetOption.setPushNotificationsAllowed como false ignora todas as dependências de notificações push e impede que elas cheguem aos usuários finais. |
Booleano | true |
UjetOption ujetOption = new UjetOption.Builder()
.setLogLevel(Log.INFO)
.setDefaultLanguage("en")
.setFallbackPhoneNumber("+18001112222")
.setUncaughtExceptionHandlerEnabled(false)
.setNetworkSensitivity(0)
.setDarkModeEnabled(true)
.setShowSingleChannelEnabled(true)
.setAutoMinimizeCallView(true)
.setShowAgentIconBorderEnabled(true)
.setStaticFontSizeInPickerView(true)
.setHideMediaAttachmentInChat(true)
.setIgnoreReadPhoneStatePermission(true)
.setCobrowseLicenseKey("COBROWSE_IO_LICENSE_KEY_HERE")
.setCobrowseURL("COBROWSE_IO_API_URL_HERE")
.setCustomChatHeaderTitle("CHAT_HEADER_TITLE_TEXT")
.setUjetStylesOptions(
new UjetStylesOptions.Builder()
.setChatQuickReplyButtonsStyle(QuickReplyButtonsStyle.INDIVIDUAL)
.setChatStyles(new ChatStyles(...)) // See `Content Cards Theme` item
.build() )
.setBlockChatTerminationByEndUser(true)
.setHideStatusBar(true)
.setLoadingSpinnerDrawableRes(R.drawable.RESOURCE_NAME)
.setLandscapeOrientationDisabled(true)
.setShowCsatSkipButton(false)
.setHideDownloadChatTranscript(0) // 0 to 3. 0 = Show everywhere, 1 = Hide from the options menu, 2 = Hide from the post chat screen, 3 = Hide from both the options menu and the post chat screen.
.setPushNotificationsAllowed(true)
.build();
//The following customizes various attributes in chat UI
ChatStyles chatStyles = new ChatStyles();
chatStyles.setBackButton(new BackButtonStyle(false, "ujet_agent_sample")); //customizes back button styles
chatStyles.setHeader(...); //customizes chat header styles
chatStyles.setAgentMessageBubbles(...); //customizes agent messages styles
chatStyles.setConsumerMessageBubbles(...); //customizes consumer messages styles
chatStyles.setSystemMessages(...); //customizes system messages styles
chatStyles.setEndChatButton(...); //customizes end chat button styles
chatStyles.setTimeStamps(...); //customizes timestamp styles
chatStyles.setUserInputBar(...); //customizes user input bar styles
UjetOption ujetOption = new UjetOption.Builder()
.setUjetStylesOptions(
new UjetStylesOptions.Builder()
.setChatStyles(chatStyles)
.build()
)
//The following customizes various attributes in chat UI using json file. Store json file in assets folder
//and create a method to read json file contents and convert it into json string.
String chatStylesFromJson = parseJsonContentsFromAssetsFolder();
UjetOption ujetOption = new UjetOption.Builder()
.setUjetStylesOptions(
new UjetStylesOptions.Builder()
.setChatStyles(chatStylesFromJson)
.build()
)
Fallback
Você pode usar UjetErrorListener para o fallback de erros inesperados. Se você não definir esse listener ou retornar "false", o SDK do Android vai processar o erro.
O SDK do Android vai redirecionar os usuários para o discador com um número alternativo somente quando a opção "Ativar fallback da PSTN" estiver ATIVADA em Configurações > Configurações do desenvolvedor > MMA > Editar pop-up. Caso contrário, saia do SDK.
| Tipo de erro | Código do erro | Gatilho |
|---|---|---|
| NETWORK_ERROR | 1 | A rede não está disponível. Esse erro não é acionado quando a rede não está disponível durante uma conversa por chat ou ligação ou na tela de classificação. |
| AUTHENTICATION_ERROR | 100 | Ocorreu um erro inesperado durante a autenticação. |
| AUTHENTICATION_JWT_ERROR | 101 | Ocorreu um erro inesperado durante a validação do JWT (por exemplo, um erro de análise). |
| VOIP_CONNECTION_ERROR | 1000 | Não foi possível estabelecer uma conexão com o provedor de VoIP. Ele é processado pelo callback do SDK de VoIP. |
| VOIP_LIBRARY_NOT_FOUND | 1001 | Uma chamada deveria ser conectada usando um provedor de VoIP, mas não foi possível encontrar um. Isso pode acontecer quando um desenvolvedor integra o SDK errado ou não adiciona a biblioteca do provedor de VoIP às dependências. |
| CHAT_LIBRARY_NOT_FOUND | 1100 | Ocorre quando não é possível encontrar a biblioteca de chat. Isso pode acontecer quando um desenvolvedor integra o SDK errado ou não adiciona a biblioteca do Twilio Chat às dependências. |
Ujet.setUjetEventListener(new UjetEventListener() {
@Override
public void onEvent(UjetEventType eventType, HashMap<String, Object> eventData) {
// eventType specifies the event type and eventData holds the data related to the event.
// You can parse the eventData and here we are just logging the event type and event data.
Log.i("CCAI Platform Event Type", eventType.getValue());
StringBuilder builder = new StringBuilder();
for (Map.Entry<String, Object> entry : eventData.entrySet()) {
builder.append(entry.getKey()).append(" : ").append(entry.getValue()).append("\n");
}
Log.i("CCAI Platform Event Data", builder.toString());
}
});
Permissões do app
O app requer as seguintes permissões e as solicita ao usuário quando necessário.
| Permissão | Descrição |
|---|---|
| CÂMERA | Usado para ações inteligentes para tirar fotos e gravar vídeos. |
| MICROFONE | Permite que o app use chamadas VoIP pelo Twilio. |
| ARMAZENAMENTO | Permite que o app salve fotos e vídeos. |
Configuração de links diretos (opcional)
Se você quiser usar ações inteligentes em uma chamada de IVR (PSTN), configure o link direto no seu projeto.
O formato de link direto é um URI exclusivo, como:
ujet:// <package_name>/smartchannel.
Além disso, você precisa definir esse link ou qualquer URL que redirecione para ele no Portal do administrador (Configurações > Gerenciamento de operações > Ativar o envio de SMS para baixar o app).
Você precisará adicionar um filtro de intent que contenha o link direto no manifesto.
<activity android:name="co.ujet.android.activity.UjetActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="<package_name>"
android:scheme="ujet"
android:path="/smartchannel" />
</intent-filter>
</activity>
Canal preferido
Com o parâmetro "Canal preferido", você encaminha os consumidores diretamente para um canal específico. O usuário final pula a etapa de seleção do canal e inicia o contato diretamente pelo canal especificado no parâmetro "Canal preferido".
UjetStartOptions.preferredChannel
Ujet.start(new)
UjetStartOptions.Builder().setPreferredChannel
(UjetPreferredChannel.UjetPreferredChannelChat).build());
Notificações de eventos
Você também pode definir UjetEventListener para receber notificações de eventos do aplicativo.
Os tipos de evento e as descrições disponíveis estão listados aqui.
Ujet.setUjetEventListener(new UjetEventListener() {
@Override
public void onEvent(UjetEventType eventType, HashMap<String, Object> eventData) {
// eventType specifies the event type and eventData holds the data related to the event.
// You can parse the eventData and here we are just logging the event type and event data.
Log.i("CCAI Platform Event Type", eventType.getValue());
StringBuilder builder = new StringBuilder();
for (Map.Entry<String, Object> entry : eventData.entrySet()) {
builder.append(entry.getKey()).append(" : ").append(entry.getValue()).append("\n");
}
Log.i("CCAI Platform Event Data", builder.toString());
}
});
| Tipo de evento | Descrição | Dados incluídos no evento |
|---|---|---|
EmailClicked |
Acionado quando o usuário final clica no canal de e-mail. | Dados do menu da fila |
EmailSubmitted |
Acionado quando o usuário final envia um e-mail. | Dados do menu da fila, dados enviados por e-mail |
SessionPaused |
Acionado quando o usuário final minimiza uma sessão de chat ou chamada. | Dados de sessão |
SessionResumed |
Acionado quando o usuário final volta para uma sessão de chat ou chamada do segundo plano. | Dados de sessão |
SessionCreated |
É acionado quando uma sessão de chat ou chamada é criada. | Dados do menu da fila, dados de criação da sessão |
SessionEnded |
Acionada quando uma sessão de chat ou chamada é encerrada. | Dados do menu da fila, dados de criação e término da sessão |
SdkTerminated |
Acionada quando o SDK é fechado, inclusive quando isso acontece de forma inesperada. | Dados de encerramento do SDK |
ContentCardClicked |
Acionado quando um card de conteúdo é clicado. | Dados de cliques no card de conteúdo |
ContentCardButtonClicked |
Acionado quando um botão de card de conteúdo é clicado. | Dados de cliques no botão do card de conteúdo |
QuickReplyClicked |
Acionada quando uma resposta rápida é clicada. | Dados de cliques em respostas rápidas |
MessageLinkClicked |
Acionado quando um link é clicado. | Dados de clique no link da mensagem |
Dados do menu da fila
| Chave | Tipo | Descrição |
|---|---|---|
event_name |
String | Contém o nome do evento. Por exemplo, "E-mail clicado". |
application |
String | Contém o nome do aplicativo. Por exemplo, "Android". |
app_id |
String | Contém o identificador do app, que é igual a Context.getPackageName(). |
app_version |
String | Contém o nome e o código da versão do app. Por exemplo, "0.32.0 (123)". |
sdk_version |
String | Contém a versão do SDK. Por exemplo, "0.32.0". |
timestamp |
String | Contém o carimbo de data/hora em UTC (no formato aaaa-MM-dd'T'HH:mm:ss'Z'). |
device_model |
String | Contém o modelo do dispositivo do usuário. Por exemplo, "Google Pixel". |
device_version |
String | Contém a versão do dispositivo do usuário. Por exemplo, "10, Q, SDK 29". |
company |
String | Contém o nome da empresa. Por exemplo, "Empresa". |
menu_name |
String | Contém o nome do nó folha (última seleção de menu do usuário). Por exemplo, "Submenu". |
menu_id |
String | Contém o ID do nó folha (última seleção de menu do usuário). Por exemplo, "123". |
menu_path |
String | Contém a sequência completa de menus selecionados pelo usuário. Por exemplo, "Menu principal / Menu filho / Submenu". |
menu_key |
String | Contém a chave da DAP e é opcional. Por exemplo, "special_user_menu". |
Dados enviados por e-mail
| Chave | Tipo | Descrição |
|---|---|---|
has_attachments |
Booleano | Retorna "True" se o e-mail tiver anexos. Caso contrário, retorna "False". |
Dados de sessão
| Chave | Tipo | Descrição |
|---|---|---|
event_name |
String | Contém o nome do evento. Por exemplo, "E-mail clicado". |
type |
String | Contém o tipo de sessão. Por exemplo, "chat" ou "call". |
timestamp |
String | Contém o carimbo de data/hora em UTC (no formato aaaa-MM-dd'T'HH:mm:ss'Z'). |
Dados de criação da sessão
| Chave | Tipo | Descrição |
|---|---|---|
session_id |
String | Contém o ID da sessão. Por exemplo, "100". |
type |
String | Contém o tipo de sessão. Por exemplo, "chat" ou "call". |
end_user_identifier |
String | Contém o identificador do usuário final. Por exemplo, "João". |
messages_end_user |
String | Contém a contagem de mensagens do usuário final e só é incluído para a sessão de chat. Por exemplo, "3". |
messages_agent |
String | Contém a contagem de mensagens do agente e só é incluído na sessão de chat. Por exemplo, "3". |
Dados de encerramento da sessão
| Chave | Tipo | Descrição |
|---|---|---|
agent_name |
String | Contém o nome do agente. Por exemplo, "João". |
ended_by |
String | Contém detalhes sobre quem encerrou a sessão. Os valores possíveis são "agent" (quando o agente encerra a sessão), "end_user" (quando o usuário final encerra a sessão), "timeout" (quando o chat atinge o tempo limite) ou "dismissed" (quando o chat é dispensado). |
duration |
String | Contém a duração da sessão em segundos e só é incluído para a sessão de chamada. Por exemplo, "30 segundos". |
Dados de encerramento do SDK
| Chave | Tipo | Descrição |
|---|---|---|
event_name |
String | Contém o nome do evento. Por exemplo, "E-mail clicado". |
Dados de cliques em cards de conteúdo
| Chave | Tipo | Descrição |
|---|---|---|
title |
string | O título do card. |
title |
string | O título do card. |
subtitle |
string | O subtítulo do card. |
body |
string | A descrição do card de conteúdo. |
link | string | Um link de página da Web ou um link direto. O SDK usa os recursos do SO para abrir. |
event_params | dictionary | Um dicionário que contém informações extras sobre o evento de clique. O SDK usa isso. |
Dados de clique no botão do card de conteúdo
| Chave | Tipo | Descrição |
|---|---|---|
title |
string | O título do card. |
title |
string | O título do card. |
link | string | Um link de página da Web ou um link direto. O SDK usa os recursos do SO para abrir. |
event_params | dictionary | Um dicionário que contém informações extras sobre o evento de clique. O SDK usa isso. |
Dados de cliques em respostas rápidas
| Chave | Tipo | Descrição |
|---|---|---|
title |
string | O título do card. |
title |
string | O título do card. |
link | string | Um link de página da Web ou um link direto. O SDK usa os recursos do SO para abrir. |
event_params | dictionary | Um dicionário que contém informações extras sobre o evento de clique. O SDK usa isso. |
Dados de clique no link da mensagem
| Chave | Tipo | Descrição |
|---|---|---|
event_name |
String | Contém o nome do evento, por exemplo, "Clique no link da mensagem". |
link |
String | Um link de página da Web ou um link direto. O SDK usa os recursos do SO para abrir. |
Mudanças no comportamento das chamadas recebidas
A partir dos dispositivos com a versão Android 10, as chamadas recebidas não serão recebidas diretamente pelos usuários finais quando o app host estiver em segundo plano. Em vez disso, usamos notificações para alertar os usuários sobre uma chamada recebida (mesmo quando o smartphone está bloqueado), a opção de aceitar ou recusar a chamada.
Mostramos as mesmas notificações quando o app host está em segundo plano e a tela bloqueada antes da chegada da chamada. Essa mudança de comportamento tem como objetivo obedecer às restrições recentes do Google para iniciar atividades quando o app está em segundo plano. O comportamento não é afetado quando o app host está em primeiro plano ou em dispositivos com versões anteriores ao Android 10.
Personalizar a sessão do SDK
Esta seção descreve como o SDK pode ser ainda mais personalizado.
Verificar se há uma sessão
Antes de iniciar uma sessão, use o método descrito para verificar se há alguma sessão em andamento ou já existente. Se ele existir, você poderá pedir ao usuário final para retomar ou cancelar.
Isso é especialmente importante quando um usuário é alterado.
if (Ujet.getStatus() != UjetStatus.None) {
// Display alert to cancel login or resume existing session
}
Desconectar a sessão
Consulte o método se quiser desconectar qualquer sessão em andamento.
Antes de usar esse método, verifique se uma sessão desse tipo existe usando
Ujet.getStatus(). Se você quiser realizar uma ou mais ações depois que o SDK
desconectar a sessão, por exemplo, mostrar uma mensagem ou fechar o
app, use o callback de resposta onFinished(), conforme abordado na próxima
seção. Caso contrário, defina o callback como nulo.
Ujet.disconnect(new UjetResponseCallback() {
@Override
public void onFinished() {
// `onFinished()` is triggered after CCAI Platform disconnects the session.
finish(); // Finishes the activity.
}
});
Limpar dados do usuário final do cache
Você é responsável por limpar o cache quando os dados relacionados ao usuário final forem atualizados ou alterados no seu app. Por exemplo, se o usuário final fizer logout, invoque o método para remover o cache desse usuário. Assim, uma nova sessão será iniciada para o novo usuário final na próxima inicialização do SDK.
Ujet.clearUserData();
Ocultar o SDK
É possível ocultar o SDK usando o método Ujet.hideSDK(). Isso é útil quando o SDK interfere na interface do usuário do app, por exemplo. Inicialize o SDK
usando Ujet.init() antes de chamar esse método. Ujet.init() retorna true se
o SDK for ocultado com êxito e false caso contrário. Depois de ocultar o SDK, você
pode iniciá-lo novamente usando o método Ujet.start().
O exemplo a seguir oculta o SDK:
Ujet.hideSDK();
Preferência de idioma
O SDK do Android vai usar a seguinte ordem de prioridade para determinar o idioma.
Idioma selecionado na tela de apresentação do app.
Idioma padrão selecionado usando
UjetOptions. É possível definir o idioma padrão usandosetDefaultLanguage("en")emUjetOptions. Consulte "Idioma padrão" na seção "Configuração do SDK" para mais detalhes.O idioma selecionado no dispositivo (em Configurações > Geral > Idioma) será usado quando for compatível com o app.
O dialeto mais próximo do idioma do dispositivo será usado quando o app não for compatível com o idioma do dispositivo, mas for compatível com o dialeto principal mais próximo. Por exemplo, se o usuário selecionar "Espanhol de Cuba" como o idioma no dispositivo e o app não for compatível com essa opção, mas for compatível com o dialeto principal "Espanhol", o idioma espanhol será usado.
O inglês será usado como idioma padrão quando o idioma do dispositivo não for compatível com o app.
Configurar ícones de links de evasão externos
Personalize o ícone no canal "Link de redirecionamento externo" fazendo upload dele em uma pasta drawable do seu app. Use o mesmo nome de ícone ao criar o link de redirecionamento externo no portal da plataforma CCAI em Configurações > Chat > Links de redirecionamento externo > Ver links > Adicionar link de redirecionamento.
Se o nome do ícone no portal da plataforma de CCAI não corresponder ao ícone enviado para o app, o SDK do Android usará o ícone padrão.
Configurar o ícone Agradecimento das pesquisas
É possível personalizar ou substituir o ícone na página de agradecimento da pesquisa fazendo upload de um
ícone na pasta drawable do app e usando o nome de arquivo
ujet_survey_thank_you_icon como nome do ícone.
Personalizar (opcional)
Esta seção descreve como personalizar valores específicos no SDK.
Strings
É possível personalizar as strings usadas no aplicativo substituindo as chaves de cada string em strings.xml.
<resources>
<!--Greeting title and message in splash screen-->
<string name="ujet_greeting_title">Customer Support</string>
<string name="ujet_greeting_description">runs on UJET</string>
</resources>

Personalização do tamanho do texto
Personalize o título, a descrição e o tamanho do texto do seletor usados no aplicativo substituindo as seguintes chaves em dimens.xml.
Os tamanhos de texto personalizáveis são destacados:
<resources>
<!-- Don't include the following tags if you don't want to customize any of these keys and prefer to use the CCAI Platform default values instead. -->
<!-- You can customize title text size by updating value here. -->
<dimen name="ujet_title">10sp</dimen>
<!-- You can customize description text size by updating value here. -->
<dimen name="ujet_description">10sp</dimen>
<!-- You can customize picker text size by updating value here. -->
<dimen name="ujet_picker_item_text_size">10sp</dimen>
</resources>

Tema
Personalize o tema e o plano de fundo seguindo estas etapas. A etapa 1 é para o tema e a etapa 2 é para o plano de fundo.
Personalize o tema substituindo as chaves de cada item de estilo em style.xml. Por exemplo,
<!--Default style applies to both Light and Dark Mode Themes--> <style name="Ujet"> <item name="ujet_typeFace">ProximaNova-Reg.otf</item> <item name="ujet_colorPrimary">@color/primaryDefault</item> <item name="ujet_colorPrimaryDark">@color/primaryDarkDefault</item> <item name="ujet_buttonRadius">10dp</item> <item name="ujet_companyLogo">@drawable/your_company_logo_default</item> <!-- You can customize the avatar in waiting UI before call or chat is connected by using the following option. --> <item name="ujet_defaultAvatar">@drawable/your_default_avatar</item> </style> <!--This is optional and can be used to update style in Light Mode Theme only--> <style name="Ujet.Light"> <item name="ujet_typeFace">ProximaNova-Reg.otf</item> <item name="ujet_colorPrimary">@color/primaryLightMode</item> <item name="ujet_colorPrimaryDark">@color/primaryDarkLightMode</item> <item name="ujet_buttonRadius">10dp</item> <item name="ujet_companyLogo">@drawable/your_company_logo_light_mode</item> <!-- You can customize the avatar in waiting UI before call or chat is connected by using the following option. --> <item name="ujet_defaultAvatar">@drawable/your_default_avatar</item> </style> <!--This is optional and can be used to update style in Dark Mode Theme only--> <style name="Ujet.Dark"> <item name="ujet_typeFace">ProximaNova-Reg.otf</item> <item name="ujet_colorPrimary">@color/primaryDarkMode</item> <item name="ujet_colorPrimaryDark">@color/primaryDarkForDarkMode</item> <item name="ujet_buttonRadius">10dp</item> <item name="ujet_companyLogo">@drawable/your_company_logo</item> <!-- You can customize the avatar in waiting UI before call or chat is connected by using the following option. --> <item name="ujet_defaultAvatar">@drawable/your_default_avatar</item> </style>É possível personalizar a cor de plano de fundo no aplicativo substituindo chaves para cada item de estilo em style.xml. A cor de plano de fundo personalizável é mostrada na captura de tela.
<style name="Ujet"> <!-- Don't include the following tags if you don't want to customize any of these keys and prefer to use the CCAI Platform default values instead. --> <!-- You can customize light mode theme background color by updating value here in hex. --> <item name="ujet_colorBackground">@color/backgroundDefault</item> <!-- You can customize dark mode theme background color by updating value here in hex. --> <item name="ujet_colorBackgroundDark">@color/backgroundDefaultDark</item> </style>
Personalizar o título do cabeçalho do chat
Há opções disponíveis para personalizar o texto do título do cabeçalho do chat na sua UI.
Você pode personalizar o texto do título do cabeçalho do chat usando as seguintes opções:
<item name="ujet_chatCustomHeaderTextColor">@color/chatHeaderTextLightMode</item>
<item name="ujet_chatCustomHeaderTextColowDark">@color/chatHeaderTextDarkMode</item>
<item name="ujet_chatCustomHeaderTextSize">16sp</item>
<item name="ujet_chatCustomHeaderTextStyle">bold</item>
É possível personalizar as respostas rápidas do agente virtual na UI de chat usando as seguintes opções:
<item name="ujet_colorChatQuickReplyButtonBackground">@color/chatQuickReplyButtonBackgroundLightMode</item>
<item name="ujet_colorChatQuickReplyButtonBackgroundDark">@color/chatQuickReplyButtonBackgroundDarkMode</item>
<item name="ujet_colorChatQuickReplyButtonPressedBackground">@color/chatQuickReplyButtonPressedBackgroundLightMode</item>
<item name="ujet_colorChatQuickReplyButtonPressedBackgroundDark">@color/chatQuickReplyButtonPressedBackgroundDarkMode</item>
<item name="ujet_colorChatQuickReplyButtonText">@color/chatQuickReplyButtonTextLightMode</item>
<item name="ujet_colorChatQuickReplyButtonTextDark">@color/chatQuickReplyButtonTextDarkMode</item>
<item name="ujet_colorChatQuickReplyButtonPressedText">@color/chatQuickReplyButtonPressedTextLightMode</item>
<item name="ujet_colorChatQuickReplyButtonPressedTextDark">@color/chatQuickReplyButtonPressedTextDarkMode</item>
<item name="ujet_colorChatQuickReplyButtonStroke">@color/chatQuickReplyButtonStrokeLightMode</item>
<item name="ujet_colorChatQuickReplyButtonStrokeDark">@color/chatQuickReplyButtonStrokeDarkMode</item>
<item name="ujet_chatQuickReplyButtonTypeFace">Kreon-Regular.ttf</item>
<item name="ujet_chatQuickReplyButtonStrokeWidth">3dp</item>
<item name="ujet_chatQuickReplyButtonCornerRadius">3dp</item>
<item name="ujet_chatQuickReplyButtonVerticalMargin">0dp</item>
<item name="ujet_chatQuickReplyButtonHorizontalPadding">10dp</item>
<item name="ujet_chatQuickReplyButtonVerticalPadding">1dp</item>
<item name="ujet_chatQuickReplyButtonAlignment">right</item>
Cards de conteúdo
Você pode adicionar personalização para cards de conteúdo e para o chat. Você pode fazer isso usando o arquivo JSON (consulte content_card property no arquivo app/src/main/assets/json/ujet_styles.json) ou a classe ContentCardStyle.
ChatStyles(
...
contentCard = ContentCardStyle(
backgroundColor = "color_reference",
cornerRadius = 8,
font = FontStyle(
colorReference = "color_reference",
size = 16,
style = "bold|italic",
family = "Roboto-Black.ttf",
),
border = BorderStyle(
color = "color_reference",
width = 2,
),
title = TextStyle(
FontStyle(
colorReference = "color_reference",
size = 18,
style = "bold|italic",
family = "Roboto-Black.ttf",
)
),
subtitle = TextStyle(
FontStyle(
colorReference = "color_reference",
size = 16,
style = "bold|italic",
family = "Roboto-Black.ttf",
)
),
body = TextStyle(
FontStyle(
colorReference = "color_reference",
size = 16,
style = "bold|italic",
family = "Roboto-Black.ttf",
)
)
)
)
Tema do formulário da Web
Você pode personalizar o card do formulário da Web e o chat. Para isso, use o arquivo JSON (consulte a propriedade form_card no arquivo app/src/main/assets/json/ujet_styles.json) ou a classe FormCardStyle.
ChatStyles(
...
formCard = FormCardStyle(
backgroundColor = "color_reference",
cornerRadius = 8,
font = FontStyle(
colorReference = "color_reference",
size = 16,
style = "bold|italic",
family = "Roboto-Black.ttf",
),
border = BorderStyle(
color = "color_reference",
width = 2,
),
title = TextStyle(
FontStyle(
colorReference = "color_reference",
size = 18,
style = "bold|italic",
family = "Roboto-Black.ttf",
)
),
subtitle = TextStyle(
FontStyle(
colorReference = "color_reference",
size = 16,
style = "bold|italic",
family = "Roboto-Black.ttf",
)
),
image = ImageStyle (
height = 94,
),
)
)
Pesquisas
Para mudar o ícone na página de agradecimento da pesquisa, faça upload de um ícone para a pasta drawable do app.
Use ujet_survey_thank_you_icon como o nome do ícone.
Solução de problemas
Iniciar um novo chat levou mais de 30 segundos
Verifique se você está respondendo a um método delegado de dados personalizados. Você precisa retornar dados personalizados válidos mediante solicitação ou apenas retornar nulo com um callback. Use o código a seguir como referência.
@Override
public void onSignPayloadRequest(Map<String, Object> payload, UjetPayloadType ujetPayloadType, UjetTokenCallback tokenCallback) {
if (ujetPayloadType == UjetPayloadType.CustomData) {
tokenCallback.onToken(null);
}
}
Explicação da declaração de política
Se você receber uma notificação no Google Play Console pedindo para declarar uma política para os serviços ou permissões usados pelo SDK do Android, use uma das explicações a seguir.
Declarar serviços em primeiro plano usados pelo SDK do Android
O Google introduziu os tipos de serviços em primeiro plano no Android 14 e exigiu que eles fossem especificados ao iniciar esses serviços, de acordo com https://developer.android.com/about/versions/14/changes/fgs-types-required#remote-messaging. O SDK do Android da Contact Center AI Platform (Plataforma CCAI) usa serviços em primeiro plano para iniciar chat e chamadas. Por isso, usamos o tipo de serviço FOREGROUND_SERVICE_REMOTE_MESSAGING para chat, já que estamos lidando com mensagens de texto, e o tipo de serviço FOREGROUND_SERVICE_MICROPHONE para chamadas. Sem esses tipos de serviço, o SDK vai falhar ao iniciar um chat ou uma chamada em dispositivos com a versão 14 do Android ou mais recente.
Declarar a permissão de intent para tela cheia usada pelo SDK do Android
A permissão USE_FULL_SCREEN_INTENT é necessária para mostrar a notificação push de chamada recebida quando o dispositivo está bloqueado. Ele alerta o usuário final e mostra a notificação de chamada recebida em tela cheia. É assim que o app de telefone integrado notifica o usuário final sobre a chamada recebida.
Compatibilidade com o Android 15
Para oferecer suporte ao Android 15, siga estas etapas:
Defina
compileSdkVersion = 35etargetSdkVersion = 35no seubuild.gradle(:app).Verifique se a versão do Plug-in do Android para Gradle (AGP) do projeto é 8.5.1 ou mais recente. Para mais informações, consulte Atualizar o pacote das bibliotecas compartilhadas.
Instale o Java Development Kit (JDK) versão 17 ou mais recente para criar projetos do Android usando o AGP 8.0 ou mais recente. Para mais informações, consulte JDK 17 necessário para executar o AGP 8.0.