Halaman ini menjelaskan cara menggunakan Android SDK.
Mengakses aplikasi contoh
Untuk mendownload aplikasi contoh Android, klik Aplikasi contoh Android.
Untuk membuat aplikasi contoh menggunakan SDK seluler Android, Anda memerlukan hal berikut:
Kunci Perusahaan dan Rahasia Perusahaan portal CCAI Platform.
Android 5.0 (level API 21, Lollipop) atau yang lebih baru.
Firebase Cloud Messaging atau Google Cloud Messaging untuk notifikasi push.
Aplikasi dimigrasikan ke AndroidX.
Persyaratan upgrade SDK Twilio
Memerlukan Twilio SDK untuk mengikuti versi tertentu jika Android SDK diintegrasikan menggunakan paket kami secara langsung, jika tidak, hal ini dapat diabaikan.
// Twilio VoIP SDK
api 'com.twilio:voice-android:6.1.1'
// Twilio Conversations SDK
api 'com.twilio:conversations-android:3.1.0'
Selain itu, aturan Proguard sudah disertakan dalam Android SDK untuk memastikan bahwa library Twilio Programmable Voice tidak dihapus oleh ProGuard dan dapat digunakan untuk memecahkan masalah jika ProGuard tidak sengaja menghapus library tersebut.
-keep class com.twilio.** { *; }
-keep class tvo.webrtc.** { *; }
-dontwarn tvo.webrtc.**
-keep class com.twilio.voice.** { *; }
-keepattributes InnerClasses
Untuk mendukung versi Twilio terbaru, mulai dari Android SDK versi 0.34.0, SDK tidak lagi kompatibel secara biner dengan aplikasi yang menargetkan Java 7. Untuk menggunakan rilis ini dan rilis mendatang, developer harus mengupgrade aplikasi mereka untuk menargetkan Java 8. Lihat contoh kode berikut:
android {
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
Mendapatkan kunci perusahaan dan rahasia perusahaan
Login ke Portal Admin menggunakan kredensial Admin.
Buka Setelan > Setelan Developer > Kunci Perusahaan & Kode Rahasia.
Ambil Company Key dan Company Secret Code.
Penginstalan
Tambahkan repositori Android SDK ke setelan Gradle untuk project root.
build.gradle (Project)
allprojects {
repositories {
google()
jcenter()
maven {
url "https://sdk.ujet.co/android/"
}
}
}
build.gradle (module: 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"
}
Menyiapkan setelan perusahaan
Masukkan setelan perusahaan Anda sebagai metadata dalam file 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>
Penandatanganan JWT
Informasi pengguna akhir harus ditandatangani sebagai JWT di server Anda untuk tujuan keamanan.
Aplikasi contoh berisi APIManager untuk pengujian dan Anda harus menempatkan UJET_COMPANY_SECRET di mock/APIManager.java. APIManager harus menerapkan metode yang memulai panggilan asinkron untuk menandatangani token autentikasi JWT yang menampilkan token.
Dalam produksi, Anda harus menerapkan proses penandatanganan di server Anda.
public class APIManager {
public static final String UJET_COMPANY_SECRET = "Please input your UJET_COMPANY_SECRET from Ujet developer admin page";
// ...
}
Melakukan inisialisasi SDK
Lakukan inisialisasi SDK di metode onCreate class Aplikasi Android.
public class ExampleApplication extends Application implements UjetRequestListener {
@Override
public void onCreate() {
super.onCreate();
Ujet.init(this);
}
// ...
}
Autentikasi pengguna akhir
Pengguna akhir adalah konsumen yang menghubungi tim dukungan pelanggan Anda melalui aplikasi.
Untuk mengautentikasi pengguna akhir dalam aplikasi, kami memperkenalkan mekanisme penandatanganan JWT.
Android SDK meminta untuk menandatangani payload saat memerlukan autentikasi. Jika penandatanganan berhasil, aplikasi akan menukar JWT yang ditandatangani dengan token autentikasi pengguna akhir.
Di ExampleApplication, Anda harus mengimplementasikan antarmuka UjetRequestListener
untuk menandatangani token autentikasi dan untuk data kustom.
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();
}
});
}
}
}
Untuk mengetahui informasi selengkapnya, lihat autentikasi pengguna akhir.
Menyiapkan notifikasi push
Bagian ini menjelaskan cara mengaktifkan notifikasi push seluler.
Menyiapkan Firebase
Anda harus menyiapkan project Firebase.
Jika sudah memiliki project, Anda dapat menggunakan project Anda sendiri dan melewati proses ini.
Buat project Firebase di Firebase console.
Download google-services.json dari Settings > GENERAL di Firebase console.

- Dapatkan Kunci Server dari Settings > CLOUD MESSAGING di Firebase console.

Menambahkan kunci akun layanan
Anda harus menambahkan kunci akun layanan ke aplikasi seluler untuk menerima notifikasi push. Untuk mendapatkan kunci akun layanan, lihat Melakukan autentikasi dengan akun layanan.
Untuk menambahkan kunci akun layanan ke aplikasi seluler Anda, ikuti langkah-langkah berikut:
Di portal CCAI Platform, klik Settings > Developer Settings. Jika Anda tidak melihat menu Setelan, klik Menu.
Buka panel Mobile Apps.
Klik Edit di samping aplikasi Anda. Dialog Edit Mobile App akan muncul.
Di Service Account Field, masukkan kunci akun layanan Anda, lalu klik Save.
Penyiapan klien Android
Salin
google-services.jsonke direktori aplikasi Anda, misalnya,PROJECT_ROOT/app/google-services.json.Dapatkan token
FCMmenggunakan kode berikut: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); });FirebaseMessagingServicedipanggil, yang terdaftar di Manifes jika token diperbarui. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan aplikasi klien Firebase Cloud Messaging di 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); } }Terapkan
UjetRequestListener.onRequestPushTokendi class Application Anda.UjetRequestListener.onRequestPushTokenakan menampilkan 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 -> { }) } }Menangani notifikasi push. Jika Anda ingin Contact Center AI Platform (CCAI Platform) menangani pemrosesan pesan push-nya sendiri, Anda dapat meneruskan data langsung ke
UjetPushHandler.handle().Aplikasi hanya memproses pesan dengan kolom
ujet_noti_type(ataunoti_type, untuk kompatibilitas mundur) yang ditetapkan.Atau, Anda dapat memilih untuk hanya mengirim pesan dengan
ujet_noti_typekeUjetPushHandler.handle()untuk diproses.
Berikut adalah contoh pesan notifikasi push:
{ "call_id" : 12345, "ujet_noti_type" : "connect_call", "noti_type" : "connect_call", "call_type" : "ScheduledCall", "fail_reason" : "none", "fail_details" : "none" }
Menangani pesan 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
}
}
}
Menangani pesan 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
}
}
}
Menangani pesan GCM di GcmReceiver (Cara lama)
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
}
}
}
Memulai aplikasi
Tambahkan baris berikut di tempat Anda ingin memulai aplikasi (tanpa parameter apa pun):
Ujet.start(new UjetStartOptions.Builder().build());
Anda juga dapat memulai Android SDK tanpa layar pembuka.
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setSkipSplashEnabled(true)
.build();
Ujet.start(ujetStartOptions);
Anda juga dapat memulai Android SDK dari titik tertentu di menu dengan kunci ini menggunakan Titik Akses Langsung:
String menuKey = "MENU_KEY";
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setMenuKey(menuKey)
.build();
Ujet.start(ujetStartOptions);
menuKey dapat dibuat dengan Direct Access Point di portal CCAI Platform
(dengan peran Admin).
Buka Setelan > Antrean.
Pilih antrean dari struktur menu.
Centang Create direct access point.
Masukkan kunci di formulir teks.
Klik Simpan.

Anda juga dapat memulai Android SDK dengan ID tiket tertentu untuk meneruskannya ke CRM. ID tiket ini akan dibuka saat chat atau panggilan terhubung.
String ticketId = "TICKET_ID";
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
.setTicketId(ticketId)
.build();
Ujet.start(ujetStartOptions);
Konfigurasi SDK
Anda dapat mengonfigurasi beberapa opsi sebelum memulai Android SDK. Lihat class UjetOption. Opsi Nomor Telepon Pengganti dan Sensitivitas Jaringan
yang dijelaskan dalam tabel berikut hanya berfungsi jika tombol Enable PSTN Fallback
diaktifkan di portal CCAI Platform di Settings > Developer Settings >
MMA > Edit. Jika tombol Aktifkan Penggantian PSTN dinonaktifkan, kami tidak akan beralih ke PSTN. CCAI Platform menggunakan sensitivitas jaringan default (0,85) untuk memeriksa koneksi jaringan.
| Opsi | Deskripsi | Nilai | Nilai default |
|---|---|---|---|
| Tingkat Log | Level log yang akan dicetak di Logcat. | Bilangan bulat. Sama dengan Log level untuk Android Log. (Min: 2, Maks: 7) | 5 (Log.Warn) |
| Bahasa Default | Kode bahasa default. | String. Kode bahasa ISO 639. (misalnya, en untuk bahasa Inggris) | null |
| Nomor Telepon Pengganti | Nomor telepon digunakan sebagai pengganti saat internet tidak tersedia atau nomor telepon perwakilan untuk perusahaan tidak ada di portal Admin. | String. Nomor telepon. | null |
| Pengendali Pengecualian yang Tidak Tertangkap Diaktifkan | Mengaktifkan pengendali pengecualian yang tidak tertangkap. Jika true, aplikasi akan menangani semua pengecualian SDK yang tidak tertangkap saat runtime menggunakan Thread.setDefaultUncaughtExceptionHandler. Namun, jika pengecualian yang sama terjadi dua kali, aplikasi akan error. |
Boolean. | true |
| Sensitivitas Jaringan | Sensitivitas untuk memeriksa status jaringan. | Double antara 0 dan 1, dengan 0 adalah yang paling tidak sensitif dan 1 adalah yang paling sensitif. Nilai 1 akan selalu di-fallback ke panggilan PSTN. Jika digunakan, sebaiknya mulai dengan nilai .97. Nilai dari Portal di bagian Settings > Developer Settings > Mobile Apps > Fallback phone number threshold akan menggantikan nilai ini. |
0.85 |
| Mode Gelap Diaktifkan | Aktifkan tema mode gelap. Jika true, SDK akan menerapkan tema mode gelap saat pengguna mengaktifkan mode gelap, dan mengabaikan tindakan tersebut jika tidak. |
Boolean. | false |
| Saluran Tunggal Diaktifkan | Opsi konfigurasi untuk menampilkan atau mengabaikan layar pemilihan channel untuk satu channel. Jika true, SDK akan menampilkan layar pemilihan satu saluran, bukan memilih saluran secara otomatis, meskipun hanya satu saluran yang diaktifkan dalam antrean menu. |
Boolean. | false |
| Minimalkan Tampilan Panggilan Otomatis | Opsi konfigurasi untuk otomatis meminimalkan UI layar panggilan awal secara default atau menunggu pengguna meminimalkannya. | Boolean. | false |
| Batas Ikon Agen Diaktifkan | Opsi konfigurasi untuk menampilkan atau menghapus batas melingkar di sekitar ikon agen. | Boolean. | false |
| Ukuran Font Statis di Tampilan Pemilih | Opsi konfigurasi untuk menyesuaikan atau menonaktifkan ukuran teks item pemilih secara otomatis. | Boolean. | false |
| Sembunyikan Lampiran Media Di Chat | Opsi konfigurasi untuk menampilkan atau menyembunyikan ikon lampiran media di UI chat. | Boolean. | false |
Mengabaikan Izin READ_PHONE_STATE |
Jika ditetapkan ke true, SDK tidak akan meminta izin READ_PHONE_STATE. Jika Anda tidak ingin menggunakan panggilan IVR dalam aplikasi, tetapkan tanda ini ke true untuk menghindari permintaan izin ini dan aplikasi Anda juga harus secara eksplisit menghapus izin android.permission.READ_PHONE_STATE untuk CCAI Platform SDK. Perhatikan bahwa sebaiknya jangan tetapkan ini ke true, karena izin ini diperlukan agar panggilan IVR dalam aplikasi berfungsi. |
Boolean | false |
| Kunci Lisensi Cobrowse.io (jika ada) | Opsi konfigurasi untuk menyiapkan library Cobrowse.io. Anda dapat menemukan Kunci Lisensi Cobrowse dengan login ke https://cobrowse.io/dashboard/settings dan membuka bagian License Key. |
String | null |
| Judul header chat kustom | Opsi konfigurasi untuk menyesuaikan teks judul header chat di UI chat. | String | null |
| Menyesuaikan balasan cepat UI chat | Opsi konfigurasi untuk menyesuaikan balasan cepat agen virtual di UI chat. Balasan cepat agen virtual dikelompokkan secara default, tetapi jika Anda ingin menampilkannya satu per satu, Anda dapat menggunakan opsi konfigurasi ini untuk menetapkan QuickReplyButtonsStyle.INDIVIDUAL | UjetStylesOptions | QuickReplyButtonsStyle.GROUPED |
| Menyesuaikan berbagai atribut UI chat | Opsi konfigurasi untuk menyesuaikan berbagai atribut seperti font, warna latar belakang, ikon, dll. | UjetStylesOptions | null |
| Sembunyikan status bar | Opsi konfigurasi untuk menampilkan atau menyembunyikan status bar. Jika nilainya benar, SDK akan menyembunyikan status bar. | Boolean | false |
| Menetapkan res drawable indikator lingkaran berputar pemuatan | Opsi konfigurasi untuk menyesuaikan tampilan indikator lingkaran berputar di seluruh aplikasi. Jika tidak tersedia atau null, kami akan menggunakan tampilan pemuatan default. | Bilangan bulat | null |
| Orientasi lanskap dinonaktifkan | Nonaktifkan orientasi lanskap. Jika nilainya benar, orientasi lanskap tidak akan diterapkan. | Boolean | false |
| Sembunyikan tombol inline mulai percakapan baru di chat | Opsi konfigurasi untuk menampilkan atau menyembunyikan tombol inline mulai percakapan baru di UI chat. | Boolean | false |
| Tampilkan tombol lewati CSAT | Opsi konfigurasi untuk menampilkan atau menyembunyikan tombol lewati di dialog CSAT | Boolean | false |
| Memblokir penghentian chat oleh pengguna akhir | Opsi konfigurasi untuk menampilkan atau menyembunyikan tombol akhiri chat di UI chat | Boolean | false |
| Sembunyikan download transkrip chat | Menampilkan atau menyembunyikan tombol download transkrip chat di menu tindakan chat dan di antarmuka pengguna chat. Jika Anda menambahkan spasi ke string ujet_common_hide, teks Hide akan hilang dan hanya panah kembali yang akan muncul. |
Bilangan bulat. Nilai:
|
0
|
| Menonaktifkan notifikasi push di tingkat global | Menyetel UjetOption.setPushNotificationsAllowed ke false akan mengabaikan semua dependensi notifikasi push dan mencegah notifikasi push menjangkau pengguna akhir. |
Boolean | true |
| Sembunyikan Ketersediaan berikutnya | Tampilkan atau sembunyikan pesan Ketersediaan berikutnya di layar pemeriksaan chat di luar jam kerja. | Boolean | false |
| Sembunyikan Mulai dari awal | Menampilkan atau menyembunyikan tombol Mulai ulang di layar check-in chat di luar jam kerja. | Boolean | 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()
)
Izin aplikasi
Aplikasi memerlukan izin berikut dan meminta izin ini dari pengguna jika diperlukan.
| Izin | Deskripsi |
|---|---|
| KAMERA | Digunakan untuk tindakan cerdas guna mengambil foto dan merekam video |
| MIKROFON | Mengizinkan aplikasi menggunakan panggilan VoIP melalui Twilio |
| STORAGE | Mengizinkan aplikasi menyimpan foto dan video |
Preferensi bahasa
Android SDK akan menggunakan urutan prioritas berikut untuk menentukan bahasa.
Bahasa yang dipilih dari layar pembuka dalam aplikasi.
Bahasa default dipilih menggunakan
UjetOptions. Anda dapat menetapkan bahasa default menggunakansetDefaultLanguage("en")diUjetOptions. Lihat Bahasa Default di bagian konfigurasi SDK untuk mengetahui detail selengkapnya.Bahasa perangkat yang dipilih di perangkat (menggunakan Settings > General > Language) akan digunakan, jika didukung oleh aplikasi.
Dialek terdekat dari bahasa perangkat akan digunakan jika aplikasi tidak mendukung bahasa perangkat, tetapi mendukung dialek induk terdekatnya. Misalnya, jika pengguna memilih bahasa Spanyol Kuba sebagai bahasa di perangkat dan aplikasi tidak mendukung bahasa Spanyol Kuba, tetapi mendukung dialek induk bahasa Spanyol, bahasa Spanyol akan digunakan.
Bahasa Inggris akan digunakan sebagai bahasa default, jika bahasa perangkat tidak didukung oleh aplikasi.
Saluran pilihan
Parameter Saluran Pilihan memungkinkan Anda mengarahkan konsumen langsung ke saluran tertentu. Kemudian, pengguna akhir akan melewati langkah pemilihan saluran dan langsung memulai kontak melalui saluran yang ditentukan dalam parameter Preferred Channel.
UjetStartOptions.preferredChannel
Ujet.start(new)
UjetStartOptions.Builder().setPreferredChannel
(UjetPreferredChannel.UjetPreferredChannelChat).build());
Notifikasi Peristiwa
Anda dapat menetapkan UjetEventListener untuk menerima notifikasi peristiwa aplikasi.
Jenis dan deskripsi peristiwa yang tersedia tercantum di sini.
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());
}
});
| Jenis peristiwa | Deskripsi | Data yang disertakan dalam acara |
|---|---|---|
EmailClicked |
Dipicu saat pengguna akhir mengklik saluran email. | Mengantrekan data menu |
EmailSubmitted |
Dipicu saat pengguna akhir mengirim email. | Data menu antrean, data yang dikirimkan melalui email |
SessionPaused |
Dipicu saat pengguna akhir meminimalkan sesi chat atau panggilan. | Data sesi |
SessionResumed |
Dipicu saat pengguna akhir beralih kembali ke sesi chat atau panggilan dari latar belakang. | Data sesi |
SessionCreated |
Dipicu saat sesi chat atau panggilan dibuat. | Data menu antrean, data sesi yang dibuat |
SessionEnded |
Dipicu saat sesi chat atau panggilan diakhiri. | Data menu antrean, data sesi dibuat, data sesi berakhir |
SdkTerminated |
Dipicu saat SDK ditutup, termasuk saat ditutup secara tidak terduga. | Data penghentian SDK |
ContentCardClicked |
Dipicu saat kartu konten diklik. | Data kartu konten yang diklik |
ContentCardButtonClicked |
Dipicu saat tombol kartu konten diklik. | Data klik tombol kartu konten |
QuickReplyClicked |
Dipicu saat balasan cepat diklik. | Data klik balasan cepat |
MessageLinkClicked |
Dipicu saat link diklik. | Data link pesan yang diklik |
Mengantrekan data menu
| Kunci | Jenis | Deskripsi |
|---|---|---|
event_name |
String | Berisi nama peristiwa. Contoh, "Email Diklik". |
application |
String | Berisi nama aplikasi. Contoh, "Android". |
app_id |
String | Berisi ID aplikasi yang sama dengan Context.getPackageName(). |
app_version |
String | Berisi nama versi dan kode versi aplikasi. Contoh, "0.32.0 (123)". |
sdk_version |
String | Berisi versi SDK. Contoh, "0.32.0". |
timestamp |
String | Berisi stempel waktu dalam UTC (dalam format yyyy-MM-dd'T'HH:mm:ss'Z'). |
device_model |
String | Berisi model perangkat pengguna. Contoh, "Google Pixel". |
device_version |
String | Berisi versi perangkat pengguna. Contoh, "10, Q, SDK 29". |
company |
String | Berisi nama perusahaan. Contoh, "Perusahaan". |
menu_name |
String | Berisi nama node daun (pilihan menu terakhir pengguna). Contoh, "Sub Menu". |
menu_id |
String | Berisi ID node daun (pilihan menu terakhir pengguna). Contoh, "123". |
menu_path |
String | Berisi urutan lengkap menu yang dipilih oleh pengguna. Contoh, "Induk / Turunan / Submenu". |
menu_key |
String | Berisi kunci DAP dan bersifat opsional. Contoh, "special_user_menu". |
Data yang dikirimkan melalui email
| Kunci | Jenis | Deskripsi |
|---|---|---|
has_attachments |
Boolean | Menampilkan True jika email memiliki lampiran, False jika tidak. |
Data sesi
| Kunci | Jenis | Deskripsi |
|---|---|---|
event_name |
String | Berisi nama peristiwa. Contoh, "Email Diklik". |
type |
String | Berisi jenis sesi. Misalnya, "chat" atau "panggilan". |
timestamp |
String | Berisi stempel waktu dalam UTC (dalam format yyyy-MM-dd'T'HH:mm:ss'Z'). |
Data pembuatan sesi
| Kunci | Jenis | Deskripsi |
|---|---|---|
session_id |
String | Berisi ID sesi. Contoh, "100". |
type |
String | Berisi jenis sesi. Misalnya, "chat" atau "panggilan". |
end_user_identifier |
String | Berisi ID pengguna akhir. Contoh, "John". |
messages_end_user |
String | Berisi jumlah pesan pengguna akhir dan hanya disertakan untuk sesi chat. Contoh, "3". |
messages_agent |
String | Berisi jumlah pesan agen dan hanya disertakan untuk sesi chat. Contoh, "3". |
Data sesi berakhir
| Kunci | Jenis | Deskripsi |
|---|---|---|
agent_name |
String | Berisi nama agen. Contoh, "John". |
ended_by |
String | Berisi detail tentang siapa yang mengakhiri sesi. Nilai yang dapat digunakan adalah "agent" (saat agen mengakhiri sesi) atau "end_user" (saat pengguna akhir mengakhiri sesi) atau "timeout" (saat waktu tunggu chat habis) atau "dismissed" (saat chat ditutup). |
duration |
String | Berisi durasi sesi dalam detik dan hanya disertakan untuk sesi panggilan. Contoh, "30 detik". |
Data penghentian SDK
| Kunci | Jenis | Deskripsi |
|---|---|---|
event_name |
String | Berisi nama peristiwa. Contoh, "Email Diklik". |
Data klik kartu konten
| Kunci | Jenis | Deskripsi |
|---|---|---|
title |
string | Judul kartu. |
title |
string | Judul kartu. |
subtitle |
string | Subjudul kartu. |
body |
string | Deskripsi kartu konten. |
link | string | Link halaman web atau deeplink. SDK menggunakan kemampuan OS untuk membukanya. |
event_params | kamus | Kamus yang berisi informasi tambahan tentang peristiwa klik. SDK menggunakan ini. |
Data klik tombol kartu konten
| Kunci | Jenis | Deskripsi |
|---|---|---|
title |
string | Judul kartu. |
title |
string | Judul kartu. |
link | string | Link halaman web atau deeplink. SDK menggunakan kemampuan OS untuk membukanya. |
event_params | kamus | Kamus yang berisi informasi tambahan tentang peristiwa klik. SDK menggunakan ini. |
Data klik balasan cepat
| Kunci | Jenis | Deskripsi |
|---|---|---|
title |
string | Judul kartu. |
title |
string | Judul kartu. |
link | string | Link halaman web atau deeplink. SDK menggunakan kemampuan OS untuk membukanya. |
event_params | kamus | Kamus yang berisi informasi tambahan tentang peristiwa klik. SDK menggunakan ini. |
Data link pesan yang diklik
| Kunci | Jenis | Deskripsi |
|---|---|---|
event_name |
String | Berisi nama peristiwa—misalnya, "Message Link Clicked". |
link |
String | Link halaman web atau deep link. SDK menggunakan kemampuan OS untuk membukanya. |
Mengirim data kustom ke CRM Anda
Data kustom dapat dikirim ke agen dukungan dan akan muncul di tiket dukungan untuk panggilan/chat masuk.
Ada dua metode untuk mengirim data kustom:
Metode bertanda tangan: Penandatanganan data standar dengan JWT.
Metode tanpa tanda tangan: Data yang telah ditentukan dengan JSON biasa (tidak direkomendasikan).
Menggunakan metode bertanda tangan untuk mengirim data kustom
Untuk mengirim data kustom menggunakan metode bertanda tangan, terapkan metode penandatanganan.
Pertama, ambil data kustom ke aplikasi host, lalu kirimkan ke server Anda untuk ditandatangani. Di server, Anda dapat menambahkan data tambahan menggunakan formulir yang ditentukan. Tandatangani dengan rahasia perusahaan Anda, lalu tampilkan dengan 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));
}
// ...
}
}
Menggunakan metode tanpa tanda tangan untuk mengirim data kustom
Google merekomendasikan agar Anda menggunakan metode bertanda tangan untuk mengirim data kustom di aplikasi Anda. Untuk mengetahui informasi selengkapnya, lihat Menggunakan metode bertanda tangan untuk mengirim data kustom.
Anda dapat mengirim data yang tidak ditandatangani dengan memulai Android SDK dengan opsi mulai untuk menetapkan
data kustom menggunakan UjetStartOptions.Builder#setUnsignedCustomData dan
UjetTokenCallback harus memanggil 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);
Menggunakan data kustom yang tidak ditandatangani untuk mengirim transkrip chat eksternal
Anda dapat mengirim transkrip chat eksternal ke CCAI Platform menggunakan
data kustom yang tidak ditandatangani saat dimulai. Gunakan
UjetCustomData.putObject("external_chat_transfer", hashMapObject) untuk menetapkan
data transkrip dalam format JSON sebagai berikut:
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);
Format JSON:
greeting_override: stringagent: kamusname: stringavatar: string [URL avatar agen, opsional]
transcript: arraysender: string ["end_user" atau "agent"]timestamp: string [misalnya "2021-03-15 12:00:00Z"]content: arraytype: string [salah satu dari teks, media]text: string [wajib ada untuk jenis teks]media: kamus [wajib untuk jenis media]type: string [salah satu dari image, video]url: string [URL publik yang mengarah ke file media]
Contoh 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"
}
]
}
]
}
Anda dapat menggunakan Markdown pada jenis teks. Format berikut didukung:
Tebal
Miring
Menggarisbawahi
Pemisah baris
Daftar berbutir
Daftar bernomor
Link
Format data kustom
Bagian ini menunjukkan format data kustom yang dapat diteruskan di JWT.
JSON dienkode ke JWT
JSON harus menyertakan iat dan exp untuk memvalidasi JWT. Objek data kustom adalah nilai kunci 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"
}
}
}
Kunci adalah ID unik untuk data. Jenis adalah jenis nilai.
string- String JSON
number- integer, float
date- Format stempel waktu Unix UTC dengan 13 digit. (berisi milidetik)
url- Format URL HTTP
Label adalah nama tampilan di halaman CRM.
Mencegah tampilan data pelanggan
Anda dapat menggunakan properti invisible_to_agent dengan objek data kustom untuk
mencegah data kustom yang ditandatangani atau tidak ditandatangani ditampilkan di adaptor
agen. Dalam contoh sebelumnya, nomor jaminan sosial pengguna akhir tidak
ditampilkan di adaptor agen karena "invisible_to_agent" : true disertakan dalam
objek ssn.
Jika Anda menyertakan properti "invisible_to_agent" : true dengan objek data kustom,
Anda dapat mengharapkan perilaku berikut:
- Data kustom disertakan dalam file metadata sesi.
- Data kustom tidak disertakan dalam data CRM.
Untuk mengetahui informasi selengkapnya, lihat Melihat data sesi di adaptor agen.
Properti data yang dicadangkan
Anda dapat mengirim properti data yang dicadangkan ke Contact Center AI Platform (CCAI Platform) sebagai data kustom yang ditandatangani saat sesi dimulai. Untuk mengetahui informasi selengkapnya, lihat Mengirim properti data yang dicadangkan.
Berikut adalah contoh properti data yang dicadangkan dalam data kustom:
{
"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"
}
}
}
Tetapkan setiap nilai ke true atau false.
reserved_verified_customer:truejika Anda menganggap pengguna akhir ini sebagai pelanggan yang sah.reserved_bad_actor:truejika Anda menganggap pengguna akhir ini berpotensi menjadi pelaku kejahatan.reserved_repeat_customer:truejika Anda telah menentukan bahwa pengguna akhir ini pernah menghubungi pusat kontak Anda sebelumnya.
Pengganti
Anda dapat menggunakan UjetErrorListener untuk penggantian error yang tidak terduga. Jika
Anda tidak menetapkan pemroses ini atau menampilkan nilai salah, Android SDK akan
menangani error tersebut.
Android SDK akan mengalihkan pengguna ke dialer dengan nomor pengganti hanya jika tombol Aktifkan Penggantian PSTN AKTIF di Setelan > Setelan Developer > MMA > Edit pop-up, jika tidak, keluar dari SDK.
| Jenis Error | Kode Error | Pemicu |
|---|---|---|
| NETWORK_ERROR | 1 | Jaringan tidak tersedia. Perhatikan bahwa error ini tidak dipicu saat jaringan tidak tersedia selama chat atau panggilan atau layar rating. |
| AUTHENTICATION_ERROR | 100 | Terjadi error tidak terduga selama autentikasi. |
| AUTHENTICATION_JWT_ERROR | 101 | Terjadi error tidak terduga selama validasi JWT (misalnya, error penguraian). |
| VOIP_CONNECTION_ERROR | 1000 | Gagal membuat koneksi ke penyedia VoIP. Hal ini ditangani melalui callback SDK VoIP. |
| VOIP_LIBRARY_NOT_FOUND | 1001 | Panggilan diharapkan terhubung menggunakan penyedia VoIP, tetapi tidak dapat ditemukan. Hal ini dapat terjadi jika developer mengintegrasikan SDK yang salah atau tidak menambahkan library penyedia VoIP dalam dependensinya. |
| CHAT_LIBRARY_NOT_FOUND | 1.100 | Terjadi saat tidak dapat menemukan library chat. Hal ini dapat terjadi jika developer mengintegrasikan SDK yang salah atau tidak menambahkan library Twilio Chat dalam dependensinya. |
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());
}
});
Deep linking
Jika ingin menggunakan tindakan cerdas untuk panggilan IVR (PSTN), Anda harus menyiapkan deep linking di project Anda.
Format deep linking adalah URI unik seperti:
ujet:// <package_name>/smartchannel.
Selain itu, Anda harus menetapkan link ini atau URL apa pun yang akan mengalihkan ke link ini di Portal Admin (Setelan > Pengelolaan Operasi > Aktifkan Kirim SMS untuk Mendownload Aplikasi).
Anda harus menambahkan filter intent yang berisi deep link di manifes Anda.
<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>
Ketahanan live chat
Untuk meningkatkan waktu beroperasi live chat, konfigurasikan ketahanan live chat. Tindakan ini akan menambahkan lapisan media pesan penggantian sekunder yang digunakan jika lapisan media utama gagal.
Untuk menambahkan kemampuan ini, tambahkan dependensi berikut ke file build.gradle level modul:
dependencies {
implementation "co.ujet.android:chat_blue:VERSION"
}
Ganti VERSION dengan SDK UJET versi terbaru.
Perubahan perilaku panggilan masuk
Mulai perangkat Android versi 10, panggilan masuk tidak akan diterima langsung oleh pengguna akhir saat aplikasi host berada di latar belakang. Sebagai gantinya, kami menggunakan notifikasi untuk memberi tahu pengguna tentang panggilan masuk (bahkan saat ponsel terkunci) yang memberi mereka opsi untuk menerima atau menolak panggilan.
Kami menampilkan notifikasi yang sama saat aplikasi host berada di latar belakang dan mengunci layar sebelum panggilan masuk diterima. Perubahan perilaku ini bertujuan untuk mematuhi batasan terbaru Google untuk memulai aktivitas saat aplikasi berada di latar belakang. Perilaku tidak terpengaruh saat aplikasi host berada di latar depan atau berjalan di perangkat dengan versi Android 10 atau yang lebih rendah.
Menyesuaikan sesi SDK
Bagian ini menjelaskan cara menyesuaikan SDK lebih lanjut.
Memeriksa sesi yang ada
Sebelum memulai sesi, gunakan metode yang dijelaskan untuk memeriksa apakah ada sesi yang sudah ada atau sedang berlangsung. Jika ada, Anda dapat meminta pengguna akhir untuk melanjutkan atau membatalkannya.
Hal ini sangat penting saat pengguna diubah.
if (Ujet.getStatus() != UjetStatus.None) {
// Display alert to cancel login or resume existing session
}
Memutuskan koneksi sesi
Lihat metode ini jika Anda ingin memutuskan koneksi sesi yang sedang berlangsung.
Sebelum menggunakan metode ini, pastikan untuk memeriksa apakah sesi tersebut ada menggunakan
Ujet.getStatus(). Jika Anda ingin melakukan tindakan setelah SDK
memutuskan koneksi sesi, misalnya, menampilkan pesan atau menutup
aplikasi, Anda dapat menggunakan callback respons onFinished() seperti yang dibahas di bagian
berikutnya, atau tetapkan callback ke null.
Ujet.disconnect(new UjetResponseCallback() {
@Override
public void onFinished() {
// `onFinished()` is triggered after CCAI Platform disconnects the session.
finish(); // Finishes the activity.
}
});
Menghapus data pengguna akhir dari cache
Anda bertanggung jawab untuk menghapus cache saat data terkait pengguna akhir telah diperbarui atau diubah dari aplikasi Anda. Misalnya, jika pengguna akhir telah logout, panggil metode untuk menghapus cache bagi pengguna tersebut sehingga sesi baru dimulai untuk pengguna akhir baru saat SDK dimulai berikutnya.
Ujet.clearUserData();
Menyembunyikan SDK
Anda dapat menyembunyikan SDK menggunakan metode Ujet.hideSDK(). Hal ini berguna, misalnya, saat
SDK mengganggu antarmuka pengguna aplikasi Anda. Lakukan inisialisasi SDK menggunakan Ujet.init() sebelum memanggil metode ini. Ujet.init() menampilkan true jika
SDK berhasil disembunyikan, dan false jika tidak. Setelah menyembunyikan SDK, Anda
dapat memulainya lagi menggunakan metode Ujet.start().
Contoh berikut menyembunyikan SDK:
Ujet.hideSDK();
Mengonfigurasi ikon link pengalihan eksternal
Sesuaikan ikon di saluran Link Pengalihan Eksternal dengan mengupload ikon ke folder drawable aplikasi Anda dan pastikan Anda menggunakan nama ikon yang sama saat membuat link pengalihan eksternal di portal CCAI Platform di Settings > Chat > External Deflection Links > View links > Add Deflection Link.
Jika nama ikon di portal CCAI Platform tidak cocok dengan ikon yang diupload ke aplikasi, Android SDK akan menggunakan ikon default.
Mengonfigurasi ikon Terima Kasih survei
Anda dapat menyesuaikan atau mengganti ikon di halaman terima kasih survei dengan mengupload
ikon ke folder drawable aplikasi Anda dan menggunakan nama file
ujet_survey_thank_you_icon sebagai nama ikon.
Penyesuaian UI dan string
Bagian ini menjelaskan cara menyesuaikan string, kartu konten, tema, dan header chat.
String
Anda dapat menyesuaikan string yang digunakan dalam aplikasi dengan mengganti kunci untuk setiap string di 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>

Penyesuaian ukuran teks
Sesuaikan judul, deskripsi, dan ukuran teks pemilih yang digunakan dalam aplikasi dengan mengganti kunci berikut di dimens.xml.
Ukuran teks yang dapat disesuaikan diuraikan:
<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
Sesuaikan tema dan latar belakang dengan langkah-langkah berikut. Langkah 1 untuk tema dan langkah 2 untuk latar belakang.
Sesuaikan tema dengan mengganti kunci untuk setiap item gaya di style.xml. Misalnya,
<!--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>Anda dapat menyesuaikan warna latar belakang dalam aplikasi dengan mengganti kunci untuk setiap item gaya di style.xml. Warna latar belakang yang dapat disesuaikan ditampilkan dalam screenshot.
<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>
Menyesuaikan judul header chat
Tersedia opsi untuk menyesuaikan teks judul header chat dalam chat di UI Anda.
Anda dapat menyesuaikan teks judul header chat menggunakan opsi berikut:
<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>
Anda dapat menyesuaikan balasan cepat Agen Virtual di UI chat menggunakan opsi berikut:
<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>
Kartu konten
Anda dapat menambahkan penyesuaian untuk kartu konten bersama dengan penyesuaian chat. Anda
dapat melakukannya dengan menggunakan file JSON (lihat content_card property
dalam file app/src/main/assets/json/ujet_styles.json) atau dengan menggunakan
class 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 formulir web
Anda dapat menyesuaikan kartu formulir web bersama dengan penyesuaian chat. Anda dapat
melakukannya menggunakan file JSON (lihat properti form_card dalam
file app/src/main/assets/json/ujet_styles.json) atau menggunakan
class 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,
),
)
)
Survei
Anda dapat mengubah ikon di halaman terima kasih survei dengan mengupload ikon ke folder drawable aplikasi.
Pastikan Anda menggunakan ujet_survey_thank_you_icon sebagai nama ikon.
Menyesuaikan dialog izin berbagi layar
Untuk menyesuaikan dialog izin berbagi layar, terapkan
class abstrak CoBrowseAlertProvider. Anda dapat menggunakan DialogFragment atau
AlertDialog untuk menerapkan dialog izin kustom.
Jika Anda menggunakan
DialogFragment, sertakan dua tombol, satu untuk menerima dan satu untuk menolak izin. Teruskan instanceDialogFragmentkustom ke callbackdialogInstance.Jika Anda menggunakan
AlertDialog, jangan teruskan instanceDialogFragmentke callbackdialogInstance.
Setelah mendapatkan izin, teruskan ke SDK dengan memanggil callback consentStatus
dan meneruskan nilai boolean yang sesuai.
Gunakan contoh kode berikut untuk menerapkan dialog izin kustom:
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
}
}
Teruskan implementasi ini ke SDK menggunakan API berikut:
Ujet.setCoBrowseAlertProvider(CoBrowseAlertProviderImpl())
Mengonfigurasi formulir web
Untuk mengonfigurasi formulir web, terapkan metode ujetWebFormDidReceive dari
antarmuka UjetWebFormListener. Metode ini menerima peristiwa (peta FormMessageReceived) sebagai parameter, yang berisi informasi terkait formulir.
Peristiwa ini mencakup struktur JSON berikut:
{
"type": "form_message_received",
"smart_action_id": 1,
"external_form_id": "external_foobar",
"signature": "4868a7e1dcb5..."
}
Menangani peristiwa
Untuk menangani peristiwa, ikuti langkah-langkah berikut:
- Ekstrak informasi yang relevan dari peta peristiwa (
smart_action_id,external_form_id, dansignature). - Buat URI formulir dan tanda tangan untuk data formulir.
- Teruskan data formulir ke SDK sebagai peta
FormDataEventmenggunakancallback.onEvent(formDataEvent). - Jika terjadi error selama pembuatan URI atau tanda tangan, panggil callback error menggunakan
callback.onError().
Peta (FormDataEvent) yang diteruskan ke SDK harus memiliki struktur berikut:
{
"type": "form_data",
"signature": "4868a7e1dcb5...",
"data": {
"external_form_id": "form_id",
"smart_action_id": 1,
"uri": "foobar"
}
}
Tanda tangan (HMAC-SHA256) harus dibuat menggunakan data, yang ditandatangani dengan kunci rahasia bersama. Kunci objek data harus diurutkan menurut abjad sebelum membuat tanda tangan dan data yang sama harus dikirim ke SDK.
Contoh kode berikut menunjukkan cara menerapkan pemroses formulir web:
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()
}
}
}
Teruskan implementasi ini ke SDK menggunakan API berikut:
Ujet.setUjetWebFormListener(UjetWebFormListenerImpl())
Pemecahan masalah
Memulai chat baru memerlukan waktu lebih dari 30 detik
Periksa apakah Anda merespons metode delegasi data kustom. Anda harus menampilkan data kustom yang valid sesuai permintaan atau cukup menampilkan null dengan callback. Gunakan kode berikut sebagai referensi.
@Override
public void onSignPayloadRequest(Map<String, Object> payload, UjetPayloadType ujetPayloadType, UjetTokenCallback tokenCallback) {
if (ujetPayloadType == UjetPayloadType.CustomData) {
tokenCallback.onToken(null);
}
}
Penjelasan pernyataan kebijakan
Jika Anda menerima notifikasi di Konsol Google Play yang meminta Anda untuk menyatakan kebijakan terkait layanan atau izin yang digunakan oleh Android SDK, gunakan salah satu penjelasan berikut.
Mendeklarasikan layanan latar depan yang digunakan oleh Android SDK
Google memperkenalkan jenis layanan latar depan di Android 14 dan mewajibkannya untuk ditentukan saat memulai layanan latar depan, sesuai dengan https://developer.android.com/about/versions/14/changes/fgs-types-required#remote-messaging. Android SDK Contact Center AI Platform (CCAI Platform) menggunakan layanan latar depan untuk memulai chat dan panggilan, jadi kami menggunakan jenis layanan FOREGROUND_SERVICE_REMOTE_MESSAGING untuk chat karena kami menangani pesan teks dan jenis layanan FOREGROUND_SERVICE_MICROPHONE untuk panggilan. Tanpa jenis layanan ini, SDK akan error saat memulai chat atau panggilan mulai dari perangkat Android versi 14.
Menyatakan izin intent layar penuh yang digunakan oleh Android SDK
Izin USE_FULL_SCREEN_INTENT diperlukan untuk menampilkan notifikasi push panggilan masuk saat perangkat terkunci. Tindakan ini akan memberi tahu pengguna akhir dan menampilkan notifikasi panggilan masuk dalam layar penuh (ini adalah cara aplikasi telepon bawaan memberi tahu panggilan masuk kepada pengguna akhir).
Mendukung Android 15
Untuk mendukung Android 15, ikuti langkah-langkah berikut:
Tetapkan
compileSdkVersion = 35dantargetSdkVersion = 35dibuild.gradle(:app)Anda.Pastikan versi Plugin Android Gradle (AGP) project Anda adalah 8.5.1 atau yang lebih baru. Untuk mengetahui informasi selengkapnya, lihat Mengupdate pengemasan library bersama.
Instal Java Development Kit (JDK) versi 17 atau yang lebih baru untuk mem-build project Android menggunakan AGP 8.0 atau yang lebih baru. Untuk mengetahui informasi selengkapnya, lihat JDK 17 diperlukan untuk menjalankan AGP 8.0.