En esta página, se explica cómo usar el SDK de Android.
Accede a la app de ejemplo
Para descargar la app de ejemplo para Android, haz clic en App de ejemplo para Android.
Para crear una app de ejemplo con el SDK para dispositivos móviles de Android, necesitas lo siguiente:
Clave y secreto de la empresa del portal de CCAI Platform
Android 5.0 (nivel de API 21, Lollipop) o versiones posteriores
Firebase Cloud Messaging o Google Cloud Messaging para la notificación push.
Se migró la app a AndroidX.
Requisitos para actualizar el SDK de Twilio
Requiere que el SDK de Twilio siga versiones específicas si el SDK de Android se integra directamente con nuestro paquete; de lo contrario, se puede ignorar.
// Twilio VoIP SDK
api 'com.twilio:voice-android:6.1.1'
// Twilio Conversations SDK
api 'com.twilio:conversations-android:3.1.0'
Además, las reglas de ProGuard ya están incluidas en el SDK de Android para garantizar que ProGuard no quite la biblioteca de Twilio Programmable Voice y que se pueda usar para solucionar problemas en caso de que ProGuard quite la biblioteca por accidente.
-keep class com.twilio.** { *; }
-keep class tvo.webrtc.** { *; }
-dontwarn tvo.webrtc.**
-keep class com.twilio.voice.** { *; }
-keepattributes InnerClasses
Para admitir las versiones más recientes de Twilio, a partir de la versión 0.34.0 del SDK de Android, el SDK ya no es compatible a nivel binario con las aplicaciones que tienen como objetivo Java 7. Para usar esta y las versiones futuras, los desarrolladores deben actualizar sus aplicaciones para que tengan como objetivo Java 8. Consulta el siguiente ejemplo de código:
android {
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
Obtén la clave y el secreto de la empresa
Accede al portal de administrador con las credenciales de administrador.
Ve a Configuración > Configuración para desarrolladores > Clave y código secreto de la empresa.
Recupera la clave de la empresa y el código secreto de la empresa.
Instalación
Agrega el repositorio del SDK de Android a la configuración de Gradle para el proyecto raíz.
build.gradle (proyecto)
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"
}
Configura los parámetros de configuración de la empresa
Ingresa la configuración de tu empresa como metadatos en el archivo 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>
Firma de JWT
La información del usuario final debe firmarse como JWT en tu servidor por motivos de seguridad.
La app de ejemplo contiene APIManager para pruebas, y debes colocar UJET_COMPANY_SECRET en mock/APIManager.java. APIManager debe implementar un método que inicie una llamada asíncrona para firmar el token de autenticación JWT que devuelve el token.
En producción, debes implementar el proceso de firma en tu servidor.
public class APIManager {
public static final String UJET_COMPANY_SECRET = "Please input your UJET_COMPANY_SECRET from Ujet developer admin page";
// ...
}
Inicializa el SDK
Inicializa el SDK en el método onCreate de la clase Android Application.
public class ExampleApplication extends Application implements UjetRequestListener {
@Override
public void onCreate() {
super.onCreate();
Ujet.init(this);
}
// ...
}
Autenticación del usuario final
El usuario final es el consumidor que se comunica con tu equipo de asistencia al cliente a través de la aplicación.
Para autenticar al usuario final en la aplicación, presentamos un mecanismo de firma de JWT.
El SDK de Android solicita que se firme la carga útil cuando necesita autenticación. Si la firma se realiza correctamente, la aplicación intercambia el JWT firmado por el token de autenticación del usuario final.
En ExampleApplication, debes implementar la interfaz UjetRequestListener para firmar el token de autorización y los datos 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 obtener más información, consulta Autenticación de usuarios finales.
Cómo configurar las notificaciones push
En esta sección, se describe cómo habilitar las notificaciones push en dispositivos móviles.
Prepara Firebase
Debes preparar un proyecto de Firebase.
Si ya tienes tu proyecto, puedes usar el tuyo y omitir este proceso.
Crea un proyecto en Firebase console.
Descarga google-services.json desde Configuración > GENERAL en Firebase console.

- Obtén la clave del servidor en Configuración > CLOUD MESSAGING en Firebase console.

Agrega una clave de cuenta de servicio
Debes agregar una clave de cuenta de servicio a tu app para dispositivos móviles para recibir notificaciones push. Para obtener una clave de cuenta de servicio, consulta Realiza la autenticación con una cuenta de servicio.
Para agregar una clave de cuenta de servicio a tu app para dispositivos móviles, sigue estos pasos:
En el portal de la Plataforma de CCAI, haz clic en Configuración > Configuración del desarrollador. Si no ves el menú Configuración, haz clic en Menú.
Ve al panel Mobile Apps.
Haz clic en Editar junto a tu app. Aparecerá el diálogo Editar app para dispositivos móviles.
En el campo de la cuenta de servicio, ingresa la clave de tu cuenta de servicio y, luego, haz clic en Guardar.
Configuración del cliente de Android
Copia
google-services.jsonen el directorio de tu app, por ejemplo,PROJECT_ROOT/app/google-services.json.Obtén el token de
FCMcon el siguiente 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); });Se llama a
FirebaseMessagingService, que se registra en el manifiesto si se actualiza el token. Para obtener más información, consulta Configura una app cliente de Firebase Cloud Messaging en 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); } }Implementa
UjetRequestListener.onRequestPushTokenen tu clase Application.UjetRequestListener.onRequestPushTokendebería devolver el 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 -> { }) } }Controla la notificación push. Si quieres que Contact Center AI Platform (CCAI Platform) controle el procesamiento de sus propios mensajes push, puedes pasar los datos directamente a
UjetPushHandler.handle().La aplicación solo procesa mensajes con el campo
ujet_noti_type(onoti_type, para retrocompatibilidad) establecido.De lo contrario, puedes elegir enviar solo los mensajes con
ujet_noti_typeaUjetPushHandler.handle()para su procesamiento.
A continuación, se incluye un ejemplo de un mensaje de notificación push:
{ "call_id" : 12345, "ujet_noti_type" : "connect_call", "noti_type" : "connect_call", "call_type" : "ScheduledCall", "fail_reason" : "none", "fail_details" : "none" }
Controla el mensaje de 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
}
}
}
Cómo controlar mensajes de 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
}
}
}
Cómo controlar mensajes de GCM en GcmReceiver (método anterior)
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
}
}
}
Inicia la aplicación
Agrega la siguiente línea donde quieras iniciar la aplicación (sin parámetros):
Ujet.start(new UjetStartOptions.Builder().build());
También puedes iniciar el SDK de Android sin la pantalla de presentación.
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setSkipSplashEnabled(true)
.build();
Ujet.start(ujetStartOptions);
También puedes iniciar el SDK de Android desde un punto específico del menú con esta clave a través de un punto de acceso directo:
String menuKey = "MENU_KEY";
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setMenuKey(menuKey)
.build();
Ujet.start(ujetStartOptions);
El menuKey se puede crear con un punto de acceso directo en el portal de CCAI Platform (con el rol de administrador).
Ve a Configuración > Cola.
Selecciona cualquier fila de la estructura del menú.
Marca la casilla de verificación Crear punto de acceso directo.
Ingresa la clave en el formulario de texto.
Haz clic en Guardar.

También puedes iniciar el SDK de Android con un ID de ticket específico para pasarlo al CRM. Este ID de ticket se abrirá cuando se conecte un chat o una llamada.
String ticketId = "TICKET_ID";
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setTicketId(ticketId)
.build();
Ujet.start(ujetStartOptions);
Envía datos personalizados a tu CRM
Los datos personalizados se pueden enviar a los agentes de asistencia y aparecerán en el ticket de asistencia de la llamada o el chat entrantes.
Existen dos métodos para enviar datos personalizados:
Método firmado: Firma de datos predefinida con JWT.
Método sin firma: Datos predefinidos con JSON simple (no recomendado).
Cómo usar el método firmado para enviar datos personalizados
Para enviar datos personalizados con el método firmado, implementa un método de firma.
Primero, recupera los datos personalizados en tu app host y, luego, envíalos a tu servidor para firmarlos. En tu servidor, puedes agregar datos adicionales con un formulario definido. Fírmalos con el secreto de tu empresa y, luego, devuélvelos 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));
}
// ...
}
}
Usa un método sin firma para enviar datos personalizados
Google recomienda que uses el método firmado para enviar datos personalizados en tu aplicación. Para obtener más información, consulta Cómo usar el método firmado para enviar datos personalizados.
Puedes enviar datos sin firmar iniciando el SDK de Android con opciones de inicio para establecer datos personalizados con UjetStartOptions.Builder#setUnsignedCustomData y UjetTokenCallback debe llamar a 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);
Cómo usar datos personalizados sin firmar para enviar transcripciones de chat externas
Puedes enviar la transcripción del chat externo a la plataforma de la CCAI con datos personalizados sin firmar cuando se inicie. Usa UjetCustomData.putObject("external_chat_transfer", hashMapObject) para establecer los datos de la transcripción en formato JSON de la siguiente manera:
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: diccionarioname: stringavatar: Cadena [URL del avatar del agente, opcional]
transcript: arraysender: string ["end_user" or "agent"]timestamp: Cadena [p. ej., "2021-03-15 12:00:00Z"]content: arraytype: Cadena [uno de texto, medios]text: Cadena [obligatoria para el tipo de texto]media: diccionario [obligatorio para el tipo de medio]type: Cadena [una de las opciones: image, video]url: Cadena [URL pública que apunta al archivo multimedia]
Ejemplo 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"
}
]
}
]
}
Puedes usar Markdown en el tipo de texto. Se admiten los siguientes formatos:
Negrita
Cursiva
Subrayar
Saltos de línea
Lista con viñetas
Lista numerada
Vínculos
Formato de datos personalizado
En esta sección, se muestra el formato de los datos personalizados que se pueden pasar en el JWT.
JSON codificado en JWT
El JSON debe incluir iat y exp para validar el JWT. El objeto de los datos personalizados es el valor de la clave 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"
}
}
}
La clave es un identificador único para los datos. El tipo es el tipo de valor.
string- String de JSON
number- número entero, número de punto flotante
date- Es el formato de marca de tiempo de Unix en UTC con 13 dígitos. (contiene milisegundos)
url- Formato de URL HTTP
La etiqueta es el nombre visible en la página del CRM.
Cómo evitar que se muestren datos personalizados
Puedes usar la propiedad invisible_to_agent con un objeto de datos personalizado para evitar que se muestren datos personalizados firmados o sin firmar en el adaptador del agente. En el ejemplo anterior, el número de seguridad social del usuario final no se muestra en el adaptador del agente porque "invisible_to_agent" : true se incluye en el objeto ssn.
Cuando incluyes la propiedad "invisible_to_agent" : true con un objeto de datos personalizado, puedes esperar el siguiente comportamiento:
- Los datos personalizados se incluyen en el archivo de metadatos de la sesión.
- Los datos personalizados no se incluyen en los registros del CRM.
Para obtener más información, consulta Cómo ver los datos de la sesión en el adaptador del agente.
Propiedades de datos reservadas
Puedes enviar propiedades de datos reservadas a Contact Center AI Platform (CCAI Platform) como datos personalizados firmados cuando comienza una sesión. Para obtener más información, consulta Envía propiedades de datos reservadas.
A continuación, se muestra un ejemplo de las propiedades de datos reservadas en los datos 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"
}
}
}
Reemplaza lo siguiente:
VERIFIED_CUSTOMER_BOOLEAN: Es verdadero si consideras que este usuario final es un cliente legítimo.VERIFIED_BAD_ACTOR_BOOLEAN: Es verdadero si consideras que este usuario final podría ser una persona que actúa de mala fe.REPEAT_CUSTOMER_BOOLEAN: Es verdadero si determinaste que este usuario final se comunicó con tu centro de contacto anteriormente.
Configuración del SDK
Puedes configurar varias opciones antes de iniciar el SDK de Android. Consulta la clase UjetOption. Las opciones Número de teléfono de respaldo y Sensibilidad de la red que se describen en la siguiente tabla solo funcionan cuando el botón de activación Habilitar respaldo de PSTN está activado en el portal de la Plataforma de CCAI en Configuración > Configuración para desarrolladores > MMA > Editar. Cuando el botón de activación Enable PSTN Fallback está desactivado, no se realiza el pase a la RTC. La plataforma de la CCAI usa la sensibilidad de red predeterminada (0.85) para verificar las conexiones de red.
| Opción | Descripción | Valor | Valor predeterminado |
|---|---|---|---|
| Nivel de registro | Es el nivel de registro que se imprimirá en Logcat. | Número entero. Lo mismo sucede con el nivel de registro para el registro de Android. (Mín.: 2, Máx.: 7) | 5 (Log.Warn) |
| Idioma predeterminado | Es el código de idioma predeterminado. | String. Es un código de idioma ISO 639. (p.ej., "en" para inglés) | null |
| Número de teléfono de respaldo | El número de teléfono se usa como alternativa cuando no hay conexión a Internet o cuando no existe el número de teléfono del representante de la empresa en el portal de administrador. | String. Número de teléfono. | null |
| Se habilitó el controlador de excepciones no detectadas | Habilita el controlador de excepciones no detectadas. Si es true, la app controla todas las excepciones no detectadas del SDK en el tiempo de ejecución con Thread.setDefaultUncaughtExceptionHandler. Sin embargo, si la misma excepción ocurre dos veces, la app falla. |
Booleano. | true |
| Sensibilidad de la red | Es la sensibilidad para verificar el estado de la red. | Doble entre 0 y 1, donde 0 es el menos sensible y 1 es el más sensible. Un valor de 1 siempre recurrirá a una llamada de RTC. Si se usa, te recomendamos que comiences con un valor de .97. El valor del Portal en Configuración > Configuración para desarrolladores > Apps para dispositivos móviles > Respaldo anula este valor. |
0.85 |
| Se habilitó el modo oscuro | Habilita el tema de modo oscuro. Si es true, el SDK aplica un tema de modo oscuro cuando el usuario activa el modo oscuro y, de lo contrario, ignora la acción. |
Booleano. | false |
| Canal único habilitado | Opción de configuración para mostrar u omitir la pantalla de selección de canales para un solo canal. Si es true, el SDK muestra una sola pantalla de selección de canales en lugar de seleccionar automáticamente el canal, incluso si solo hay un canal habilitado en la fila del menú. |
Booleano. | false |
| Minimizar automáticamente la vista de llamada | Opción de configuración para minimizar automáticamente la IU de la pantalla de llamada inicial de forma predeterminada o esperar a que el usuario la minimice. | Booleano. | false |
| Borde del ícono del agente habilitado | Opción de configuración para mostrar o quitar un borde circular alrededor del ícono del agente. | Booleano. | false |
| Tamaño de fuente estático en la vista del selector | Opción de configuración para ajustar o inhabilitar automáticamente el tamaño del texto del elemento del selector. | Booleano. | false |
| Cómo ocultar archivos adjuntos multimedia en Chat | Opción de configuración para mostrar u ocultar el ícono de adjunto multimedia en la IU del chat. | Booleano. | false |
Ignorar el permiso READ_PHONE_STATE |
Si se configura como true, el SDK no solicita el permiso READ_PHONE_STATE. Si no quieres usar llamadas de IVR integradas en la app, establece esta marca en true para evitar solicitar este permiso. Además, tu aplicación debe quitar explícitamente el permiso android.permission.READ_PHONE_STATE para el SDK de CCAI Platform. Ten en cuenta que no recomendamos establecer este permiso en true, ya que se requiere para que funcionen las llamadas de IVR desde la app. |
Booleano | false |
| Clave de licencia de Cobrowse.io (si corresponde) | Es una opción de configuración para establecer la biblioteca Cobrowse.io. Para encontrar tu clave de licencia de Cobrowse, accede a https://cobrowse.io/dashboard/settings y ve a la sección Clave de licencia. |
String | null |
| Título del encabezado del chat personalizado | Opción de configuración para personalizar el texto del título del encabezado del chat en la IU de chat | String | null |
| Personaliza las respuestas rápidas de la IU del chat | Opción de configuración para personalizar las respuestas rápidas del agente virtual en la IU del chat. Las respuestas rápidas del agente virtual se agrupan de forma predeterminada, pero, si quieres mostrarlas de forma individual, puedes usar esta opción de configuración para establecer QuickReplyButtonsStyle.INDIVIDUAL. | UjetStylesOptions | QuickReplyButtonsStyle.GROUPED |
| Personaliza varios atributos de la IU del chat | Opción de configuración para personalizar varios atributos, como la fuente, el color de fondo, el ícono, etcétera | UjetStylesOptions | null |
| Ocultar la barra de estado | Opción de configuración para mostrar u ocultar la barra de estado. Si el valor es verdadero, el SDK ocultará la barra de estado. | Booleano | false |
| Establece el recurso de diseño del ícono giratorio de carga | Opción de configuración para personalizar la vista del spinner de carga en toda la app. Si no está disponible o es nula, usamos la vista de carga predeterminada. | Número entero | null |
| Se inhabilitó la orientación horizontal | Inhabilita la orientación horizontal. Si el valor es verdadero, no se aplica la orientación horizontal. | Booleano | false |
| Oculta el botón intercalado para iniciar una conversación nueva en el chat | Opción de configuración para mostrar u ocultar el botón intercalado para iniciar una conversación nueva en la IU del chat. | Booleano | false |
| Mostrar el botón para omitir la CSAT | Opción de configuración para mostrar u ocultar el botón para omitir en el diálogo de CSAT | Booleano | false |
| Bloquea la finalización del chat por parte del usuario final | Opción de configuración para mostrar u ocultar el botón para finalizar el chat en la IU del chat | Booleano | false |
| Ocultar la opción para descargar la transcripción del chat | Muestra u oculta el botón para descargar la transcripción del chat en el menú de acciones del chat y en la interfaz de usuario del chat. Si agregas un espacio a la cadena ujet_common_hide, el texto Hide desaparecerá y solo aparecerá la flecha hacia atrás. |
Número entero. Valores:
|
0
|
| Cómo desactivar las notificaciones push a nivel global | Si se configura UjetOption.setPushNotificationsAllowed como false, se omiten todas las dependencias de las notificaciones push y se impide que estas lleguen a los usuarios finales. |
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()
)
Resguardo
Puedes usar UjetErrorListener para la resiliencia ante errores inesperados. Si no estableces este objeto de escucha o devuelves false, el SDK de Android controlará el error.
El SDK de Android redireccionará a los usuarios al marcador con un número de resguardo solo cuando el botón de activación Enable PSTN Fallback esté ACTIVADO en Settings > Developer Settings > MMA > Edit pop-up. De lo contrario, saldrá del SDK.
| Tipo de error | Código de error | Activador |
|---|---|---|
| NETWORK_ERROR | 1 | La red no está disponible. Ten en cuenta que este error no se activa cuando la red no está disponible durante el chat, la llamada o la pantalla de calificación. |
| AUTHENTICATION_ERROR | 100 | Se produjo un error inesperado durante la autenticación. |
| AUTHENTICATION_JWT_ERROR | 101 | Se produjo un error inesperado durante la validación del JWT (p.ej., un error de análisis). |
| VOIP_CONNECTION_ERROR | 1000 | No se pudo establecer una conexión con el proveedor de VoIP. Se controla a través de la devolución de llamada del SDK de VoIP. |
| VOIP_LIBRARY_NOT_FOUND | 1001 | Se espera que la llamada se conecte a través de un proveedor de VoIP, pero no se pudo encontrar uno. Esto podría ocurrir cuando un desarrollador integró el SDK incorrecto o no agregó la biblioteca del proveedor de VoIP en sus dependencias. |
| CHAT_LIBRARY_NOT_FOUND | 1100 | Se produce cuando no se puede encontrar la biblioteca de chat. Esto podría ocurrir cuando un desarrollador integró el SDK incorrecto o no agregó la biblioteca de Twilio Chat en sus dependencias. |
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());
}
});
Permisos de la app
La app requiere los siguientes permisos y los solicita al usuario cuando es necesario.
| Permiso | Descripción |
|---|---|
| CÁMARA | Se usa para la acción inteligente de tomar fotos y grabar videos |
| MICRÓFONO | Permite que la app use llamadas VoIP a través de Twilio |
| ALMACENAMIENTO | Permite que la app guarde fotos y videos |
Configuración de la vinculación directa (opcional)
Si deseas usar acciones inteligentes para una llamada de IVR (PSTN), debes configurar vínculos directos en tu proyecto.
El formato de vínculo directo es un URI único, como el siguiente:
ujet:// <package_name>/smartchannel.
Además, debes configurar este vínculo o cualquier URL que redireccione a él en el Portal del administrador (Configuración > Administración de operaciones > Habilitar el envío de SMS para descargar la app).
Deberás agregar un filtro de intents que contenga el vínculo directo en tu manifiesto.
<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
El parámetro Preferred Channel te permite dirigir a los consumidores directamente a un canal específico. Luego, el usuario final omite el paso de selección del canal y se comunica directamente a través del canal especificado en el parámetro Preferred Channel.
UjetStartOptions.preferredChannel
Ujet.start(new)
UjetStartOptions.Builder().setPreferredChannel
(UjetPreferredChannel.UjetPreferredChannelChat).build());
Notificaciones de eventos
De manera opcional, puedes configurar UjetEventListener para recibir notificaciones de eventos de la aplicación.
Aquí se enumeran los tipos de eventos y las descripciones disponibles.
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 | Descripción | Datos incluidos en el evento |
|---|---|---|
EmailClicked |
Se activa cuando el usuario final hace clic en el canal de correo electrónico. | Datos del menú de la cola |
EmailSubmitted |
Se activa cuando el usuario final envía un correo electrónico. | Datos del menú de la fila, datos enviados por correo electrónico |
SessionPaused |
Se activa cuando el usuario final minimiza una sesión de chat o llamada. | Datos de la sesión |
SessionResumed |
Se activa cuando el usuario final vuelve a una sesión de chat o llamada desde segundo plano. | Datos de la sesión |
SessionCreated |
Se activa cuando se crea una sesión de chat o llamada. | Datos del menú de la fila, datos de la sesión creada |
SessionEnded |
Se activa cuando finaliza una sesión de chat o llamada. | Datos del menú de la fila, datos de la sesión creada y datos de la sesión finalizada |
SdkTerminated |
Se activa cuando se cierra el SDK, incluso cuando se cierra de forma inesperada. | Datos de SDK terminado |
ContentCardClicked |
Se activa cuando se hace clic en una tarjeta de contenido. | Datos de clics en tarjetas de contenido |
ContentCardButtonClicked |
Se activa cuando se hace clic en un botón de tarjeta de contenido. | Datos de clics en botones de tarjetas de contenido |
QuickReplyClicked |
Se activa cuando se hace clic en una respuesta rápida. | Datos de clics en respuestas rápidas |
MessageLinkClicked |
Se activa cuando se hace clic en un vínculo. | Datos de clics en vínculos de mensajes |
Datos del menú de la cola
| Clave | Tipo | Descripción |
|---|---|---|
event_name |
String | Contiene el nombre del evento. Por ejemplo, "Se hizo clic en el correo electrónico". |
application |
String | Contiene el nombre de la aplicación. Por ejemplo, "Android". |
app_id |
String | Contiene el identificador de la app, que es el mismo que Context.getPackageName(). |
app_version |
String | Contiene el nombre y el código de la versión de la app. Por ejemplo, "0.32.0 (123)". |
sdk_version |
String | Contiene la versión del SDK. Por ejemplo, "0.32.0". |
timestamp |
String | Contiene la marca de tiempo en UTC (en formato aaaa-MM-dd'T'HH:mm:ss'Z'). |
device_model |
String | Contiene el modelo del dispositivo del usuario. Por ejemplo, "Google Pixel". |
device_version |
String | Contiene la versión del dispositivo del usuario. Por ejemplo, "10, Q, SDK 29". |
company |
String | Contiene el nombre de la empresa. Por ejemplo, "Empresa". |
menu_name |
String | Contiene el nombre del nodo hoja (última selección del menú del usuario). Por ejemplo, “Submenú”. |
menu_id |
String | Contiene el ID del nodo hoja (última selección del menú del usuario). Por ejemplo, "123". |
menu_path |
String | Contiene la secuencia completa de menús que seleccionó el usuario. Por ejemplo, "Menú principal / secundario / submenú". |
menu_key |
String | Contiene la clave de DAP y es opcional. Por ejemplo, "special_user_menu". |
Datos enviados por correo electrónico
| Clave | Tipo | Descripción |
|---|---|---|
has_attachments |
Booleano | Devuelve True si el correo electrónico tiene archivos adjuntos y False en caso contrario. |
Datos de la sesión
| Clave | Tipo | Descripción |
|---|---|---|
event_name |
String | Contiene el nombre del evento. Por ejemplo, "Se hizo clic en el correo electrónico". |
type |
String | Contiene el tipo de sesión. Por ejemplo, "chat" o "llamada". |
timestamp |
String | Contiene la marca de tiempo en UTC (en formato aaaa-MM-dd'T'HH:mm:ss'Z'). |
Datos de creación de la sesión
| Clave | Tipo | Descripción |
|---|---|---|
session_id |
String | Contiene el ID de sesión. Por ejemplo, “100”. |
type |
String | Contiene el tipo de sesión. Por ejemplo, "chat" o "llamada". |
end_user_identifier |
String | Contiene el identificador del usuario final. Por ejemplo, "Juan". |
messages_end_user |
String | Contiene el recuento de mensajes del usuario final y solo se incluye para la sesión de chat. Por ejemplo, “3”. |
messages_agent |
String | Contiene el recuento de mensajes del agente y solo se incluye para la sesión de chat. Por ejemplo, “3”. |
Datos de finalización de la sesión
| Clave | Tipo | Descripción |
|---|---|---|
agent_name |
String | Contiene el nombre del agente. Por ejemplo, "Juan". |
ended_by |
String | Contiene detalles sobre quién finalizó la sesión. Los valores posibles son "agent" (cuando el agente finaliza la sesión), "end_user" (cuando el usuario finaliza la sesión), "timeout" (cuando se agota el tiempo de espera del chat) o "dismissed" (cuando se descarta el chat). |
duration |
String | Contiene la duración de la sesión en segundos y solo se incluye para la sesión de llamada. Por ejemplo, “30 segundos”. |
Datos de SDK terminado
| Clave | Tipo | Descripción |
|---|---|---|
event_name |
String | Contiene el nombre del evento. Por ejemplo, "Se hizo clic en el correo electrónico". |
Datos de clics en tarjetas de contenido
| Clave | Tipo | Descripción |
|---|---|---|
title |
cadena | Es el título de la tarjeta. |
title |
cadena | Es el título de la tarjeta. |
subtitle |
cadena | Es el subtítulo de la tarjeta. |
body |
cadena | Es la descripción de la tarjeta de contenido. |
link | cadena | Es un vínculo a una página web o un vínculo directo. El SDK usa las capacidades del SO para abrirlo. |
event_params | dictionary | Diccionario que contiene información adicional sobre el evento de clic. El SDK usa este valor. |
Datos de clics en botones de tarjetas de contenido
| Clave | Tipo | Descripción |
|---|---|---|
title |
cadena | Es el título de la tarjeta. |
title |
cadena | Es el título de la tarjeta. |
link | cadena | Es un vínculo a una página web o un vínculo directo. El SDK usa las capacidades del SO para abrirlo. |
event_params | dictionary | Diccionario que contiene información adicional sobre el evento de clic. El SDK usa este valor. |
Datos de clics en respuestas rápidas
| Clave | Tipo | Descripción |
|---|---|---|
title |
cadena | Es el título de la tarjeta. |
title |
cadena | Es el título de la tarjeta. |
link | cadena | Es un vínculo a una página web o un vínculo directo. El SDK usa las capacidades del SO para abrirlo. |
event_params | dictionary | Diccionario que contiene información adicional sobre el evento de clic. El SDK usa este valor. |
Datos de clics en vínculos de mensajes
| Clave | Tipo | Descripción |
|---|---|---|
event_name |
String | Contiene el nombre del evento, por ejemplo, "Se hizo clic en el vínculo del mensaje". |
link |
String | Un vínculo a una página web o un vínculo directo El SDK usa las capacidades del SO para abrirlo. |
Cambios en el comportamiento de las llamadas entrantes
A partir de los dispositivos con la versión de Android 10, los usuarios finales no recibirán llamadas entrantes directamente cuando la app host esté en segundo plano. En su lugar, usamos notificaciones para alertar a los usuarios sobre las llamadas entrantes (incluso cuando el teléfono está bloqueado) y darles la opción de aceptar o rechazar la llamada.
Mostramos las mismas notificaciones cuando la app host está en segundo plano y la pantalla está bloqueada antes de que llegue la llamada entrante. Este cambio de comportamiento se debe a las restricciones recientes de Google para iniciar actividades cuando la app está en segundo plano. El comportamiento no se ve afectado cuando la app host está en primer plano o se ejecuta en dispositivos con versiones anteriores a Android 10.
Personaliza la sesión del SDK
En esta sección, se describe cómo se puede personalizar aún más el SDK.
Verifica si hay una sesión existente
Antes de iniciar una sesión, usa el método descrito para verificar si hay alguna sesión existente o en curso. Además, si existe, puedes pedirle al usuario final que la reanude o la cancele.
Esto es especialmente importante cuando se cambia un usuario.
if (Ujet.getStatus() != UjetStatus.None) {
// Display alert to cancel login or resume existing session
}
Desconectar la sesión
Consulta el método si quieres desconectar cualquier sesión en curso.
Antes de usar este método, asegúrate de verificar si existe una sesión de este tipo con Ujet.getStatus(). Si deseas realizar una o más acciones después de que el SDK desconecte la sesión, por ejemplo, mostrar un mensaje o cerrar la app, puedes usar la devolución de llamada de respuesta onFinished() como se explica en la siguiente sección. De lo contrario, establece la devolución de llamada como nula.
Ujet.disconnect(new UjetResponseCallback() {
@Override
public void onFinished() {
// `onFinished()` is triggered after CCAI Platform disconnects the session.
finish(); // Finishes the activity.
}
});
Borra los datos del usuario final de la caché
Eres responsable de borrar la caché cuando se actualizan o cambian los datos relacionados con el usuario final desde tu app. Por ejemplo, si el usuario final cerró su sesión, invoca el método para quitar la caché de ese usuario de modo que se inicie una nueva sesión para el nuevo usuario final en el próximo inicio del SDK.
Ujet.clearUserData();
Oculta el SDK
Puedes ocultar el SDK con el método Ujet.hideSDK(). Esto es útil cuando el SDK interfiere con la interfaz de usuario de tu app, por ejemplo. Inicializa el SDK con Ujet.init() antes de llamar a este método. Ujet.init() devuelve true si el SDK se ocultó correctamente y false en caso contrario. Después de ocultar el SDK, puedes volver a iniciarlo con el método Ujet.start().
En el siguiente ejemplo, se oculta el SDK:
Ujet.hideSDK();
Preferencia de idioma
El SDK de Android usará el siguiente orden de prioridad para determinar el idioma.
Idioma seleccionado en la pantalla de presentación de la app.
El idioma predeterminado se selecciona con
UjetOptions. Puedes configurar el idioma predeterminado consetDefaultLanguage("en")enUjetOptions. Consulta el idioma predeterminado en la sección de configuración del SDK para obtener más detalles.Se usará el idioma del dispositivo seleccionado en el dispositivo (con Configuración > General > Idioma) cuando la app lo admita.
Se usará el dialecto más cercano al idioma del dispositivo cuando la app no admita el idioma del dispositivo, pero sí admita su dialecto principal más cercano. Por ejemplo, si el usuario seleccionó español (Cuba) como el idioma en el dispositivo y la app no admite español (Cuba), pero sí admite el dialecto principal español, se usará el idioma español.
Se usará el inglés como idioma predeterminado cuando la app no admita el idioma del dispositivo.
Configura los íconos de vínculos de desviación externos
Personaliza el ícono en el canal de vínculos de redireccionamiento externo. Para ello, sube el ícono a una carpeta de elementos de diseño de tu app y asegúrate de usar el mismo nombre de ícono cuando crees el vínculo de redireccionamiento externo en el portal de la Plataforma de CCAI en Configuración > Chat > Vínculos de redireccionamiento externo > Ver vínculos > Agregar vínculo de redireccionamiento.
Si el nombre del ícono en el portal de la Plataforma de CCAI no coincide con el ícono subido a la app, el SDK de Android usará el ícono predeterminado.
Configura el ícono de agradecimiento de las encuestas
Puedes personalizar o anular el ícono en la página de agradecimiento de la encuesta. Para ello, sube un ícono a la carpeta de elementos de diseño de tu app y usa el nombre de archivo ujet_survey_thank_you_icon como nombre del ícono.
Personalizar (opcional)
En esta sección, se describe cómo personalizar valores específicos dentro del SDK.
Strings
Puedes personalizar las cadenas que se usan en la aplicación reemplazando las claves de cada cadena en 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>

Personalización del tamaño del texto
Personaliza el título, la descripción y el tamaño del texto del selector que se usan en la aplicación reemplazando las siguientes claves en dimens.xml.
Se describen los tamaños de texto personalizables:
<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
Sigue estos pasos para personalizar el tema y el fondo. El paso 1 es para el tema y el paso 2 es para el fondo.
Personaliza el tema anulando las claves de cada elemento de estilo en style.xml. Por ejemplo:
<!--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>Puedes personalizar el color de fondo en la aplicación anulando las claves de cada elemento de estilo en style.xml. En la captura de pantalla, se muestra el color de fondo personalizable.
<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>
Cómo personalizar el título del encabezado del chat
Hay opciones disponibles para personalizar el texto del título del encabezado del chat en la IU.
Puedes personalizar el texto del título del encabezado del chat con las siguientes opciones:
<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>
Puedes personalizar las respuestas rápidas del agente virtual en la IU del chat con las siguientes opciones:
<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>
Tarjetas de contenido
Puedes agregar personalización para las tarjetas de contenido junto con la personalización del chat. Puedes hacerlo con el archivo JSON (consulta content_card property en el archivo app/src/main/assets/json/ujet_styles.json) o con la clase 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 del formulario web
Puedes personalizar la tarjeta del formulario web junto con la personalización del chat. Puedes hacerlo con el archivo JSON (consulta la propiedad form_card en el archivo app/src/main/assets/json/ujet_styles.json) o con la clase 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,
),
)
)
Encuestas
Puedes cambiar el ícono en la página de agradecimiento de la encuesta. Para ello, sube un ícono a la carpeta de elementos de diseño de tu app.
Asegúrate de usar ujet_survey_thank_you_icon como nombre del ícono.
Soluciona problemas
El inicio de un chat nuevo tardó más de 30 segundos.
Verifica si estás respondiendo a un método delegado de datos personalizados. Debes devolver datos personalizados válidos cuando se soliciten o simplemente devolver un valor nulo con una devolución de llamada. Usa el siguiente código como referencia.
@Override
public void onSignPayloadRequest(Map<String, Object> payload, UjetPayloadType ujetPayloadType, UjetTokenCallback tokenCallback) {
if (ujetPayloadType == UjetPayloadType.CustomData) {
tokenCallback.onToken(null);
}
}
Explicación de la declaración de política
Si recibes una notificación en Google Play Console en la que se te solicita que declares una política para los servicios o permisos que usa el SDK de Android, usa una de las siguientes explicaciones.
Declara los servicios en primer plano que usa el SDK de Android
Google introdujo los tipos de servicios en primer plano en Android 14 y exigió que se especificaran al iniciar los servicios en primer plano, según https://developer.android.com/about/versions/14/changes/fgs-types-required#remote-messaging. El SDK de Android de Contact Center AI Platform (CCAI Platform) usa servicios en primer plano para iniciar chats y llamadas, por lo que usamos el tipo de servicio FOREGROUND_SERVICE_REMOTE_MESSAGING para el chat, ya que trabajamos con mensajes de texto, y el tipo de servicio FOREGROUND_SERVICE_MICROPHONE para las llamadas. Sin estos tipos de servicios, el SDK fallará al iniciar el chat o la llamada en dispositivos con la versión de Android 14.
Declara el permiso de intent de pantalla completa que usa el SDK de Android
Se requiere el permiso USE_FULL_SCREEN_INTENT para mostrar notificaciones push de llamadas entrantes cuando el dispositivo está bloqueado. Alerta al usuario final y muestra la notificación de llamada entrante en pantalla completa (así es como la app de teléfono integrada notifica la llamada entrante al usuario final).
Compatibilidad con Android 15
Para admitir Android 15, sigue estos pasos:
Establece
compileSdkVersion = 35ytargetSdkVersion = 35en tubuild.gradle(:app).Asegúrate de que la versión del complemento de Android para Gradle (AGP) de tu proyecto sea 8.5.1 o posterior. Para obtener más información, consulta Actualiza el empaquetado de tus bibliotecas compartidas.
Instala el Java Development Kit (JDK) versión 17 o posterior para compilar proyectos de Android con AGP 8.0 o posterior. Para obtener más información, consulta Se requiere JDK 17 para ejecutar AGP 8.0.