Headless Mobile SDK für Android: Warteschlangen, Channels und Chat

In diesem Dokument wird erläutert, wie Sie Support-Einstiegspunkte (Warteschlangen und Kanäle) in Ihrer App verfügbar machen und den gesamten Chat-Lebenszyklus steuern: Starten, Fortsetzen, Senden von Nachrichten und Anhängen, Anzeigen von Eingaben, Schwärzen vertraulicher Daten, Eskalieren an menschliche Kundenservicemitarbeiter und Beenden der Sitzung.

Hinweis

Richten Sie das SDK ein. Weitere Informationen finden Sie unter Headless Mobile SDK für Android: Erste Schritte.

Warteschlangen und Kanäle auswählen

  • Eine Warteschlange stellt in der Regel einen Support-Einstiegspunkt dar, z. B. „Abrechnung“, „Technischer Support“ oder „VIP-Support“.

  • Jede Warteschlange kann einen oder mehrere der folgenden Kanäle anbieten:

    • Chat

    • Sofortanruf (Sprachanruf)

    • Geplanter Anruf

    • E-Mail

    • Externe Links zur Ablenkung (Links zu Ihren Selfservice-Seiten oder anderen Kanälen)

Warteschlangen und Kanalverfügbarkeit werden von Administratoren im Contact Center AI Platform-Admin-Portal konfiguriert.

So sieht es in Ihrer App aus

In Ihrer App sieht ein typischer Ablauf so aus:

  1. Sie fügen in Ihrer App einen Support-Einstiegspunkt hinzu, z. B. einen Tab Hilfe oder eine Schaltfläche Kontakt.

  2. Wenn der Nutzer darauf tippt, rufen Sie das Warteschlangenmenü über das SDK ab und rendern Ihre eigene Menü-UI.

  3. Wenn der Nutzer eine Warteschlange auswählt, prüfen Sie die verfügbaren Kanäle.

  4. In Ihrer App werden diese Kanäle dem Nutzer angezeigt (z. B. Jetzt chatten, Jetzt anrufen, Anruf planen, E-Mail senden, Hilfe aufrufen).

  5. Wenn der Nutzer einen Kanal auswählt, rufen Sie die entsprechende SDK API auf.

Warteschlangenmenüs aus dem SDK abrufen

Das SDK bietet queueMenuService zum Abrufen von Warteschlangenmenüs. Die Methode get gibt ein QueueMenuResult mit der Liste der Warteschlangen (List<QueueMenu>) und ein isDirectAccess-Flag zurück. Sie können entweder die vollständige Menüstruktur abrufen oder einen Direktzugriffsschlüssel verwenden, um direkt zu einer bestimmten Warteschlange zu springen:

import com.ccaiplatform.ccaikit.CCAI
import com.ccaiplatform.ccaikit.models.response.queuemenu.QueueMenuResult
import com.ccaiplatform.ccaikit.models.response.queuemenu.QueueMenu

// Fetch the full queue menu tree
val menuResult: QueueMenuResult? = CCAI.queueMenuService?.get()

// Or fetch a specific queue using a Direct Access Key
val menuResult: QueueMenuResult? = CCAI.queueMenuService?.get(key = "billing_vip")

Mit dem optionalen Parameter key können Sie das Menü mit der vollständigen Warteschlange umgehen und den Nutzer direkt zu einer bestimmten Warteschlange weiterleiten. In der CCAI Platform wird dies mit einem direkten Zugriffspunkt (DAP) erreicht.

Ein DAP kann von Administratoren im CCAI Platform-Portal so konfiguriert werden:

  1. Gehen Sie zu Einstellungen > Warteschlange und wählen Sie eine Warteschlange aus der Menüstruktur aus.

  2. Klicken Sie im Bereich Zugriffspunkt auf + Direkten Zugriffspunkt erstellen.

  3. Gib den Schlüssel in das Textfeld ein.

  4. Klicken Sie auf Speichern.

QueueMenu-Datenstruktur

Jedes QueueMenu enthält Folgendes:

Attribut Typ Beschreibung
id Integer Die eindeutige Kennung für diese Warteschlange.
name String? Der Anzeigename (z. B. „Abrechnungssupport“).
children List<QueueMenu> Untermenüs (leere Liste, wenn es sich um einen Blattknoten handelt).
channels Kanäle? Verfügbare Kanäle für diese Warteschlange.
hidden Boolesch Gibt an, ob diese Warteschlange für Nutzer ausgeblendet werden soll (vom Administrator konfiguriert).
position Int? Vom Server definierte Anzeigeposition – die Reihenfolge im Administratorportal wird beibehalten.
settings List<QueueMenuSetting>? Einstellungen auf Warteschlangenebene, die im Administratorportal konfiguriert wurden.
redirectionExtra QueueMenuRedirection? Metadaten für die automatische Weiterleitung, falls konfiguriert (siehe Weiterleitung und Ablenkung).
deflectionFrom List<QueueMenuDeflection>? Die Warteschlangen, die zu dieser Warteschlange umgeleitet wurden. Die Plattform gibt diese Warteschlange an ihrer Stelle zurück. Eine nicht leere Liste erklärt also eine bereits erfolgte Weiterleitung (siehe Weiterleitung).

Die Datenklasse Channels hat die folgenden Eigenschaften:

Attribut Typ Beschreibung
chat ChatChannel? Konfiguration des Chatkanals (null, wenn der Chat für diese Warteschlange nicht verfügbar ist).
voiceCall VoiceCallChannel? Konfiguration des Sprachanrufkanals (null, wenn die Sprachfunktion nicht verfügbar ist). Enthält Flags wie scheduleEnabled und Aufzeichnungseinstellungen.
email EmailChannel? Konfiguration des E-Mail-Kanals (null, wenn die E-Mail-Adresse nicht verfügbar ist). Greifen Sie über channels.email?.email auf die Adresse zu.
externalDeflectionLink ExternalDeflectionLink? Konfiguration des externen Weiterleitungslinks (null, falls nicht verfügbar). Greifen Sie über die Attribute des strukturierten Typs auf die URL zu.

VoiceCallChannel-Felder (Metadaten zu Funktionen und Ablenkung)

// VoiceCallChannel.kt (simplified)
data class VoiceCallChannel(
    val instantEnabled: Boolean,            // Live voice call allowed now
    val preSessionSmartAction: Boolean,     // Per-channel pre-session smart action flag
    val scheduleEnabled: Boolean,           // Scheduled calls supported
    val recordingOption: RecordingOption?,  // ALWAYS / NEVER / ASK_USER
    val voicemailReason: String?,
    val phoneNumber: String?,
    val scheduleDeflectionType: String?,
    val deflected: Boolean?,
    val deflectedReason: String?
)

Implementierungsbeispiel

fun showAvailableChannels(queueMenu: QueueMenu) {
    val channels = queueMenu.channels

    val voice = channels?.voiceCall

    // Show only what the platform enabled, and hide everything else so
    // nothing carries over from a previously selected queue
    chatButton.isVisible = channels?.chat?.enabled == true
    callButton.isVisible = voice != null && voice.instantEnabled && !voice.deflected
    scheduleButton.isVisible = voice?.scheduleEnabled == true
    emailButton.isVisible = channels?.email?.enabled == true

    // External deflection links: the enabled entries that have a URL
    val links = channels?.externalDeflectionLink
        ?.takeIf { it.enabled }
        ?.links.orEmpty()
        .filter { it.enabled && it.url != null }
    helpLinksButton.isVisible = links.isNotEmpty()
}

Wartezeiten werden abgerufen

Sie können auch die geschätzten Wartezeiten für eine bestimmte Warteschlange abrufen:

// Fetch wait time for a specific queue
val waitTime = CCAI.queueMenuService?.getWaitTimes(menuId = queueMenu.id)

// waitTime contains:
// - chat: estimated wait time for chat (in seconds)
// - voiceCall: estimated wait time for voice call (in seconds)

Warteschlangen mit einem Kanal

Wenn eine Warteschlange nur einen Kanal bietet (z. B. nur E-Mail), können Sie Folgendes tun:

  • Überspringen Sie den Schritt zur Kanalauswahl und rufen Sie direkt die entsprechende Benutzeroberfläche auf.

  • Du kannst den verfügbaren Kanal aber auch explizit anzeigen, wenn das in deiner UX sinnvoller ist.

Die Konfiguration und die Metadaten des SDKs geben an, welche Kanäle zulässig sind. Ihre App entscheidet, wie sie angezeigt werden.

Weiterleitung und Ablenkung

Administratoren können eine Warteschlange so konfigurieren, dass Nutzer weitergeleitet werden, anstatt Kanäle anzubieten. Wenn QueueMenu.redirectionExtra festgelegt ist, reagiere darauf, sobald der Nutzer die Warteschlange auswählt:

  • option gibt an, was zu tun ist: PHONE, MESSAGE, URL, VOICEMAIL, QUEUE, SIP oder CONTACT.
  • data enthält den Wert, z. B. die zu wählende Nummer, die anzuzeigende Nachricht oder die zu öffnende URL.

QueueMenu.deflectionFrom ist anders. Wenn eine Warteschlange zu einer anderen Warteschlange umgeleitet wird, gibt die Plattform die Zielwarteschlange anstelle der vom Nutzer ausgewählten Warteschlange zurück und listet die Quellwarteschlangen in „deflectionFrom“ auf. Sie erklärt eine Weiterleitung, die bereits stattgefunden hat, und ist keine Liste von Optionen, die angeboten werden.

Die Weiterleitung außerhalb der Geschäftszeiten und bei Überkapazität wird pro Kanal gemeldet. Informationen zur Handhabung finden Sie unter Headless Mobile SDK für Android: Intelligente Aktionen, Anhänge und Ablenkung.

Kanäle

Im Headless Mobile SDK dient Ihr CCAI Platform-Administratorportal als zentrale Datenquelle für Ihre Supportvorgänge. Administratoren konfigurieren, welche Supportkanäle (z. B. Chat, Sprache, E-Mail oder hilfreiche Links) für verschiedene Supportwarteschlangen (z. B. „Abrechnung“ oder „Technischer Support“) verfügbar sind.

Das SDK ruft diese Konfiguration sicher ab und übergibt sie an Ihre App. Ihre App liest diese Konfiguration und zeichnet die entsprechende Benutzeroberfläche.

Verfügbare Kanäle prüfen

Was das SDK bietet: Eine Echtzeit-Momentaufnahme, welche Supportkanäle für die vom Nutzer ausgewählte Warteschlange aktiv und verfügbar sind, unter Berücksichtigung der Öffnungszeiten und Kapazitätsgrenzen Ihres Portals.

Was Sie erstellen: Das UI-Menü (Schaltflächen, Listen oder Karten), in dem dem Nutzer diese verfügbaren Optionen angezeigt werden.

Implementierungsbeispiel: Der folgende Kotlin-Code nimmt die Warteschlange, auf die der Nutzer gerade getippt hat, und prüft die Datenklasse Channels, um zu sehen, welche Kanäle aktiviert sind. Anschließend wird entschieden, welche Schaltflächen auf dem Bildschirm angezeigt werden sollen.

// Assuming 'selectedMenu' is a QueueMenu returned by the SDK
fun setupChannelMenu(selectedMenu: QueueMenu) {
    val channels = selectedMenu.channels

    if (channels.chat != null) {
        showChatNowButton()
    }

    if (channels.voiceCall != null) {
        showCallNowButton()
    }

    if (channels.email != null) {
        showEmailUsButton()
    }

    if (channels.externalDeflectionLink != null) {
        showHelpCenterLinks()
    }
}

In den folgenden Abschnitten wird der Chat ausführlich beschrieben. Informationen zu Links für Sprachanrufe, Bildschirmfreigabe, geplante Anrufe, E‑Mails und externe Weiterleitungen finden Sie unter Headless Mobile SDK for Android: Voice, Screen Share, Scheduled Call, and Email.

Chat-Dienst-API

Der chatService verwaltet den gesamten Chat-Lebenszyklus. Die wichtigsten Methoden, die Sie am häufigsten verwenden, sind:

Methode Beschreibung
start Startet eine neue Chatsitzung mit einem ChatRequest.
sendMessage Sendet eine Nachricht (Text, Bild, Video oder Formularereignis).
typing Aktualisiert die Eingabeanzeige.
endChat Beendet die aktuelle Chatsitzung.
resumeChat Setzt eine zuvor gestartete Chatsitzung fort.
escalateToHumanAgent Übertragungen von einem virtuellen Kundenservicemitarbeiter an einen menschlichen Kundenservicemitarbeiter.
checkStatus Aktualisiert den aktuellen Chatstatus vom Server.

ChatRequest- und ChatResponse-Datenstrukturen

Die Datenklasse ChatRequest enthält die Konfiguration zum Starten eines neuen Chats:

data class ChatRequest(
    val chat: Chat? = null,                 // The session configuration (always pass one)
    val isScreenShareable: Boolean? = null, // Optional: enable screen share for this session
    val isVerifiable: Boolean? = null       // Optional: allow verification smart actions
)

data class Chat(
    val menuId: Int,                    // Required: queue menu ID
    val lang: String? = "en",           // Optional: language code override (defaults to "en")
    val ticketId: String? = null,       // Optional: associate with existing ticket
    val greeting: String? = null,       // Optional: custom greeting message
    val customData: CustomData? = null, // Optional: structured custom data
    val displayOrderInAdapter: List<String>? = null,
    val directAccessKeyId: Int? = null, // Optional: from QueueMenuResult (Direct Access Point)
    val dapRequestId: String? = null    // Optional: from QueueMenuResult (Direct Access Point)
)

Nachdem Sie einen Chat gestartet oder fortgesetzt haben, liefert das SDK seine ChatResponse im chatReceived-Flow (start() und resumeChat() geben nichts zurück). Die Properties, auf die in diesem Leitfaden am häufigsten verwiesen wird, sind:

  • id: die eindeutige Kennung der Chatsitzung.

  • status: der aktuelle Chatstatus (in der Warteschlange, aktiv, beendet usw.).

  • agent / virtualAgent: der zugewiesene menschliche oder virtuelle Kundenservicemitarbeiter.

  • postSessionRequired: Gibt an, ob für die Sitzung ein virtueller Agent nach der Sitzung konfiguriert ist. Umfragen und CSAT werden durch surveyEnabled und csatSetting signalisiert.

  • redactionEnabled: Gibt an, ob die automatische Entfernung personenidentifizierbarer Informationen für diese Sitzung aktiv ist.

Chatsitzung starten

Wenn Sie eine Chatsitzung starten möchten, verwenden Sie chatService mit einem ChatRequest, das die ID des Warteschlangenmenüs angibt.

Minimales Beispiel

import android.util.Log
import androidx.lifecycle.lifecycleScope
import com.ccaiplatform.ccaichat.chatService
import com.ccaiplatform.ccaichat.model.Chat
import com.ccaiplatform.ccaichat.model.ChatRequest
import com.ccaiplatform.ccaikit.CCAI
import com.ccaiplatform.ccaiscreenshare.screenShareService
import kotlinx.coroutines.launch

// If screen share is initialized, pass isScreenShareable for agent visibility
val chatRequest = ChatRequest(
    chat = Chat(menuId = 123),
    isScreenShareable = CCAI.screenShareService != null
)
startOrResumeChat(chatRequest)

// Resumes an earlier chat if there is one; otherwise starts a new one
fun startOrResumeChat(chatRequest: ChatRequest) {
    lifecycleScope.launch {
        val chatService = CCAI.chatService ?: return@launch
        try {
            // Pre-flight check: resume an earlier chat instead of starting a second one
            val existing = chatService.getLastChatInProgress()
            if (existing != null) {
                chatService.resumeChat(existing)
                return@launch
            }

            chatService.start(chatRequest)
            // Chat started - navigate to your custom chat screen
        } catch (e: Exception) {
            Log.e("CCAI", "Failed to start chat: ${e.message}")
        }
    }
}

Wenn Ihre App das Modul CCAIScreenShare nicht enthält, entfernen Sie den Import screenShareService und das Argument isScreenShareable.

Mit anstößiger Sprache

val chatRequest = ChatRequest(
    chat = Chat(menuId = 123, lang = "en")
)
startOrResumeChat(chatRequest) // Defined in the Minimal example

Chatsitzung fortsetzen

Setzen Sie eine zuvor gestartete Chatsitzung mit einem ChatResponse-Objekt fort:

lifecycleScope.launch {
    try {
        CCAI.chatService?.resumeChat(chat)
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to resume chat: ${e.message}")
    }
}

Verwaltung der Chat-Warteschlange

Sie können den aktuellen Chat wieder in die Warteschlange stellen (der Status wird zu „In der Warteschlange“) oder nach vorhandenen laufenden Chats suchen:

// Enqueue the current chat (automatically calls checkStatus() after enqueuing)
lifecycleScope.launch {
    try {
        CCAI.chatService?.enqueueCurrentChat()
        Log.d("CCAI", "Chat enqueued successfully")
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to enqueue chat: ${e.message}")
    }
}

// Check for an existing in-progress chat
lifecycleScope.launch {
    try {
        val chat = CCAI.chatService?.getLastChatInProgress()
        if (chat != null) {
            Log.d("CCAI", "Found ongoing chat: ${chat.id}")
        } else {
            Log.d("CCAI", "No ongoing chat found")
        }
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to get last chat: ${e.message}")
    }
}

// Retrieve previous chat history with pagination
lifecycleScope.launch {
    try {
        val previousChats = CCAI.chatService?.getPreviousChats(currentPage = 1)
        if (previousChats != null) {
            Log.d("CCAI", "Found ${previousChats.messages.size} previous messages")
        }
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to get previous chats: ${e.message}")
    }
}

Nachrichten senden

Die Methode sendMessage unterstützt mehrere Nachrichtentypen über die versiegelte Klasse OutgoingMessageContent:

sealed class OutgoingMessageContent {
    data class Text(val content: String) : OutgoingMessageContent()
    data class Photos(
        val images: List<UploadableImage>,
        val smartAction: SmartAction? = null
    ) : OutgoingMessageContent()
    data class Videos(
        val video: UploadableVideo,
        val smartAction: SmartAction? = null
    ) : OutgoingMessageContent()
    data class FormComplete(
        val type: String? = null,
        val signature: String? = null,
        val data: FormCompleteEventData
    ) : OutgoingMessageContent()
    data class ScreenShare(
        val event: String,
        val detail: ScreenShareResponse? = null
    ) : OutgoingMessageContent()
}

Die Typen UploadableImage und UploadableVideo (in com.ccaiplatform.ccaikit.models.smartaction) verpacken Medien für den Upload:

data class UploadableImage(
    val data: ByteArray,       // The binary data of the image
    val mimeType: String,      // For example, "image/jpeg" or "image/png"
    val uri: Uri? = null       // Optional URI for display and local file reference
)

data class UploadableVideo(
    val uri: Uri,              // The file URI of the video
    val mimeType: String       // For example, "video/mp4"
)

Photos akzeptiert eine Liste von Bildern, Videos ein einzelnes Video. Vermeide es, große Medien-Assets im Arbeitsspeicher zu halten, während der Nutzer in der Warteschlange wartet oder ein Upload aussteht.

Beispiele für die Verwendung

// Send text message
lifecycleScope.launch {
    try {
        CCAI.chatService?.sendMessage(OutgoingMessageContent.Text("Hello world"))
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to send message: ${e.message}")
    }
}

// Send image message (read the file off the main thread)
lifecycleScope.launch {
    try {
        val imageData = withContext(Dispatchers.IO) {
            requireNotNull(contentResolver.openInputStream(selectedImageUri)).use { it.readBytes() }
        }
        val images = listOf(
            UploadableImage(data = imageData, mimeType = "image/jpeg", uri = selectedImageUri)
        )
        CCAI.chatService?.sendMessage(
            OutgoingMessageContent.Photos(
                images = images,
                smartAction = null
            )
        )
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to send image: ${e.message}")
    }
}

// Send video message (one video per message)
val video = UploadableVideo(uri = selectedVideoUri, mimeType = "video/mp4")

lifecycleScope.launch {
    try {
        CCAI.chatService?.sendMessage(
            OutgoingMessageContent.Videos(
                video = video,
                smartAction = null
            )
        )
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to send video: ${e.message}")
    }
}

// Send form completion event
// Note: status is a nullable String: "success", "error", or "cancelled".
val formCompleteData = FormCompleteEventData(
    smartActionId = 123,
    status = "success",
    timestamp = "2024-01-01T12:00:00Z",
    details = FormCompleteEventDetails(message = "Form submitted successfully")
)

lifecycleScope.launch {
    try {
        CCAI.chatService?.sendMessage(
            OutgoingMessageContent.FormComplete(data = formCompleteData)
        )
        Log.d("CCAI", "Form completion event sent")
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to send form completion: ${e.message}")
    }
}

Der Nachrichtentyp ScreenShare wird verwendet, um Ereignisse und Antworten zur Bildschirmfreigabe an den Server zu senden. Verfügbare Ereignisse für die Bildschirmfreigabe:

  • screenShareRequestedFromAgent – Kundenservicemitarbeiter hat Bildschirmfreigabe angefordert

  • screenShareRequestedFromEndUser – Endnutzer hat Bildschirmfreigabe angefordert

  • screenShareCodeGenerated – Code für die Bildschirmfreigabe wurde generiert

  • screenShareFailed – Bildschirmfreigabe fehlgeschlagen

  • screenShareStarted – Bildschirmfreigabe gestartet

  • screenShareEnded – Bildschirmfreigabe beendet

Eingabeanzeigen und Nachrichtenvorschauen

Aktualisieren Sie den Eingabestatus und senden Sie Nachrichtenvorschauen, während der Nutzer tippt:

// Update typing indicator
CCAI.chatService?.typing(true)   // Start typing
CCAI.chatService?.typing(false)  // Stop typing

// Send message preview
lifecycleScope.launch {
    try {
        CCAI.chatService?.sendMessagePreview("Typing...")
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to send message preview: ${e.message}")
    }
}

// Example: Send preview as user types
fun onTextChanged(text: String) {
    lifecycleScope.launch {
        try {
            CCAI.chatService?.sendMessagePreview(text)
        } catch (e: Exception) {
            Log.e("CCAI", "Failed to send preview: ${e.message}")
        }
    }
}

Nachrichtenentfernung

Das automatische Entfernen vertraulicher Informationen (personenidentifizierbare Informationen, Kreditkartennummern usw.) wird für Nur-Text-Chatnachrichten und Nachrichtenvorschauen unterstützt.

Konfiguration der Entfernung:

  • Wird durch das Attribut redactionEnabled in ChatResponse gesteuert.

  • Wird im Portal unter Einstellungen > Chateinstellungen > Automatische Schwärzung konfiguriert.

  • Wenn diese Option aktiviert ist, werden sensible Daten automatisch durch Platzhalter ersetzt, bevor sie an Agenten gesendet werden.

// Redaction is automatically handled, use sendMessage as usual
lifecycleScope.launch {
    try {
        CCAI.chatService?.sendMessage(
            OutgoingMessageContent.Text("My phone number is 4155553423")
        )
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to send message: ${e.message}")
    }
}

Chats beenden und eskalieren

// End the current chat session
lifecycleScope.launch {
    try {
        CCAI.chatService?.endChat()
        Log.d("CCAI", "Chat ended successfully")
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to end chat: ${e.message}")
    }
}

// Escalate to a human agent
lifecycleScope.launch {
    try {
        CCAI.chatService?.escalateToHumanAgent()
        Log.d("CCAI", "Chat escalated to human agent")
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to escalate chat: ${e.message}")
    }
}

// Record the deflection channel the user chose for an existing escalation
// (the escalation must already exist; start one with escalateToHumanAgent())
val escalationOption = ChatEscalationOption(
    escalationId = 123,
    deflectionChannel = DeflectionChannel.Email
)

lifecycleScope.launch {
    try {
        CCAI.chatService?.updateEscalation(option = escalationOption)
        Log.d("CCAI", "Escalation updated successfully")
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to update escalation: ${e.message}")
    }
}

// Check the current chat status
lifecycleScope.launch {
    try {
        CCAI.chatService?.checkStatus()
        Log.d("CCAI", "Status check completed successfully")
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to check status: ${e.message}")
    }
}

Chat-Ereignisse

Senden Sie Chatereignisse an den Server, um Nutzerinteraktionen zu erfassen. ChatEvent.payload ist ein nicht-nullbarer Map<String, String>. Sowohl Schlüssel als auch Werte müssen Strings sein.

val event = ChatEvent(
    name = "form_received",
    payload = mapOf("name" to "contact_form")
)

lifecycleScope.launch {
    try {
        CCAI.chatService?.sendEvent(event)
        Log.d("CCAI", "Event sent successfully")
    } catch (e: Exception) {
        Log.e("CCAI", "Failed to send event: ${e.message}")
    }
}

Zu den gängigen Anwendungsfällen für Ereignisse gehören Formularinteraktionen („form_received“, „form_clicked“), Smart Action-Ereignisse („smart_action_received“, „smart_action_clicked“) und benutzerdefinierte Nutzerinteraktionen für Analysen.

Modulspezifische Überlegungen zum Build

Beachten Sie Folgendes für einen modulspezifischen Build.

Mindest-SDK-Level

Für die Media-Layer-Module CCAIChatRed und CCAICallRed ist mindestens SDK = 23 (Android 6.0) erforderlich. Wenn deine App eine niedrigere minSdkVersion deklariert, kann Gradle die Manifeste nicht zusammenführen. Erhöhe deine min Sdk auf mindestens 23 in app/build.gradle.kts:

android {
    defaultConfig {
        minSdk = 23
    }
}