Auf dieser Seite wird die Verwendung des Android SDK erläutert.
Auf die Beispiel-App zugreifen
Klicken Sie auf Android-Beispiel-App, um die Android-Beispiel-App herunterzuladen.
Wenn Sie eine Beispiel-App mit dem Android Mobile SDK erstellen möchten, benötigen Sie Folgendes:
Unternehmensschlüssel und Unternehmens-Secret des CCAI Platform-Portals.
Android 5.0 (API-Level 21, Lollipop) oder höher
Firebase Cloud Messaging oder Google Cloud Messaging für die Push-Benachrichtigung.
Die App wurde zu AndroidX migriert.
Anforderungen für das Upgrade des Twilio SDK
Wenn das Android SDK direkt über unser Paket eingebunden wird, muss das Twilio SDK bestimmte Versionen haben. Andernfalls kann dies ignoriert werden.
// Twilio VoIP SDK
api 'com.twilio:voice-android:6.1.1'
// Twilio Conversations SDK
api 'com.twilio:conversations-android:3.1.0'
Darüber hinaus sind ProGuard-Regeln bereits im Android SDK enthalten, um sicherzustellen, dass die Twilio Programmable Voice-Bibliothek nicht von ProGuard entfernt wird. Sie können zur Fehlerbehebung verwendet werden, falls ProGuard die Bibliothek versehentlich entfernt.
-keep class com.twilio.** { *; }
-keep class tvo.webrtc.** { *; }
-dontwarn tvo.webrtc.**
-keep class com.twilio.voice.** { *; }
-keepattributes InnerClasses
Um die neuesten Twilio-Versionen zu unterstützen, ist das SDK ab der Android SDK-Version 0.34.0 nicht mehr binärkompatibel mit Anwendungen, die auf Java 7 ausgerichtet sind. Damit Entwickler diese und zukünftige Releases verwenden können, müssen sie ihre Anwendungen auf Java 8 aktualisieren. Hier ein Codebeispiel:
android {
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
Unternehmensschlüssel und Unternehmens-Secret abrufen
Melden Sie sich mit Ihren Administratoranmeldedaten im Admin-Portal an.
Gehen Sie zu Einstellungen > Entwicklereinstellungen > Unternehmensschlüssel und Geheimcode.
Rufen Sie den Unternehmensschlüssel und den geheimen Unternehmenscode ab.
Installation
Fügen Sie das Android SDK-Repository der Gradle-Einstellung für das Stammprojekt hinzu.
build.gradle (Project)
allprojects {
repositories {
google()
jcenter()
maven {
url "https://sdk.ujet.co/android/"
}
}
}
build.gradle (Modul: 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"
}
Unternehmenseinstellungen einrichten
Geben Sie die Einstellungen Ihres Unternehmens als Metadaten in die Datei „AndroidManifest.xml“ ein.
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>
JWT-Signatur
Aus Sicherheitsgründen müssen die Informationen eines Endnutzers auf deinem Server als JWT signiert werden.
Die Beispiel-App enthält APIManager zum Testen. Sie müssen UJET_COMPANY_SECRET in mock/APIManager.java einfügen. APIManager muss eine Methode implementieren, die einen asynchronen Aufruf zum Signieren des JWT-Authentifizierungstokens initiiert, das das Token zurückgibt.
In der Produktion müssen Sie den Signaturprozess auf Ihrem Server implementieren.
public class APIManager {
public static final String UJET_COMPANY_SECRET = "Please input your UJET_COMPANY_SECRET from Ujet developer admin page";
// ...
}
SDK initialisieren
Initialisieren Sie das SDK in der Methode onCreate der Android-App-Klasse.
public class ExampleApplication extends Application implements UjetRequestListener {
@Override
public void onCreate() {
super.onCreate();
Ujet.init(this);
}
// ...
}
Endnutzerauthentifizierung
Der Endnutzer ist der Kunde, der Ihr Kundensupportteam über die Anwendung kontaktiert.
Zur Authentifizierung des Endnutzers in der Anwendung führen wir einen JWT-Signierungsmechanismus ein.
Das Android SDK fordert zum Signieren der Nutzlast auf, wenn eine Authentifizierung erforderlich ist. Wenn die Signierung erfolgreich ist, tauscht die Anwendung das signierte JWT gegen das Authentifizierungstoken des Endnutzers aus.
In ExampleApplication sollten Sie die Schnittstelle UjetRequestListener zum Signieren des Authentifizierungstokens und für benutzerdefinierte Daten implementieren.
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();
}
});
}
}
}
Weitere Informationen finden Sie unter Endnutzerauthentifizierung.
Push-Benachrichtigungen einrichten
In diesem Abschnitt wird beschrieben, wie Sie Push-Benachrichtigungen auf Mobilgeräten aktivieren.
Firebase vorbereiten
Sie sollten ein Firebase-Projekt vorbereiten.
Wenn Sie bereits ein Projekt haben, können Sie dieses verwenden und diesen Vorgang überspringen.
Erstellen Sie ein Firebase-Projekt in der Firebase Console.
Laden Sie „google-services.json“ in der Firebase Console unter „Einstellungen“ > „ALLGEMEIN“ herunter.

- Rufen Sie den Serverschlüssel in der Firebase Console unter „Einstellungen“ > „CLOUD MESSAGING“ ab.

Dienstkontoschlüssel hinzufügen
Sie müssen Ihrer mobilen App einen Dienstkontoschlüssel hinzufügen, um Push-Benachrichtigungen zu erhalten. Informationen zum Abrufen eines Dienstkontoschlüssels finden Sie unter Mit einem Dienstkonto authentifizieren.
So fügen Sie Ihrer mobilen App einen Dienstkontoschlüssel hinzu:
Klicken Sie im CCAI Platform-Portal auf Einstellungen > Entwicklereinstellungen. Wenn Sie das Menü Einstellungen nicht sehen, klicken Sie auf das Dreistrich-Menü .
Rufen Sie den Bereich Mobile Apps auf.
Klicken Sie neben Ihrer App auf Bearbeiten. Das Dialogfeld Mobile App bearbeiten wird angezeigt.
Geben Sie im Feld Dienstkonto Ihren Dienstkontoschlüssel ein und klicken Sie dann auf Speichern.
Android-Client einrichten
Kopieren Sie
google-services.jsonin Ihr Anwendungsverzeichnis, z. B.PROJECT_ROOT/app/google-services.json.Rufen Sie das
FCM-Token mit dem folgenden Code ab: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); });FirebaseMessagingServicewird aufgerufen, das im Manifest registriert ist, wenn das Token aktualisiert wird. Weitere Informationen finden Sie unter Firebase Cloud Messaging-Client-App unter Android einrichten.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); } }Implementieren Sie
UjetRequestListener.onRequestPushTokenin Ihrer Anwendungsklasse.UjetRequestListener.onRequestPushTokensollte das TokenFCM/GCMzurückgeben.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 -> { }) } }Push-Benachrichtigung verarbeiten. Wenn Sie möchten, dass die Contact Center AI Platform (CCAI Platform) die Verarbeitung ihrer eigenen Push-Nachrichten übernimmt, können Sie die Daten direkt an
UjetPushHandler.handle()übergeben.Die Anwendung verarbeitet nur Nachrichten, bei denen das Feld
ujet_noti_type(odernoti_typefür die Abwärtskompatibilität) festgelegt ist.Andernfalls können Sie festlegen, dass nur Nachrichten mit
ujet_noti_typezur Verarbeitung anUjetPushHandler.handle()gesendet werden.
Hier siehst du ein Beispiel für eine Push-Benachrichtigung:
{ "call_id" : 12345, "ujet_noti_type" : "connect_call", "noti_type" : "connect_call", "call_type" : "ScheduledCall", "fail_reason" : "none", "fail_details" : "none" }
FCM-Nachricht verarbeiten
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
}
}
}
GCM-Nachricht verarbeiten
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
}
}
}
GCM-Nachricht in GcmReceiver verarbeiten (alte Methode)
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
}
}
}
Anwendung starten
Fügen Sie die folgende Zeile an der Stelle ein, an der Sie die Anwendung starten möchten (ohne Parameter):
Ujet.start(new UjetStartOptions.Builder().build());
Sie können das Android SDK auch ohne den Splash Screen starten.
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setSkipSplashEnabled(true)
.build();
Ujet.start(ujetStartOptions);
Sie können das Android SDK auch von einem bestimmten Punkt im Menü mit dieser Taste über einen Direktzugriffspunkt starten:
String menuKey = "MENU_KEY";
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setMenuKey(menuKey)
.build();
Ujet.start(ujetStartOptions);
Der menuKey kann mit einem Direct Access Point im CCAI Platform-Portal (mit Administratorrolle) erstellt werden.
Gehen Sie zu Einstellungen > Warteschlange.
Wählen Sie eine beliebige Warteschlange aus der Menüstruktur aus.
Klicken Sie auf Direkten Zugriffspunkt erstellen.
Geben Sie den Schlüssel in das Textfeld ein.
Klicken Sie auf Speichern.

Sie können das Android SDK auch mit einer bestimmten Ticket-ID starten, um es an das CRM zu übergeben. Diese Ticket-ID wird geöffnet, wenn ein Chat oder Anruf verbunden wird.
String ticketId = "TICKET_ID";
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setTicketId(ticketId)
.build();
Ujet.start(ujetStartOptions);
SDK-Konfiguration
Sie können mehrere Optionen konfigurieren, bevor Sie das Android SDK starten. Weitere Informationen finden Sie unter der Klasse UjetOption. Die in der folgenden Tabelle beschriebenen Optionen „Fallback-Telefonnummer“ und „Netzwerkempfindlichkeit“ funktionieren nur, wenn die Ein/Aus-Schaltfläche PSTN-Fallback aktivieren im CCAI Platform-Portal unter Einstellungen > Entwicklereinstellungen > MMA > Bearbeiten aktiviert ist. Wenn die Ein/Aus-Schaltfläche PSTN-Fallback aktivieren deaktiviert ist, wird kein Fallback auf PSTN durchgeführt. Die CCAI Platform verwendet die Standardnetzwerkempfindlichkeit (0,85) zum Prüfen von Netzwerkverbindungen.
| Option | Beschreibung | Wert | Standardwert |
|---|---|---|---|
| Protokollebene | Logebene, die in Logcat ausgegeben werden soll. | Ganzzahl. Dasselbe gilt für die Logebene für Android-Logs. (Min.: 2, Max.: 7) | 5 (Log.Warn) |
| Standardsprache | Der Standardsprachcode. | String. Ein Sprachcode gemäß ISO 639. (z.B. „en“ für Englisch) | null |
| Fallback-Telefonnummer | Die Telefonnummer wird als Fallback verwendet, wenn das Internet nicht verfügbar ist oder die repräsentative Telefonnummer für das Unternehmen im Admin-Portal nicht vorhanden ist. | String. Telefonnummer. | null |
| Handler für nicht abgefangene Ausnahmen aktiviert | Aktivieren Sie den Handler für nicht abgefangene Ausnahmen. Wenn true, verarbeitet die App alle nicht abgefangenen SDK-Ausnahmen zur Laufzeit mit Thread.setDefaultUncaughtExceptionHandler. Wenn dieselbe Ausnahme jedoch zweimal auftritt, stürzt die App ab. |
Boolescher Wert. | true |
| Netzwerksensitivität | Die Empfindlichkeit für die Prüfung des Netzwerkstatus. | Double zwischen 0 und 1, wobei 0 die geringste und 1 die höchste Empfindlichkeit ist. Bei einem Wert von 1 wird immer auf einen PSTN-Anruf zurückgegriffen. Wenn Sie diesen Parameter verwenden, empfehlen wir, mit dem Wert .97 zu beginnen. Der Wert im Portal unter Einstellungen > Entwicklereinstellungen > Mobile Apps > Fallback-Telefonnummer überschreibt diesen Wert. |
0.85 |
| Dunkler Modus aktiviert | Aktivieren Sie das dunkle Design. Wenn true, wendet das SDK ein Design für den dunklen Modus an, wenn der Nutzer den dunklen Modus aktiviert. Andernfalls wird die Aktion ignoriert. |
Boolescher Wert. | false |
| Einzelner Kanal aktiviert | Konfigurationsoption, um den Bildschirm für die Kanalauswahl für einen einzelnen Kanal entweder anzuzeigen oder zu umgehen. Wenn true, zeigt das SDK einen Bildschirm zur Auswahl eines einzelnen Kanals an, anstatt den Kanal automatisch auszuwählen, auch wenn nur ein Kanal in der Menüwarteschlange aktiviert ist. |
Boolescher Wert. | false |
| Anrufansicht automatisch minimieren | Konfigurationsoption, um die Benutzeroberfläche des ersten Anrufbildschirms standardmäßig automatisch zu minimieren oder zu warten, bis der Nutzer sie minimiert. | Boolescher Wert. | false |
| Rahmen für Agentensymbol aktiviert | Konfigurationsoption zum Ein- oder Ausblenden eines runden Rahmens um das Agentensymbol. | Boolescher Wert. | false |
| Statische Schriftgröße in der Auswahlansicht | Konfigurationsoption zum automatischen Anpassen oder Deaktivieren der Textgröße für die Auswahl. | Boolescher Wert. | false |
| Medienanhang im Chat ausblenden | Konfigurationsoption zum Ein- oder Ausblenden des Symbols für Medienanhänge in der Chat-Benutzeroberfläche. | Boolescher Wert. | false |
Berechtigung „READ_PHONE_STATE“ ignorieren |
Wenn der Wert auf true gesetzt ist, fordert das SDK die Berechtigung READ_PHONE_STATE nicht an. Wenn Sie keine In-App-IVR-Anrufe verwenden möchten, setzen Sie dieses Flag auf true, um die Anforderung dieser Berechtigung zu vermeiden. Außerdem muss Ihre Anwendung die Berechtigung android.permission.READ_PHONE_STATE für das CCAI Platform SDK explizit entfernen. Wir empfehlen, diese Berechtigung nicht auf true festzulegen, da sie für IVR-Anrufe in der App erforderlich ist. |
Boolesch | false |
| Cobrowse.io-Lizenzschlüssel (falls zutreffend) | Konfigurationsoption zum Einrichten der Cobrowse.io-Bibliothek. Sie finden Ihren Cobrowse-Lizenzschlüssel, indem Sie sich in https://cobrowse.io/dashboard/settings anmelden und den Bereich Lizenzschlüssel aufrufen. |
String | null |
| Benutzerdefinierter Titel für die Kopfzeile des Chats | Konfigurationsoption zum Anpassen des Titels der Chatkopfzeile in der Chat-UI. | String | null |
| Kurzantworten in der Chat-Benutzeroberfläche anpassen | Konfigurationsoption zum Anpassen der Kurzantworten des virtuellen Kundenservicemitarbeiters in der Chat-Benutzeroberfläche. Kurzantworten des virtuellen Kundenservicemitarbeiters werden standardmäßig gruppiert. Wenn Sie sie einzeln anzeigen möchten, können Sie diese Konfigurationsoption verwenden, um QuickReplyButtonsStyle.INDIVIDUAL festzulegen. | UjetStylesOptions | QuickReplyButtonsStyle.GROUPED |
| Verschiedene Attribute der Chat-Benutzeroberfläche anpassen | Konfigurationsoption zum Anpassen verschiedener Attribute wie Schriftart, Hintergrundfarbe, Symbol usw. | UjetStylesOptions | null |
| Statusleiste ausblenden | Konfigurationsoption zum Ein- oder Ausblenden der Statusleiste. Wenn der Wert „true“ ist, wird die Statusleiste vom SDK ausgeblendet. | Boolesch | false |
| Drawable-Ressource für rotierendes Ladesymbol festlegen | Konfigurationsoption zum Anpassen der Ladeanzeige in der App. Wenn sie nicht verfügbar oder null ist, wird die Standardladeanzeige verwendet. | Ganzzahl | null |
| Querformat deaktiviert | Deaktivieren Sie das Querformat. Wenn der Wert „true“ ist, wird das Querformat nicht angewendet. | Boolesch | false |
| Inline-Schaltfläche „Neue Unterhaltung starten“ im Chat ausblenden | Konfigurationsoption zum Ein- oder Ausblenden der Inline-Schaltfläche „Neue Unterhaltung starten“ in der Chat-Benutzeroberfläche. | Boolesch | false |
| Schaltfläche zum Überspringen der CSAT-Umfrage anzeigen | Konfigurationsoption zum Ein- oder Ausblenden der Schaltfläche „Überspringen“ im CSAT-Dialog | Boolesch | false |
| Beenden des Chats durch Endnutzer blockieren | Konfigurationsoption zum Ein- oder Ausblenden der Schaltfläche „Chat beenden“ in der Chat-Benutzeroberfläche | Boolesch | false |
| Chattranskript herunterladen ausblenden | Schaltfläche zum Herunterladen des Chatprotokolls im Menü für Chataktionen und auf der Benutzeroberfläche des Chats ein- oder ausblenden. Wenn Sie dem String ujet_common_hide ein Leerzeichen hinzufügen, wird der Text Hide nicht mehr angezeigt und nur der Zurückpfeil ist zu sehen. |
Ganzzahl. Werte:
|
0
|
| Push-Benachrichtigungen auf globaler Ebene deaktivieren | Wenn UjetOption.setPushNotificationsAllowed auf false gesetzt ist, werden alle Push-Benachrichtigungsabhängigkeiten umgangen und Push-Benachrichtigungen werden nicht an Endnutzer gesendet. |
Boolesch | true |
| Nächste Verfügbarkeit ausblenden | Die Nachricht Nächste Verfügbarkeit auf dem Bildschirm Chat-Check-in außerhalb der Geschäftszeiten ein- oder ausblenden. | Boolesch | false |
| Neu beginnen ausblenden | Hier können Sie die Schaltfläche Neu starten auf dem Bildschirm Chat-Check-in außerhalb der Geschäftszeiten ein- oder ausblenden. | Boolesch | false |
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)
.setHideNextAvailability(true)
.setHideStartOver(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()
)
App-Berechtigungen
Die App benötigt die folgenden Berechtigungen und fordert sie bei Bedarf vom Nutzer an.
| Berechtigung | Beschreibung |
|---|---|
| KAMERA | Wird für die Smart-Aktion zum Aufnehmen von Fotos und Videos verwendet |
| MIKROFON | Ermöglicht der App, VoIP-Anrufe über Twilio zu tätigen |
| Speicherplatz | Ermöglicht der App, Fotos und Videos zu speichern |
Spracheinstellung
Das Android SDK verwendet die folgende Prioritätsreihenfolge, um die Sprache zu bestimmen.
Die Sprache, die auf dem Splash Screen in der App ausgewählt wurde.
Standardsprache ausgewählt mit
UjetOptions. Sie können die Standardsprache mitsetDefaultLanguage("en")inUjetOptionsfestlegen. Weitere Informationen finden Sie im Abschnitt zur SDK-Konfiguration unter „Standardsprache“.Die auf dem Gerät ausgewählte Gerätesprache (unter Einstellungen > Allgemein > Sprache) wird verwendet, wenn sie von der App unterstützt wird.
Der nächstgelegene Dialekt der Gerätesprache wird verwendet, wenn die App die Gerätesprache nicht unterstützt, aber den nächstgelegenen übergeordneten Dialekt. Wenn der Nutzer beispielsweise Spanisch (Kuba) als Sprache auf dem Gerät ausgewählt hat und die App Spanisch (Kuba) nicht unterstützt, aber den übergeordneten Dialekt Spanisch, wird die spanische Sprache verwendet.
Wenn die Gerätesprache von der App nicht unterstützt wird, wird standardmäßig Englisch verwendet.
Bevorzugter Kanal
Mit dem Parameter „Bevorzugter Kanal“ können Sie Nutzer direkt zu einem bestimmten Kanal weiterleiten. Der Endnutzer überspringt dann den Schritt zur Kanalauswahl und initiiert den Kontakt direkt über den im Parameter „Bevorzugter Kanal“ angegebenen Kanal.
UjetStartOptions.preferredChannel
Ujet.start(new)
UjetStartOptions.Builder().setPreferredChannel
(UjetPreferredChannel.UjetPreferredChannelChat).build());
Terminbenachrichtigungen
Sie können optional UjetEventListener festlegen, um Ereignisbenachrichtigungen zu erhalten.
Hier finden Sie eine Liste der verfügbaren Ereignistypen und Beschreibungen.
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());
}
});
| Ereignistyp | Beschreibung | Im Ereignis enthaltene Daten |
|---|---|---|
EmailClicked |
Wird ausgelöst, wenn der Endnutzer auf den E-Mail-Kanal klickt. | Daten für Speisekarten in die Warteschlange stellen |
EmailSubmitted |
Wird ausgelöst, wenn der Endnutzer eine E‑Mail sendet. | Menüdaten in die Warteschlange stellen, per E-Mail gesendete Daten |
SessionPaused |
Wird ausgelöst, wenn der Endnutzer eine Chat- oder Anrufsitzung minimiert. | Sitzungsdaten |
SessionResumed |
Wird ausgelöst, wenn der Endnutzer aus dem Hintergrund zu einer Chat- oder Anrufsitzung zurückkehrt. | Sitzungsdaten |
SessionCreated |
Wird ausgelöst, wenn eine Chat- oder Anrufsitzung erstellt wird. | Daten zum Warteschlangenmenü, Daten zur Sitzungserstellung |
SessionEnded |
Wird ausgelöst, wenn eine Chat- oder Anrufsitzung beendet wird. | Daten zum Warteschlangenmenü, Daten zur Sitzungserstellung, Daten zum Sitzungsende |
SdkTerminated |
Wird ausgelöst, wenn das SDK geschlossen wird, auch wenn es unerwartet geschlossen wird. | SDK-Daten gelöscht |
ContentCardClicked |
Wird ausgelöst, wenn auf eine Inhaltskarte geklickt wird. | Daten zu Klicks auf Inhaltskarten |
ContentCardButtonClicked |
Wird ausgelöst, wenn auf eine Schaltfläche auf einer Inhaltskarte geklickt wird. | Daten zu Klicks auf Buttons in Content-Karten |
QuickReplyClicked |
Wird ausgelöst, wenn auf eine Kurzantwort geklickt wird. | Daten zu angeklickten Kurzantworten |
MessageLinkClicked |
Wird ausgelöst, wenn auf einen Link geklickt wird. | Daten zu Klicks auf Nachrichtenlinks |
Daten für Speisekarten in die Warteschlange stellen
| Schlüssel | Typ | Beschreibung |
|---|---|---|
event_name |
String | Enthält den Ereignisnamen. Beispiel: „E-Mail angeklickt“. |
application |
String | Enthält den Anwendungsnamen. Beispiel: „Android“. |
app_id |
String | Enthält die App-ID, die mit Context.getPackageName() übereinstimmt. |
app_version |
String | Enthält den Namen und den Code der App-Version. Beispiel: „0.32.0 (123)“. |
sdk_version |
String | Enthält die SDK-Version. Beispiel: „0.32.0“. |
timestamp |
String | Enthält den Zeitstempel in UTC (im Format jjjj-MM-tt'T'HH:mm:ss'Z'). |
device_model |
String | Enthält das Gerätemodell des Nutzers. Beispiel: „Google Pixel“. |
device_version |
String | Enthält die Version des Nutzergeräts. Beispiel: „10, Q, SDK 29“. |
company |
String | Enthält den Namen des Unternehmens. Beispiel: „Unternehmen“. |
menu_name |
String | Enthält den Namen des Blattknotens (letzte Menüauswahl des Nutzers). Beispiel: „Untermenü“. |
menu_id |
String | Enthält die ID des Blattknotens (letzte Menüauswahl des Nutzers). Beispiel: „123“. |
menu_path |
String | Enthält die vollständige Abfolge der vom Nutzer ausgewählten Menüs. Beispiel: „Übergeordnetes Element / Untergeordnetes Element / Untermenü“. |
menu_key |
String | Enthält den DAP-Schlüssel und ist optional. Beispiel: „special_user_menu“. |
E-Mail-Adresse für gesendete Daten
| Schlüssel | Typ | Beschreibung |
|---|---|---|
has_attachments |
Boolesch | Gibt „True“ zurück, wenn die E‑Mail Anhänge enthält, andernfalls „False“. |
Sitzungsdaten
| Schlüssel | Typ | Beschreibung |
|---|---|---|
event_name |
String | Enthält den Ereignisnamen. Beispiel: „E-Mail angeklickt“. |
type |
String | Enthält den Sitzungstyp. Beispiel: „Chat“ oder „Anruf“. |
timestamp |
String | Enthält den Zeitstempel in UTC (im Format jjjj-MM-tt'T'HH:mm:ss'Z'). |
Daten zur Sitzungserstellung
| Schlüssel | Typ | Beschreibung |
|---|---|---|
session_id |
String | Enthält die Sitzungs-ID. Beispiel: „100“. |
type |
String | Enthält den Sitzungstyp. Beispiel: „Chat“ oder „Anruf“. |
end_user_identifier |
String | Enthält die Endnutzer-ID. Beispiel: „Melanie“. |
messages_end_user |
String | Enthält die Anzahl der Nachrichten von Endnutzern und wird nur für Chatsitzungen berücksichtigt. Beispiel: „3“. |
messages_agent |
String | Enthält die Anzahl der Agentennachrichten und ist nur für Chatsitzungen enthalten. Beispiel: „3“. |
Daten zur beendeten Sitzung
| Schlüssel | Typ | Beschreibung |
|---|---|---|
agent_name |
String | Enthält den Namen des KI-Agenten. Beispiel: „Melanie“. |
ended_by |
String | Enthält Details dazu, wer die Sitzung beendet hat. Mögliche Werte sind „agent“ (wenn der Agent die Sitzung beendet), „end_user“ (wenn der Endnutzer die Sitzung beendet), „timeout“ (wenn die Zeit für den Chat abgelaufen ist) oder „dismissed“ (wenn der Chat abgelehnt wurde). |
duration |
String | Enthält die Sitzungsdauer in Sekunden und ist nur für Anrufsitzungen enthalten. Beispiel: „30 Sekunden“. |
SDK-Daten gelöscht
| Schlüssel | Typ | Beschreibung |
|---|---|---|
event_name |
String | Enthält den Ereignisnamen. Beispiel: „E-Mail angeklickt“. |
Daten zu Klicks auf Content-Karten
| Schlüssel | Typ | Beschreibung |
|---|---|---|
title |
String | Der Titel der Karte. |
title |
String | Der Titel der Karte. |
subtitle |
String | Der Untertitel der Karte. |
body |
String | Die Beschreibung der Inhaltskarte. |
link | String | Ein Webseitenlink oder ein Deeplink. Das SDK verwendet die Betriebssystemfunktionen, um sie zu öffnen. |
event_params | dictionary | Ein Wörterbuch mit zusätzlichen Informationen zum Click-Event. Das SDK verwendet diese. |
Daten zu Klicks auf Buttons in Content Cards
| Schlüssel | Typ | Beschreibung |
|---|---|---|
title |
String | Der Titel der Karte. |
title |
String | Der Titel der Karte. |
link | String | Ein Webseitenlink oder ein Deeplink. Das SDK verwendet die Betriebssystemfunktionen, um sie zu öffnen. |
event_params | dictionary | Ein Wörterbuch mit zusätzlichen Informationen zum Click-Event. Das SDK verwendet diese. |
Daten zu angeklickten Kurzantworten
| Schlüssel | Typ | Beschreibung |
|---|---|---|
title |
String | Der Titel der Karte. |
title |
String | Der Titel der Karte. |
link | String | Ein Webseitenlink oder ein Deeplink. Das SDK verwendet die Betriebssystemfunktionen, um sie zu öffnen. |
event_params | dictionary | Ein Wörterbuch mit zusätzlichen Informationen zum Click-Event. Das SDK verwendet diese. |
Daten zu Klicks auf Links in Nachrichten
| Schlüssel | Typ | Beschreibung |
|---|---|---|
event_name |
String | Enthält den Ereignisnamen, z. B. „Message Link Clicked“. |
link |
String | Ein Webseitenlink oder ein Deeplink. Das SDK verwendet die Betriebssystemfunktionen, um ihn zu öffnen. |
Benutzerdefinierte Daten an Ihr CRM-System senden
Benutzerdefinierte Daten können an Kundenservicemitarbeiter gesendet werden und werden im Support-Ticket für den eingehenden Anruf/Chat angezeigt.
Es gibt zwei Methoden, um benutzerdefinierte Daten zu senden:
Signierte Methode: Vordefinierte Datensignatur mit JWT.
Unsignierte Methode: Vordefinierte Daten mit einfachem JSON (nicht empfohlen).
Benutzerdefinierte Daten mit der signierten Methode senden
Wenn Sie benutzerdefinierte Daten mit der signierten Methode senden möchten, müssen Sie eine Signaturmethode implementieren.
Rufen Sie zuerst benutzerdefinierte Daten in Ihrer Host-App ab und senden Sie sie dann zum Signieren an Ihren Server. Auf Ihrem Server können Sie zusätzliche Daten mithilfe eines definierten Formulars hinzufügen. Signiere sie mit deinem Unternehmens-Secret und gib sie dann per JWT zurück.
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));
}
// ...
}
}
Nicht signierte Methode zum Senden benutzerdefinierter Daten verwenden
Google empfiehlt, die signierte Methode zu verwenden, um benutzerdefinierte Daten in Ihrer Anwendung zu senden. Weitere Informationen finden Sie unter Benutzerdefinierte Daten mit der signierten Methode senden.
Sie können unsignierte Daten senden, indem Sie das Android SDK mit Startoptionen starten, um benutzerdefinierte Daten mit UjetStartOptions.Builder#setUnsignedCustomData festzulegen. UjetTokenCallback sollte onToken(null) aufrufen.
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);
Nicht signierte benutzerdefinierte Daten zum Senden eines externen Chatprotokolls verwenden
Sie können das externe Chatprotokoll mit nicht signierten benutzerdefinierten Daten an die CCAI Platform senden, wenn es gestartet wird. Verwenden Sie UjetCustomData.putObject("external_chat_transfer", hashMapObject), um die Transkriptdaten im JSON-Format so festzulegen:
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);
JSON-Format:
greeting_override: Stringagent: Wörterbuchname: Stringavatar: String [URL des Agenten-Avatars, optional]
transcript: Arraysender: string ["end_user" oder "agent"]timestamp: String [z. B. „2021-03-15 12:00:00Z“]content: Arraytype: String [entweder „text“ oder „media“]text: String [erforderlich für Texttyp]media: Wörterbuch [für Medientyp erforderlich]type: String [entweder „image“ oder „video“]url: String [öffentliche URL, die auf die Mediendatei verweist]
JSON-Beispiel:
{
"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"
}
]
}
]
}
Sie können Markdown für den Texttyp verwenden. Die folgenden Formate werden unterstützt:
Fett
Kursiv
Unterstrichen
Zeilenumbrüche
Aufzählungsliste
Nummerierte Liste
Links
Benutzerdefiniertes Datenformat
In diesem Abschnitt wird das Format der benutzerdefinierten Daten gezeigt, die im JWT übergeben werden können.
JSON-codiert in JWT
Die JSON-Datei sollte „iat“ und „exp“ enthalten, um das JWT zu validieren. Das Objekt der benutzerdefinierten Daten ist der Wert des Schlüssels 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"
}
}
}
Der Schlüssel ist eine eindeutige Kennung für die Daten. Der Typ ist der Typ des Werts.
string- JSON-String
number- Ganzzahl, Gleitkommazahl
date- UTC-Unix-Zeitstempelformat mit 13 Ziffern. (enthält Millisekunden)
url- HTTP-URL-Format
Das Label ist der Anzeigename auf der CRM-Seite.
Anzeige benutzerdefinierter Daten verhindern
Sie können die Property invisible_to_agent mit einem benutzerdefinierten Datenobjekt verwenden, um zu verhindern, dass signierte oder unsignierte benutzerdefinierte Daten im Agent-Adapter angezeigt werden. Im vorherigen Beispiel wird die Sozialversicherungsnummer des Endnutzers nicht im Agent-Adapter angezeigt, da "invisible_to_agent" : true im Objekt ssn enthalten ist.
Wenn Sie das Attribut "invisible_to_agent" : true in ein benutzerdefiniertes Datenobjekt einfügen, können Sie Folgendes erwarten:
- Die benutzerdefinierten Daten sind in der Sitzungsmetadatendatei enthalten.
- Die benutzerdefinierten Daten sind nicht in CRM-Datensätzen enthalten.
Weitere Informationen finden Sie unter Sitzungsdaten im Agent-Adapter ansehen.
Reservierte Dateneigenschaften
Sie können reservierte Datenattribute als signierte benutzerdefinierte Daten an die Contact Center AI Platform (CCAI Platform) senden, wenn eine Sitzung beginnt. Weitere Informationen finden Sie unter Reservierte Datenattribute senden.
Im Folgenden finden Sie ein Beispiel für reservierte Datenattribute in benutzerdefinierten Daten:
{
"custom_data": {
"reserved_verified_customer": {
"label": "Verified Customer",
"value": false,
"type": "boolean"
},
"reserved_bad_actor": {
"label": "Bad Actor",
"value": false,
"type": "boolean"
},
"reserved_repeat_customer": {
"label": "Repeat Customer",
"value": false,
"type": "boolean"
}
}
}
Legen Sie für jeden Wert true oder false fest.
reserved_verified_customer:true, wenn Sie diesen Endnutzer als legitimen Kunden betrachten.reserved_bad_actor:true, wenn Sie diesen Endnutzer als potenziellen böswilligen Akteur betrachten.reserved_repeat_customer:true, wenn Sie festgestellt haben, dass dieser Endnutzer Ihr Contact Center schon einmal kontaktiert hat.
Fallback
Sie können UjetErrorListener als Fallback für unerwartete Fehler verwenden. Wenn Sie diesen Listener nicht festlegen oder „false“ zurückgeben, wird der Fehler vom Android SDK verarbeitet.
Das Android SDK leitet Nutzer nur dann mit einer Fallback-Nummer an die Telefon-App weiter, wenn die Option „PSTN-Fallback aktivieren“ unter Einstellungen > Entwicklereinstellungen > MMA > Pop-up bearbeiten aktiviert ist. Andernfalls wird das SDK beendet.
| Fehlertyp | Fehlercode | Trigger |
|---|---|---|
| NETWORK_ERROR | 1 | Das Netzwerk ist nicht verfügbar. Dieser Fehler wird nicht ausgelöst, wenn das Netzwerk während des Chats, Anrufs oder Bewertungsbildschirms nicht verfügbar ist. |
| AUTHENTICATION_ERROR | 100 | Während der Authentifizierung ist ein unerwarteter Fehler aufgetreten. |
| AUTHENTICATION_JWT_ERROR | 101 | Bei der JWT-Validierung ist ein unerwarteter Fehler aufgetreten (z.B. ein Parsing-Fehler). |
| VOIP_CONNECTION_ERROR | 1000 | Es konnte keine Verbindung zum VoIP-Anbieter hergestellt werden. Dies wird über den Callback des VoIP SDKs abgewickelt. |
| VOIP_LIBRARY_NOT_FOUND | 1001 | Ein Anruf sollte über einen VoIP-Anbieter verbunden werden, aber es konnte keiner gefunden werden. Das kann passieren, wenn ein Entwickler das falsche SDK eingebunden oder die Bibliothek des VoIP-Anbieters nicht in seinen Abhängigkeiten hinzugefügt hat. |
| CHAT_LIBRARY_NOT_FOUND | 1100 | Tritt auf, wenn die Chatbibliothek nicht gefunden werden konnte. Das kann passieren, wenn ein Entwickler das falsche SDK eingebunden oder die Twilio Chat-Bibliothek nicht zu seinen Abhängigkeiten hinzugefügt hat. |
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());
}
});
Deeplinks
Wenn Sie intelligente Aktionen für einen IVR-Anruf (PSTN) verwenden möchten, müssen Sie in Ihrem Projekt Deeplinks einrichten.
Das Deeplink-Format ist ein eindeutiger URI, z. B.:
ujet:// <package_name>/smartchannel.
Außerdem müssen Sie diesen Link oder eine URL, die zu diesem Link weiterleitet, im Admin-Portal festlegen (Einstellungen > Betriebsverwaltung > SMS zum Herunterladen der App senden aktivieren).
Sie müssen Ihrem Manifest einen Intent-Filter hinzufügen, der den Deeplink enthält.
<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>
Ausfallsicherheit des Live-Chats
Konfigurieren Sie die Ausfallsicherheit des Live-Chats, um die Verfügbarkeit des Live-Chats zu verbessern. Dadurch wird eine sekundäre Fallback-Messaging-Medienebene hinzugefügt, die verwendet wird, wenn die primäre Medienebene ausfällt.
Fügen Sie der Datei build.gradle auf Modulebene die folgende Abhängigkeit hinzu, um diese Funktion hinzuzufügen:
dependencies {
implementation "co.ujet.android:chat_blue:VERSION"
}
Ersetzen Sie VERSION durch die aktuelle Version des UJET SDK.
Änderungen am Verhalten bei eingehenden Anrufen
Ab Geräten mit Android 10 werden eingehende Anrufe nicht direkt an Endnutzer weitergeleitet, wenn die Host-App im Hintergrund ausgeführt wird. Stattdessen verwenden wir Benachrichtigungen, um Nutzer auf eingehende Anrufe aufmerksam zu machen (auch wenn das Smartphone gesperrt ist). Nutzer können den Anruf dann annehmen oder ablehnen.
Wir zeigen dieselben Benachrichtigungen an, wenn die Host-App im Hintergrund ausgeführt wird und der Bildschirm vor dem eingehenden Anruf gesperrt wurde. Diese Verhaltensänderung dient der Einhaltung der aktuellen Einschränkungen von Google für das Starten von Aktivitäten, wenn sich die App im Hintergrund befindet. Das Verhalten wird nicht beeinflusst, wenn die Host-App im Vordergrund oder auf Geräten mit einer Android-Version vor Android 10 ausgeführt wird.
SDK-Sitzung anpassen
In diesem Abschnitt wird beschrieben, wie das SDK weiter angepasst werden kann.
Nach einer bestehenden Sitzung suchen
Prüfen Sie vor dem Starten einer Sitzung mit der beschriebenen Methode, ob bereits eine Sitzung vorhanden oder in Bearbeitung ist. Wenn es vorhanden ist, können Sie den Endnutzer auffordern, es fortzusetzen oder abzubrechen.
Das ist besonders wichtig, wenn ein Nutzer geändert wird.
if (Ujet.getStatus() != UjetStatus.None) {
// Display alert to cancel login or resume existing session
}
Sitzung trennen
Informationen zum Trennen einer laufenden Sitzung finden Sie in der Methode.
Prüfen Sie vor der Verwendung dieser Methode mit Ujet.getStatus(), ob eine solche Sitzung vorhanden ist. Wenn Sie nach dem Trennen der Sitzung durch das SDK eine oder mehrere Aktionen ausführen möchten, z. B. eine Nachricht anzeigen oder die App schließen, können Sie den Antwort-Callback onFinished() verwenden, wie im nächsten Abschnitt beschrieben. Setzen Sie den Callback andernfalls auf „null“.
Ujet.disconnect(new UjetResponseCallback() {
@Override
public void onFinished() {
// `onFinished()` is triggered after CCAI Platform disconnects the session.
finish(); // Finishes the activity.
}
});
Endnutzerdaten aus dem Cache löschen
Sie sind dafür verantwortlich, den Cache zu leeren, wenn endnutzerbezogene Daten in Ihrer App aktualisiert oder geändert wurden. Wenn sich der Endnutzer beispielsweise abgemeldet hat, rufen Sie die Methode auf, um den Cache für diesen Nutzer zu entfernen, damit beim nächsten Start des SDK eine neue Sitzung für den neuen Endnutzer initiiert wird.
Ujet.clearUserData();
SDK ausblenden
Sie können das SDK mit der Methode Ujet.hideSDK() ausblenden. Das ist beispielsweise nützlich, wenn das SDK die Benutzeroberfläche Ihrer App beeinträchtigt. Initialisieren Sie das SDK mit Ujet.init(), bevor Sie diese Methode aufrufen. Ujet.init() gibt true zurück, wenn das SDK erfolgreich ausgeblendet wurde, andernfalls false. Nachdem Sie das SDK ausgeblendet haben, können Sie es mit der Methode Ujet.start() wieder starten.
Im folgenden Beispiel wird das SDK ausgeblendet:
Ujet.hideSDK();
Symbole für externe Weiterleitungslinks konfigurieren
Passen Sie das Symbol im Kanal „Externer Weiterleitungslink“ an, indem Sie das Symbol in einen Ordner mit zeichenbaren Elementen Ihrer App hochladen. Achten Sie darauf, dass Sie beim Erstellen des externen Weiterleitungslinks im CCAI Platform-Portal unter Einstellungen > Chat > Externe Weiterleitungslinks > Links ansehen > Weiterleitungslink hinzufügen denselben Symbolnamen verwenden.
Wenn der Symbolname im CCAI Platform-Portal nicht mit dem in die App hochgeladenen Symbol übereinstimmt, verwendet das Android SDK das Standardsymbol.
Symbol Vielen Dank für die Umfragen konfigurieren
Sie können das Symbol auf der „Danke“-Seite der Umfrage anpassen oder überschreiben, indem Sie ein Symbol in den Ordner „drawable“ Ihrer App hochladen und den Dateinamen ujet_survey_thank_you_icon als Symbolnamen verwenden.
Anpassung der Benutzeroberfläche und von Strings
In diesem Abschnitt wird erläutert, wie Sie Strings, Inhaltskarten, Designs und Chat-Header anpassen.
Strings
Sie können die in der Anwendung verwendeten Strings anpassen, indem Sie die Schlüssel für jeden String in „strings.xml“ überschreiben.
<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>

Anpassung der Textgröße
Sie können die Größe des Titels, der Beschreibung und des Auswahltexts in der Anwendung anpassen, indem Sie die folgenden Schlüssel in „dimens.xml“ überschreiben.
Anpassbare Textgrößen sind hervorgehoben:
<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>

Design
So passen Sie das Design und den Hintergrund an: Schritt 1 ist für das Design und Schritt 2 für den Hintergrund.
Passen Sie das Design an, indem Sie die Schlüssel für jedes Stilelement in „style.xml“ überschreiben. Beispiel:
<!--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>Sie können die Hintergrundfarbe in der Anwendung anpassen, indem Sie die Schlüssel für die einzelnen Stilelemente in „style.xml“ überschreiben. Im Screenshot ist die anpassbare Hintergrundfarbe zu sehen.
<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>
Titel der Chatkopfzeile anpassen
Es gibt Optionen, mit denen Sie den Titeltext der Chatkopfzeile in der Benutzeroberfläche anpassen können.
Sie können den Titeltext des Chatheaders mit den folgenden Optionen anpassen:
<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>
Sie können die Kurzantworten des virtuellen Kundenservicemitarbeiters in der Chat-UI mit den folgenden Optionen anpassen:
<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>
Content Cards
Sie können neben der Chatanpassung auch Anpassungen für Inhaltskarten hinzufügen. Dazu können Sie entweder die JSON-Datei (siehe content_card property in der Datei app/src/main/assets/json/ujet_styles.json) oder die Klasse ContentCardStyle verwenden.
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",
)
)
)
)
Webformular-Design
Sie können die Webformular-Karte zusammen mit der Chatanpassung anpassen. Dazu können Sie entweder die JSON-Datei (siehe Attribut form_card in der Datei app/src/main/assets/json/ujet_styles.json) oder die Klasse FormCardStyle verwenden.
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,
),
)
)
Umfragen
Du kannst das Symbol auf der „Danke“-Seite der Umfrage ändern, indem du ein Symbol in den Ordner „drawable“ deiner App hochlädst.
Verwenden Sie ujet_survey_thank_you_icon als Symbolnamen.
Dialog zur Einholung von Einwilligungen für die Bildschirmfreigabe anpassen
Wenn Sie das Dialogfeld zur Einholung von Einwilligungen für die Bildschirmfreigabe anpassen möchten, implementieren Sie die abstrakte Klasse CoBrowseAlertProvider. Sie können DialogFragment oder AlertDialog verwenden, um den benutzerdefinierten Dialog zur Einholung von Einwilligungen zu implementieren.
Wenn Sie
DialogFragmentverwenden, fügen Sie zwei Schaltflächen ein, eine zum Akzeptieren und eine zum Ablehnen der Einwilligung. Übergeben Sie eine benutzerdefinierteDialogFragment-Instanz an dendialogInstance-Callback.Wenn Sie
AlertDialogverwenden, übergeben Sie dieDialogFragment-Instanz nicht an dendialogInstance-Callback.
Nachdem Sie die Einwilligung erhalten haben, übergeben Sie sie an das SDK, indem Sie den Callback consentStatus aufrufen und den booleschen Wert entsprechend übergeben.
Verwenden Sie das folgende Codebeispiel, um den benutzerdefinierten Dialog zur Einholung von Einwilligungen zu implementieren:
class CoBrowseAlertProviderImpl : CoBrowseAlertProvider() {
// You should only implement the cobrowse consent dialog methods that you want to customize and replace the default UI.
override fun showCoBrowseSessionActivationRequestDialog(context: Context, dialogInstance: (DialogFragment) -> Unit, consentStatus: (Boolean) -> Unit) {
// Using DialogFragment for customization
val dialog = ConsentDialog.newInstance(
title = context.getString(co.ujet.android.R.string.ujet_cobrowse_session_request_alert_title),
message = context.getString(co.ujet.android.R.string.ujet_cobrowse_session_request_alert_message),
positiveButton = context.getString(co.ujet.android.R.string.ujet_cobrowse_session_request_alert_button_allow),
negativeButton = context.getString(co.ujet.android.R.string.ujet_cobrowse_session_request_alert_button_deny),
cancelable = false,
onNegativeClick = { consentStatus(false) }, // Pass consent value
onPositiveClick = { consentStatus(true) }
)
// Pass DialogFragment instance
dialogInstance(dialog)
// Using AlertDialog for customization, if you use AlertDialog instead of DialogFragment then you don't need to call `dialogInstance(dialog)`, just pass consent value using `consentStatus()`
val alertDialog = AlertDialog.Builder(context).apply {
setTitle("Co-Browse Session Request") // Set dialog title
setMessage("Allow the agent to co-browse with you?") // Set dialog message
setPositiveButton("Allow"){dialogInterface, _ ->
// Pass consent
consentStatus(true)
}
setNegativeButton("Deny"){dialogInterface, _ ->
// Pass consent
consentStatus(false)
}
}.create()
alertDialog.show()
}
override fun showCoBrowseSessionRemoteControlRequestDialog(context: Context, dialogInstance: (DialogFragment) -> Unit, consentStatus: (Boolean) -> Unit) {
// Same as showCoBrowseSessionActivationRequestDialog
}
override fun showCoBrowseSessionFullDeviceRequestDialog(context: Context, dialogInstance: (DialogFragment) -> Unit, consentStatus: (Boolean) -> Unit) {
// Same as showCoBrowseSessionActivationRequestDialog
}
override fun showCoBrowseConfirmationDialog(context: Context, dialogInstance: (DialogFragment) -> Unit, consentStatus: (Boolean) -> Unit) {
// Same as showCoBrowseSessionActivationRequestDialog
}
override fun showStopCoBrowseConfirmationDialog(context: Context, dialogInstance: (DialogFragment) -> Unit, consentStatus: (Boolean) -> Unit) {
// Same as showCoBrowseSessionActivationRequestDialog
}
}
// A generic DialogFragment class
class ConsentDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// Implement your custom dialog UI here
}
}
Übergeben Sie diese Implementierung mit der folgenden API an das SDK:
Ujet.setCoBrowseAlertProvider(CoBrowseAlertProviderImpl())
Webformulare konfigurieren
Wenn Sie ein Webformular konfigurieren möchten, implementieren Sie die Methode ujetWebFormDidReceive der Schnittstelle UjetWebFormListener. Diese Methode empfängt ein Ereignis (eine FormMessageReceived-Zuordnung) als Parameter, der formularbezogene Informationen enthält.
Das Ereignis enthält die folgende JSON-Struktur:
{
"type": "form_message_received",
"smart_action_id": 1,
"external_form_id": "external_foobar",
"signature": "4868a7e1dcb5..."
}
Ereignis verarbeiten
So verarbeiten Sie das Ereignis:
- Extrahieren Sie die relevanten Informationen aus der Ereigniszuordnung (
smart_action_id,external_form_idundsignature). - Generieren Sie einen Formular-URI und eine Signatur für die Formulardaten.
- Übergeben Sie die Formulardaten mit
callback.onEvent(formDataEvent)alsFormDataEvent-Map an das SDK. - Wenn bei der URI- oder Signaturgenerierung ein Fehler auftritt, rufen Sie den Fehler-Callback mit
callback.onError()auf.
Die an das SDK übergebene Karte (FormDataEvent) sollte die folgende Struktur haben:
{
"type": "form_data",
"signature": "4868a7e1dcb5...",
"data": {
"external_form_id": "form_id",
"smart_action_id": 1,
"uri": "foobar"
}
}
Die Signatur (HMAC-SHA256) muss mit den Daten generiert und mit einem gemeinsamen Secret-Schlüssel signiert werden. Die Objektschlüssel der Daten müssen vor dem Generieren von Signaturen alphabetisch sortiert werden. Dieselben Daten sollten an das SDK gesendet werden.
Das folgende Codebeispiel zeigt, wie der Webformular-Listener implementiert wird:
class UjetWebFormListenerImpl : UjetWebFormListener {
override fun ujetWebFormDidReceive(event: Map<String, Any?>, callback: UjetWebFormCallback) {
try {
// Extract required fields from the event
val smartActionId = event["smart_action_id"]
val externalFormId = event["external_form_id"]
val signature = event["signature"]
// Simulate form URI generation (replace with actual implementation)
val formUri = "generated_form_uri"
// Prepare the data map, key should be alphabetically ordered
val data = mapOf(
"external_form_id" to externalFormId,
"smart_action_id" to smartActionId,
"uri" to formUri
)
// Generate the signature using `data`
val generatedSignature = "generated_signature"
// Create the FormDataEvent map
val formDataEvent = mapOf(
"type" to "form_data",
"signature" to generatedSignature,
"data" to data
)
// Pass the FormDataEvent to the SDK
callback.onEvent(formDataEvent)
} catch (e: Throwable) {
// If any error occurs, invoke the error callback
callback.onError()
}
}
}
Übergeben Sie diese Implementierung mit der folgenden API an das SDK:
Ujet.setUjetWebFormListener(UjetWebFormListenerImpl())
Fehlerbehebung
Das Starten eines neuen Chats hat länger als 30 Sekunden gedauert
Prüfen Sie, ob Sie auf eine Delegatmethode für benutzerdefinierte Daten antworten. Du solltest auf Anfrage gültige benutzerdefinierte Daten zurückgeben oder einfach „null“ mit einem Callback zurückgeben. Verwenden Sie den folgenden Code als Referenz.
@Override
public void onSignPayloadRequest(Map<String, Object> payload, UjetPayloadType ujetPayloadType, UjetTokenCallback tokenCallback) {
if (ujetPayloadType == UjetPayloadType.CustomData) {
tokenCallback.onToken(null);
}
}
Erklärung zur Richtlinienerklärung
Wenn Sie in der Google Play Console eine Benachrichtigung erhalten, in der Sie aufgefordert werden, eine Richtlinie für die vom Android SDK verwendeten Dienste oder Berechtigungen zu deklarieren, verwenden Sie eine der folgenden Erklärungen.
Vom Android SDK verwendete Dienste im Vordergrund deklarieren
Google hat in Android 14 Typen von Diensten im Vordergrund eingeführt und festgelegt, dass diese beim Starten von Diensten im Vordergrund angegeben werden müssen. Weitere Informationen finden Sie unter https://developer.android.com/about/versions/14/changes/fgs-types-required#remote-messaging. Das Android SDK der Contact Center AI Platform (CCAI Platform) verwendet Dienste im Vordergrund, um Chats und Anrufe zu starten. Daher haben wir den Diensttyp FOREGROUND_SERVICE_REMOTE_MESSAGING für Chats verwendet, da es sich um Textnachrichten handelt, und den Diensttyp FOREGROUND_SERVICE_MICROPHONE für Anrufe. Ohne diese Diensttypen stürzt das SDK beim Initiieren eines Chats oder Anrufs auf Geräten mit Android 14 oder höher ab.
Full-Screen-Intent-Berechtigung deklarieren, die vom Android SDK verwendet wird
Die Berechtigung „USE_FULL_SCREEN_INTENT“ ist erforderlich, um Push-Benachrichtigungen für eingehende Anrufe anzuzeigen, wenn das Gerät gesperrt ist. Der Endnutzer wird benachrichtigt und die Anrufbenachrichtigung wird im Vollbildmodus angezeigt. So benachrichtigt die integrierte Telefon App den Endnutzer über den eingehenden Anruf.
Android 15 unterstützen
So unterstützen Sie Android 15:
Legen Sie
compileSdkVersion = 35undtargetSdkVersion = 35in Ihrerbuild.gradle(:app)fest.Die Version des Android-Gradle-Plug-ins (AGP) Ihres Projekts muss mindestens 8.5.1 sein. Weitere Informationen finden Sie unter Paketierung Ihrer gemeinsam genutzten Bibliotheken aktualisieren.
Installieren Sie das Java Development Kit (JDK) in Version 17 oder höher, um Android-Projekte mit AGP 8.0 oder höher zu erstellen. Weitere Informationen finden Sie unter JDK 17 zum Ausführen von AGP 8.0 erforderlich.