Android SDK 가이드

이 페이지에서는 Android SDK 사용 방법을 설명합니다.

예시 앱에 액세스

Android 예시 앱을 다운로드하려면 Android 예시 앱을 클릭합니다.

Android 모바일 SDK를 사용하여 예시 앱을 만들려면 다음이 필요합니다.

  • CCAI Platform 포털 회사 키 및 회사 보안 비밀

  • Android 5.0 (API 수준 21, Lollipop) 이상

  • Firebase 클라우드 메시징 또는 Google Cloud 푸시 알림용 메시지입니다.

  • 앱이 AndroidX로 이전되었습니다.

Twilio SDK 업그레이드 요구사항

Android SDK가 패키지를 사용하여 직접 통합된 경우 Twilio SDK가 특정 버전을 따라야 합니다. 그렇지 않으면 무시해도 됩니다.

// Twilio VoIP SDK
api 'com.twilio:voice-android:6.1.1'
// Twilio Conversations SDK
api 'com.twilio:conversations-android:3.1.0'

또한 ProGuard가 Twilio Programmable Voice 라이브러리를 삭제하지 않도록 Android SDK에 ProGuard 규칙이 이미 포함되어 있으며, ProGuard가 실수로 라이브러리를 삭제하는 경우 문제 해결에 사용할 수 있습니다.

-keep class com.twilio.** { *; }
-keep class tvo.webrtc.** { *; }
-dontwarn tvo.webrtc.**
-keep class com.twilio.voice.** { *; }
-keepattributes InnerClasses

최신 Twilio 버전을 지원하기 위해 Android SDK 버전 0.34.0부터 SDK가 Java 7을 타겟팅하는 애플리케이션과 더 이상 바이너리 호환되지 않습니다. 이 버전과 향후 버전을 사용하려면 개발자가 Java 8을 타겟팅하도록 애플리케이션을 업그레이드해야 합니다. 다음 코드 예시를 참고하세요.

android {
    compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }
}

회사 키와 회사 보안 비밀 가져오기

  1. 관리자 사용자 인증 정보를 사용하여 관리 포털에 로그인합니다.

  2. 설정 > 개발자 설정 > 회사 키 및 비밀 코드로 이동합니다.

  3. 회사 키회사 보안 코드를 가져옵니다.

설치

루트 프로젝트의 Gradle 설정에 Android SDK 저장소를 추가합니다.

build.gradle (프로젝트)

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url "https://sdk.ujet.co/android/"
        }
    }
}

build.gradle (모듈: 앱)

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"
}

회사 설정

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>

JWT 서명

보안을 위해 최종 사용자 정보는 서버에서 JWT로 서명해야 합니다.

예시 앱에는 테스트용 APIManager가 포함되어 있으며 mock/APIManager.java에 UJET_COMPANY_SECRET을 넣어야 합니다. APIManager는 토큰을 반환하는 JWT 인증 토큰에 서명하는 비동기 호출을 시작하는 메서드를 구현해야 합니다.

프로덕션에서는 서버에서 서명 프로세스를 구현해야 합니다.

public class APIManager {
    public static final String UJET_COMPANY_SECRET = "Please input your UJET_COMPANY_SECRET from Ujet developer admin page";
    // ...
}

SDK 초기화

Android 애플리케이션 클래스 onCreate 메서드에서 SDK를 초기화합니다.

public class ExampleApplication extends Application implements UjetRequestListener {
    @Override
    public void onCreate() {
        super.onCreate();

        Ujet.init(this);
    }
    // ...
}

최종 사용자 인증

최종 사용자는 애플리케이션을 통해 고객 지원팀에 문의하는 소비자입니다.

애플리케이션에서 최종 사용자를 인증하기 위해 JWT 서명 메커니즘이 도입됩니다.

Android SDK는 인증이 필요한 경우 페이로드에 서명하도록 요청합니다. 서명이 성공하면 애플리케이션이 서명된 JWT를 최종 사용자의 인증 토큰으로 교환합니다.

ExampleApplication에서는 인증 토큰과 맞춤 데이터에 서명하기 위해 UjetRequestListener 인터페이스를 구현해야 합니다.

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();
                    }
                });
        }
    }
}

자세한 내용은 최종 사용자 인증을 참고하세요.

푸시 알림 설정

이 섹션에서는 모바일 푸시 알림을 사용 설정하는 방법을 설명합니다.

Firebase 준비

Firebase 프로젝트를 준비해야 합니다.

프로젝트가 이미 있는 경우 자체 프로젝트를 사용하고 이 프로세스를 건너뛸 수 있습니다.

  1. Firebase 콘솔에서 Firebase 프로젝트를 만듭니다.

  2. Firebase Console의 설정 > 일반에서 google-services.json을 다운로드합니다.

  1. Firebase Console의 설정 > 클라우드 메시징에서 서버 키를 가져옵니다.

서비스 계정 키 추가

푸시 알림을 수신하려면 모바일 앱에 서비스 계정 키를 추가해야 합니다. 서비스 계정 키를 가져오려면 서비스 계정으로 인증을 참고하세요.

서비스 계정 키를 모바일 앱에 추가하려면 다음 단계를 따르세요.

  1. CCAI Platform 포털에서 설정 > 개발자 설정을 클릭합니다. 설정 메뉴가 표시되지 않으면 메뉴를 클릭합니다.

  2. 모바일 앱 창으로 이동합니다.

  3. 앱 옆에 있는 수정을 클릭합니다. 모바일 앱 수정 대화상자가 표시됩니다.

  4. 서비스 계정 필드에 서비스 계정 키를 입력한 다음 저장을 클릭합니다.

Android 클라이언트 설정

  1. google-services.json를 앱 디렉터리(예: PROJECT_ROOT/app/google-services.json)에 복사합니다.

  2. 다음 코드를 사용하여 FCM 토큰을 가져옵니다.

    FirebaseMessaging.getInstance().getToken()
        .addOnCompleteListener(task -> {
            if (!task.isSuccessful() || task.getResult() == null) {
                Log.w("FCM", "Couldn't get FCM token");
                return;
            }
    
            String token = task.getResult();
            Log.i("FCM", "FCM token: " + token);
        });
    

    토큰이 새로고침되면 매니페스트에 등록된 FirebaseMessagingService가 호출됩니다. 자세한 내용은 Android에서 Firebase 클라우드 메시징 클라이언트 앱 설정을 참고하세요.

    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);
       }
    }
    
  3. Application 클래스에서 UjetRequestListener.onRequestPushToken을 구현합니다. UjetRequestListener.onRequestPushTokenFCM/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 -> { })
        }
    }
    
  4. 푸시 알림을 처리합니다. Contact Center AI Platform(CCAI Platform)에서 자체 푸시 메시지 처리를 처리하도록 하려면 데이터를 UjetPushHandler.handle()에 직접 전달하면 됩니다.

    • 애플리케이션은 ujet_noti_type (또는 하위 호환성을 위해 noti_type) 필드가 설정된 메시지만 처리합니다.

    • 그렇지 않으면 처리를 위해 ujet_noti_type가 포함된 메시지만 UjetPushHandler.handle()로 전송하도록 선택할 수 있습니다.

    다음은 푸시 알림 메시지의 예시입니다.

    {
        "call_id"           : 12345,
        "ujet_noti_type"    : "connect_call",
        "noti_type"         : "connect_call",
        "call_type"         : "ScheduledCall",
        "fail_reason"       : "none",
        "fail_details"      : "none"
    }
    

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
        }
    }
}

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
        }
    }
}

GcmReceiver에서 GCM 메시지 처리 (이전 방식)

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
        }
    }
}

신청 시작

애플리케이션을 시작할 위치에 다음 줄을 추가합니다 (매개변수 없음).

Ujet.start(new UjetStartOptions.Builder().build());

스플래시 화면 없이 Android SDK를 시작할 수도 있습니다.

UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
        .setSkipSplashEnabled(true)
        .build();

Ujet.start(ujetStartOptions);

직접 액세스 포인트를 사용하여 이 키로 메뉴의 특정 지점에서 Android SDK를 시작할 수도 있습니다.

String menuKey = "MENU_KEY";
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
        .setMenuKey(menuKey)
        .build();

Ujet.start(ujetStartOptions);

menuKey는 CCAI Platform 포털(관리자 역할)에서 직접 액세스 포인트로 만들 수 있습니다.

  1. 설정 > 대기열로 이동합니다.

  2. 메뉴 구조에서 대기열을 선택합니다.

  3. 직접 액세스 포인트 만들기를 선택합니다.

  4. 텍스트 형식으로 키를 입력합니다.

  5. 저장을 클릭합니다.

특정 티켓 ID로 Android SDK를 시작하여 CRM에 전달할 수도 있습니다. 채팅 또는 통화가 연결되면 이 티켓 ID가 열립니다.

String ticketId = "TICKET_ID";
UjetStartOptions ujetStartOptions = new UjetStartOptions.Builder()
        .setTicketId(ticketId)
        .build();

Ujet.start(ujetStartOptions);

CRM에 맞춤 데이터 전송

맞춤 데이터를 지원 상담사에게 전송할 수 있으며, 수신 전화/채팅의 지원 티켓에 표시됩니다.

맞춤 데이터를 전송하는 방법에는 두 가지가 있습니다.

  • 서명된 메서드: JWT를 사용한 사전 정의된 데이터 서명

  • 서명되지 않은 메서드: 일반 JSON이 포함된 사전 정의된 데이터 (권장되지 않음)

서명된 메서드를 사용하여 맞춤 데이터 전송

서명된 메서드를 사용하여 맞춤 데이터를 보내려면 서명 메서드를 구현하세요.

먼저 맞춤 데이터를 호스트 앱으로 가져온 다음 서명을 위해 서버로 전송합니다. 서버에서 정의된 양식을 사용하여 추가 데이터를 추가할 수 있습니다. 회사 보안 비밀로 서명한 다음 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));
        }
        // ...
    }
}

서명되지 않은 메서드를 사용하여 맞춤 데이터 전송

서명된 방법을 사용하여 애플리케이션에서 맞춤 데이터를 전송하는 것이 좋습니다. 자세한 내용은 서명된 메서드를 사용하여 맞춤 데이터 전송을 참고하세요.

시작 옵션으로 Android SDK를 시작하여 서명되지 않은 데이터를 전송할 수 있습니다. UjetStartOptions.Builder#setUnsignedCustomData를 사용하여 맞춤 데이터를 설정하고 UjetTokenCallbackonToken(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);

서명되지 않은 맞춤 데이터를 사용하여 외부 채팅 스크립트 전송

채팅이 시작되면 서명되지 않은 맞춤 데이터를 사용하여 외부 채팅 스크립트를 CCAI Platform으로 보낼 수 있습니다. UjetCustomData.putObject("external_chat_transfer", hashMapObject)를 사용하여 다음과 같이 JSON 형식으로 스크립트 데이터를 설정합니다.

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 형식:

  • greeting_override: 문자열

  • agent: 사전

    • name: 문자열

    • avatar: 문자열 [상담사 아바타 URL, 선택사항]

  • transcript: 배열

    • sender: 문자열 ['end_user' 또는 'agent']

    • timestamp: 문자열(예: '2021-03-15 12:00:00Z')

    • content: 배열

      • type: 문자열 [text, media 중 하나]

      • text: 문자열[텍스트 유형에 필요]

      • media: 사전 [미디어 유형에 필요]

        • type: 문자열[이미지, 동영상 중 하나]

        • url: 문자열 [미디어 파일을 가리키는 공개 URL]

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"
            }
        ]
        }
    ]
}

텍스트 유형에 마크다운을 사용할 수 있습니다. 지원되는 형식은 다음과 같습니다.

  • 굵게

  • 기울임꼴

  • 밑줄

  • 줄바꿈

  • 글머리기호 넣기

  • 번호 매기기 목록

  • 링크

맞춤 데이터 형식

이 섹션에서는 JWT에서 전달할 수 있는 맞춤 데이터의 형식을 보여줍니다.

JWT로 인코딩된 JSON

JSON에는 JWT를 검증하기 위한 iat 및 exp가 포함되어야 합니다. 맞춤 데이터의 객체는 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"
        }
    }
}

키는 데이터의 고유 식별자입니다. 유형은 값의 유형입니다.

  • string

    • JSON 문자열
  • number

    • 정수, 부동 소수점
  • date

    • 13자리 UTC Unix 타임스탬프 형식입니다. (밀리초 포함)
  • url

    • HTTP URL 형식

라벨은 CRM 페이지의 표시 이름입니다.

맞춤 데이터 표시 방지

맞춤 데이터 객체와 함께 invisible_to_agent 속성을 사용하여 서명된 또는 서명되지 않은 맞춤 데이터가 에이전트 어댑터에 표시되지 않도록 할 수 있습니다. 이전 예시에서는 "invisible_to_agent" : truessn 객체에 포함되어 있으므로 최종 사용자의 주민등록번호가 상담사 어댑터에 표시되지 않습니다.

맞춤 데이터 객체와 함께 "invisible_to_agent" : true 속성을 포함하면 다음과 같은 동작이 예상됩니다.

자세한 내용은 에이전트 어댑터에서 세션 데이터 보기를 참고하세요.

예약된 데이터 속성

세션이 시작될 때 예약된 데이터 속성을 서명된 맞춤 데이터로 Contact Center AI Platform (CCAI Platform)에 전송할 수 있습니다. 자세한 내용은 예약된 데이터 속성 전송을 참고하세요.

다음은 맞춤 데이터의 예약된 데이터 속성의 예입니다.

  {
    "custom_data": {
      "reserved_verified_customer": {
        "label": "Verified Customer",
        "value": "VERIFIED_CUSTOMER_BOOLEAN": ,
        "type": "boolean"
      },
      "reserved_bad_actor": {
        "label": "Bad Actor",
        "value": "VERIFIED_BAD_ACTOR_BOOLEAN": ,
        "type": "boolean"
      },
      "reserved_repeat_customer": {
        "label": "Repeat Customer",
        "value": "REPEAT_CUSTOMER_BOOLEAN": ,
        "type": "boolean"
      }
    }
  }
  

다음을 바꿉니다.

  • VERIFIED_CUSTOMER_BOOLEAN: 이 최종 사용자를 적법한 고객으로 간주하는 경우 True입니다.
  • VERIFIED_BAD_ACTOR_BOOLEAN: 이 최종 사용자가 악성 행위자일 수 있다고 생각하는 경우 true입니다.
  • REPEAT_CUSTOMER_BOOLEAN: 이 최종 사용자가 이전에 고객센터에 문의한 적이 있다고 판단한 경우 true입니다.

SDK 구성

Android SDK를 시작하기 전에 여러 옵션을 구성할 수 있습니다. UjetOption 클래스를 참고하세요. 다음 표에 설명된 대체 전화번호 및 네트워크 민감도 옵션은 CCAI 플랫폼 포털의 설정 > 개발자 설정 > MMA > 수정에서 PSTN 대체 사용 설정 전환 버튼이 사용 설정된 경우에만 작동합니다. PSTN 대체 사용 설정 전환 버튼이 꺼져 있으면 PSTN으로 대체되지 않습니다. CCAI Platform은 네트워크 연결을 확인하기 위해 기본 네트워크 감도 (0.85)를 사용합니다.

옵션 설명 기본값
로그 수준 Logcat에 출력할 로그 수준입니다. 정수. Android 로그의 로그 수준도 마찬가지입니다. (최소: 2, 최대: 7) 5 (Log.Warn)
기본 언어 기본 언어 코드입니다. 문자열. ISO 639 언어 코드입니다. (예: 영어의 경우 en) null
대체 전화번호 이 전화번호는 인터넷을 사용할 수 없거나 관리 포털에 회사의 대표 전화번호가 없는 경우 대체 번호로 사용됩니다. 문자열. 전화번호입니다. null
포착되지 않은 예외 핸들러 사용 설정됨 포착되지 않은 예외 핸들러를 사용 설정합니다. true인 경우 앱은 Thread.setDefaultUncaughtExceptionHandler을 사용하여 런타임에 포착되지 않은 모든 SDK 예외를 처리합니다. 하지만 동일한 예외가 두 번 발생하면 앱이 비정상 종료됩니다. 부울. true
네트워크 민감도 네트워크 상태를 확인하는 감도입니다. 01 사이에서 두 배가 됩니다. 여기서 0는 가장 덜 민감하고 1는 가장 민감합니다. 1 값은 항상 PSTN 통화로 대체됩니다. 사용하는 경우 .97 값으로 시작하는 것이 좋습니다. 설정 > 개발자 설정 > 모바일 앱 > 대체 전화번호 임계값의 포털 값이 이 값을 재정의합니다. 0.85
어두운 모드 사용 설정됨 어두운 모드 테마를 사용 설정합니다. true인 경우 사용자가 어두운 모드를 사용 설정하면 SDK가 어두운 모드 테마를 적용하고 그렇지 않으면 작업을 무시합니다. 부울. false
단일 채널 사용 설정됨 단일 채널의 채널 선택 화면을 표시하거나 우회하는 구성 옵션 true인 경우 메뉴 대기열에 채널이 하나만 사용 설정되어 있어도 SDK에서 채널을 자동으로 선택하지 않고 단일 채널 선택 화면을 표시합니다. 부울. false
통화 뷰 자동 최소화 기본적으로 초기 통화 화면 UI를 자동으로 최소화하거나 사용자가 최소화할 때까지 기다리는 구성 옵션 부울. false
상담사 아이콘 테두리 사용 설정됨 에이전트 아이콘 주위에 원형 테두리를 표시하거나 삭제하는 구성 옵션 부울. false
선택기 뷰의 정적 글꼴 크기 선택기 항목 텍스트 크기를 자동으로 조정하거나 사용 중지하는 구성 옵션 부울. false
채팅에서 미디어 첨부파일 숨기기 채팅 UI에서 미디어 첨부파일 아이콘을 표시하거나 숨기는 구성 옵션 부울. false
READ_PHONE_STATE 권한 무시 true로 설정하면 SDK가 READ_PHONE_STATE 권한을 요청하지 않습니다. 인앱 IVR 통화를 사용하지 않으려면 이 플래그를 true로 설정하여 이 권한을 요청하지 않도록 하고 애플리케이션에서 CCAI Platform SDK의 android.permission.READ_PHONE_STATE 권한을 명시적으로 삭제해야 합니다. 이 권한은 인앱 IVR 통화가 작동하는 데 필요하므로 true로 설정하지 않는 것이 좋습니다. 불리언 false
Cobrowse.io 라이선스 키 (해당하는 경우) Cobrowse.io 라이브러리를 설정하는 구성 옵션 https://cobrowse.io/dashboard/settings에 로그인하고 라이선스 키 섹션으로 이동하면 공동 탐색 라이선스 키를 확인할 수 있습니다. 문자열 null
맞춤 채팅 헤더 제목 채팅 UI에서 채팅 헤더 제목 텍스트를 맞춤설정하는 구성 옵션 문자열 null
채팅 UI 빠른 답장 맞춤설정 채팅 UI에서 가상 에이전트 빠른 답장을 맞춤설정하는 구성 옵션 가상 에이전트 빠른 답장은 기본적으로 그룹화되어 있지만 개별적으로 표시하려면 이 구성 옵션을 사용하여 QuickReplyButtonsStyle.INDIVIDUAL을 설정하면 됩니다. UjetStylesOptions QuickReplyButtonsStyle.GROUPED
다양한 채팅 UI 속성 맞춤설정 글꼴, 배경색, 아이콘 등 다양한 속성을 맞춤설정하는 구성 옵션 UjetStylesOptions null
상태 표시줄 숨기기 상태 표시줄을 표시하거나 숨기는 구성 옵션 값이 true이면 SDK가 상태 표시줄을 숨깁니다. 불리언 false
로딩 스피너 드로어블 리소스 설정 앱 전체에서 로딩 스피너 뷰를 맞춤설정하는 구성 옵션입니다. 사용할 수 없거나 null인 경우 기본 로딩 뷰를 사용합니다. 정수 null
가로 방향 사용 중지됨 가로 방향을 사용 중지합니다. 값이 true이면 가로 방향이 적용되지 않습니다. 불리언 false
채팅에서 새 대화 시작 인라인 버튼 숨기기 채팅 UI에서 새 대화 시작 인라인 버튼을 표시하거나 숨기는 구성 옵션 불리언 false
CSAT 건너뛰기 버튼 표시 CSAT 대화상자에서 건너뛰기 버튼을 표시하거나 숨기는 구성 옵션 불리언 false
최종 사용자의 채팅 종료 차단 채팅 UI에서 채팅 종료 버튼을 표시하거나 숨기는 구성 옵션 불리언 false
채팅 스크립트 다운로드 숨기기 채팅 작업 메뉴와 채팅 사용자 인터페이스에서 채팅 스크립트 다운로드 버튼을 표시하거나 숨깁니다. ujet_common_hide 문자열에 공백을 추가하면 Hide 텍스트가 사라지고 뒤로 화살표만 표시됩니다. 정수. 값:

0 = 모든 위치에 표시

1 = 옵션 메뉴에서 숨기기

2 = 게시 후 채팅 화면에서 숨기기

3 = 옵션 메뉴와 채팅 후 화면 모두에서 숨깁니다.

0

UjetOption.setBlockChatTerminationByEndUser

전역 수준에서 푸시 알림 사용 중지 UjetOption.setPushNotificationsAllowedfalse로 설정하면 모든 푸시 알림 종속 항목이 우회되고 푸시 알림이 최종 사용자에게 도달하지 않습니다. 불리언 true
UjetOption ujetOption = new UjetOption.Builder()
        .setLogLevel(Log.INFO)
        .setDefaultLanguage("en")
        .setFallbackPhoneNumber("+18001112222")
        .setUncaughtExceptionHandlerEnabled(false)
        .setNetworkSensitivity(0)
        .setDarkModeEnabled(true)
        .setShowSingleChannelEnabled(true)
        .setAutoMinimizeCallView(true)
        .setShowAgentIconBorderEnabled(true)
        .setStaticFontSizeInPickerView(true)
        .setHideMediaAttachmentInChat(true)
        .setIgnoreReadPhoneStatePermission(true)
        .setCobrowseLicenseKey("COBROWSE_IO_LICENSE_KEY_HERE")
        .setCobrowseURL("COBROWSE_IO_API_URL_HERE")
        .setCustomChatHeaderTitle("CHAT_HEADER_TITLE_TEXT")
        .setUjetStylesOptions(
             new UjetStylesOptions.Builder()
            .setChatQuickReplyButtonsStyle(QuickReplyButtonsStyle.INDIVIDUAL)
            .setChatStyles(new ChatStyles(...)) // See `Content Cards Theme` item
            .build()            )
        .setBlockChatTerminationByEndUser(true)
        .setHideStatusBar(true)
        .setLoadingSpinnerDrawableRes(R.drawable.RESOURCE_NAME)
        .setLandscapeOrientationDisabled(true)
        .setShowCsatSkipButton(false)
        .setHideDownloadChatTranscript(0) // 0 to 3. 0 = Show everywhere, 1 = Hide from the options menu, 2 = Hide from the post chat screen, 3 = Hide from both the options menu and the post chat screen.
        .setPushNotificationsAllowed(true)
        .build();

//The following customizes various attributes in chat UI
ChatStyles chatStyles = new ChatStyles();
chatStyles.setBackButton(new BackButtonStyle(false, "ujet_agent_sample")); //customizes back button styles
chatStyles.setHeader(...); //customizes chat header styles
chatStyles.setAgentMessageBubbles(...); //customizes agent messages styles
chatStyles.setConsumerMessageBubbles(...); //customizes consumer messages styles
chatStyles.setSystemMessages(...); //customizes system messages styles
chatStyles.setEndChatButton(...); //customizes end chat button styles
chatStyles.setTimeStamps(...); //customizes timestamp styles
chatStyles.setUserInputBar(...); //customizes user input bar styles

UjetOption ujetOption = new UjetOption.Builder()
        .setUjetStylesOptions(
            new UjetStylesOptions.Builder()
            .setChatStyles(chatStyles)
            .build()
        )

//The following customizes various attributes in chat UI using json file. Store json file in assets folder
//and create a method to read json file contents and convert it into json string.
String chatStylesFromJson = parseJsonContentsFromAssetsFolder();

UjetOption ujetOption = new UjetOption.Builder()
        .setUjetStylesOptions(
            new UjetStylesOptions.Builder()
            .setChatStyles(chatStylesFromJson)
            .build()
        )

대체

예기치 않은 오류의 대체로 UjetErrorListener를 사용할 수 있습니다. 이 리스너를 설정하지 않거나 false를 반환하면 Android SDK에서 오류를 처리합니다.

Android SDK는 설정 > 개발자 설정 > MMA > 팝업 수정에서 PSTN 대체 사용 전환 버튼이 사용으로 설정된 경우에만 대체 번호로 사용자를 다이얼러로 리디렉션하고, 그렇지 않으면 SDK를 종료합니다.

오류 유형 오류 코드 트리거
NETWORK_ERROR 1 네트워크를 사용할 수 없습니다. 채팅, 통화 또는 평가 화면 중에 네트워크를 사용할 수 없는 경우에는 이 오류가 트리거되지 않습니다.
AUTHENTICATION_ERROR 100 인증 중에 예기치 않은 오류가 발생했습니다.
AUTHENTICATION_JWT_ERROR 101 JWT 유효성 검사 중에 예기치 않은 오류가 발생했습니다 (예: 파싱 오류).
VOIP_CONNECTION_ERROR 1000 VoIP 제공업체에 연결할 수 없습니다. VoIP SDK의 콜백을 통해 처리됩니다.
VOIP_LIBRARY_NOT_FOUND 1001 VoIP 제공업체를 사용하여 통화가 연결될 것으로 예상되지만 제공업체를 찾을 수 없습니다. 개발자가 잘못된 SDK를 통합했거나 종속 항목에 VoIP 제공업체 라이브러리를 추가하지 않은 경우 이 문제가 발생할 수 있습니다.
CHAT_LIBRARY_NOT_FOUND 1100 채팅 라이브러리를 찾을 수 없는 경우 발생합니다. 개발자가 잘못된 SDK를 통합했거나 종속 항목에 Twilio Chat 라이브러리를 추가하지 않은 경우에 발생할 수 있습니다.
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());
    }
});

앱 권한

앱에 다음 권한이 필요하며 필요한 경우 사용자에게 이러한 권한을 요청합니다.

권한 설명
카메라 사진을 찍고 동영상을 녹화하는 스마트 작업에 사용됩니다.
마이크 앱이 Twilio를 통해 VoIP 통화를 사용하도록 허용
스토리지 앱이 사진과 동영상을 저장하도록 허용

딥 링크 설정 (선택사항)

IVR (PSTN) 통화에 스마트 작업을 사용하려면 프로젝트에서 딥 링크를 설정해야 합니다.

딥 링크 형식은 다음과 같은 고유한 URI입니다.

ujet:// <package_name>/smartchannel.

또한 관리 포털 (설정 > 운영 관리 > 앱 다운로드 SMS 전송 사용 설정)에서 이 링크 또는 이 링크로 리디렉션되는 URL을 설정해야 합니다.

매니페스트에 딥 링크가 포함된 인텐트 필터를 추가해야 합니다.

<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>

선호 채널

Preferred Channel(선호 채널) 매개변수를 사용하면 소비자를 특정 채널로 직접 라우팅할 수 있습니다. 그러면 최종 사용자는 채널 선택 단계를 건너뛰고 기본 채널 매개변수에 지정된 채널을 통해 직접 문의를 시작합니다.

UjetStartOptions.preferredChannel

Ujet.start(new)
UjetStartOptions.Builder().setPreferredChannel
(UjetPreferredChannel.UjetPreferredChannelChat).build());

이벤트 알림

선택적으로 UjetEventListener을 설정하여 애플리케이션 이벤트 알림을 받을 수 있습니다.

사용 가능한 이벤트 유형과 설명은 여기에 나열되어 있습니다.

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());
    }
});
이벤트 유형 설명 이벤트에 포함된 데이터
EmailClicked 최종 사용자가 이메일 채널을 클릭할 때 트리거됩니다. 대기열 메뉴 데이터
EmailSubmitted 최종 사용자가 이메일을 보낼 때 트리거됩니다. 대기열 메뉴 데이터, 이메일 제출 데이터
SessionPaused 최종 사용자가 채팅 또는 통화 세션을 최소화하면 트리거됩니다. 세션 데이터
SessionResumed 최종 사용자가 백그라운드에서 채팅 또는 통화 세션으로 다시 전환할 때 트리거됩니다. 세션 데이터
SessionCreated 채팅 또는 통화 세션이 생성될 때 트리거됩니다. 대기열 메뉴 데이터, 세션 생성 데이터
SessionEnded 채팅 또는 통화 세션이 종료되면 트리거됩니다. 대기열 메뉴 데이터, 세션 생성 데이터, 세션 종료 데이터
SdkTerminated 예기치 않게 닫히는 경우를 포함하여 SDK가 닫힐 때 트리거됩니다. SDK 종료 데이터
ContentCardClicked 콘텐츠 카드를 클릭하면 트리거됩니다. 콘텐츠 카드 클릭 데이터
ContentCardButtonClicked 콘텐츠 카드 버튼을 클릭할 때 트리거됩니다. 콘텐츠 카드 버튼 클릭 데이터
QuickReplyClicked 빠른 답장을 클릭하면 트리거됩니다. 빠른 답장 클릭 데이터
MessageLinkClicked 링크를 클릭하면 트리거됩니다. 메일 링크 클릭 데이터

대기열 메뉴 데이터

유형 설명
event_name 문자열 이벤트 이름을 포함합니다. 예: '이메일 클릭됨'
application 문자열 애플리케이션 이름을 포함합니다. 예: 'Android'
app_id 문자열 Context.getPackageName()과 동일한 앱 식별자를 포함합니다.
app_version 문자열 앱 버전 이름과 버전 코드를 포함합니다. 예: '0.32.0 (123)'
sdk_version 문자열 SDK 버전을 포함합니다. 예: '0.32.0'
timestamp 문자열 UTC의 타임스탬프를 포함합니다 (yyyy-MM-dd'T'HH:mm:ss'Z' 형식).
device_model 문자열 사용자 기기 모델을 포함합니다. 예: 'Google Pixel'
device_version 문자열 사용자 기기 버전을 포함합니다. 예: '10, Q, SDK 29'
company 문자열 회사 이름을 포함합니다. 예: '회사'
menu_name 문자열 리프 노드 (사용자의 마지막 메뉴 선택)의 이름을 포함합니다. 예: '하위 메뉴'
menu_id 문자열 리프 노드 (사용자의 마지막 메뉴 선택)의 ID를 포함합니다. 예: '123'
menu_path 문자열 사용자가 선택한 메뉴의 전체 시퀀스를 포함합니다. 예: '상위 / 하위 / 하위 메뉴'
menu_key 문자열 DAP 키를 포함하며 선택사항입니다. 예: 'special_user_menu'

이메일 제출 데이터

유형 설명
has_attachments 불리언 이메일에 첨부파일이 있으면 True를 반환하고, 그렇지 않으면 False를 반환합니다.

세션 데이터

유형 설명
event_name 문자열 이벤트 이름을 포함합니다. 예: '이메일 클릭됨'
type 문자열 세션 유형을 포함합니다. 예: 'chat' 또는 'call'
timestamp 문자열 UTC의 타임스탬프를 포함합니다 (yyyy-MM-dd'T'HH:mm:ss'Z' 형식).

세션 생성 데이터

유형 설명
session_id 문자열 세션 ID를 포함합니다. 예: '100'
type 문자열 세션 유형을 포함합니다. 예: 'chat' 또는 'call'
end_user_identifier 문자열 최종 사용자 식별자를 포함합니다. 예: '길동'
messages_end_user 문자열 최종 사용자 메시지 수를 포함하며 채팅 세션에만 포함됩니다. 예: '3'
messages_agent 문자열 상담사 메시지 수를 포함하며 채팅 세션에만 포함됩니다. 예: '3'

세션 종료 데이터

유형 설명
agent_name 문자열 상담사 이름을 포함합니다. 예: '길동'
ended_by 문자열 세션을 종료한 사용자의 세부정보를 포함합니다. 가능한 값은 'agent' (상담사가 세션을 종료한 경우) 또는 'end_user' (최종 사용자가 세션을 종료한 경우) 또는 'timeout' (채팅이 시간 초과된 경우) 또는 'dismissed' (채팅이 닫힌 경우)입니다.
duration 문자열 세션 기간(초)을 포함하며 통화 세션에만 포함됩니다. 예: '30초'

SDK 종료 데이터

유형 설명
event_name 문자열 이벤트 이름을 포함합니다. 예: '이메일 클릭됨'

콘텐츠 카드 클릭 데이터

유형 설명
title 문자열 카드 제목입니다.
title 문자열 카드 제목입니다.
subtitle 문자열 카드 부제목입니다.
body 문자열 콘텐츠 카드의 설명입니다.
link 문자열 웹페이지 링크 또는 딥 링크입니다. SDK는 OS 기능을 사용하여 이를 엽니다.
event_params 딕셔너리 클릭 이벤트에 관한 추가 정보가 포함된 사전입니다. SDK에서 이를 사용합니다.

콘텐츠 카드 버튼 클릭 데이터

유형 설명
title 문자열 카드 제목입니다.
title 문자열 카드 제목입니다.
link 문자열 웹페이지 링크 또는 딥 링크입니다. SDK는 OS 기능을 사용하여 이를 엽니다.
event_params 딕셔너리 클릭 이벤트에 관한 추가 정보가 포함된 사전입니다. SDK에서 이를 사용합니다.

빠른 답장 클릭 데이터

유형 설명
title 문자열 카드 제목입니다.
title 문자열 카드 제목입니다.
link 문자열 웹페이지 링크 또는 딥 링크입니다. SDK는 OS 기능을 사용하여 이를 엽니다.
event_params 딕셔너리 클릭 이벤트에 관한 추가 정보가 포함된 사전입니다. SDK에서 이를 사용합니다.

메일 링크 클릭 데이터

유형 설명
event_name 문자열 이벤트 이름(예: '메시지 링크 클릭됨')을 포함합니다.
link 문자열 웹페이지 링크 또는 딥 링크입니다. SDK는 OS 기능을 사용하여 엽니다.

수신 전화 동작 변경

Android 10 버전 기기부터 호스트 앱이 백그라운드에 있을 때 수신 전화가 최종 사용자에게 직접 수신되지 않습니다. 대신 전화가 잠겨 있을 때도 사용자에게 수신 전화를 알리는 알림을 사용하여 전화를 수락하거나 거부할 수 있는 옵션을 제공합니다.

수신 전화가 도착하기 전에 호스트 앱이 백그라운드에 있고 화면이 잠겨 있으면 동일한 알림이 표시됩니다. 이 동작 변경은 앱이 백그라운드에 있을 때 활동을 시작하는 Google의 최근 제한사항을 준수하기 위한 것입니다. 호스트 앱이 포그라운드에 있거나 Android 10 미만 버전 기기에서 실행되는 경우에는 동작이 영향을 받지 않습니다.

SDK 세션 맞춤설정

이 섹션에서는 SDK를 추가로 맞춤설정하는 방법을 설명합니다.

기존 세션 확인

세션을 시작하기 전에 설명된 메서드를 사용하여 기존 세션이나 진행 중인 세션이 있는지 확인합니다. 이 값이 있으면 최종 사용자에게 일시중지된 작업을 재개하거나 취소하라는 메시지를 표시할 수 있습니다.

이는 특히 사용자가 변경된 경우에 중요합니다.

if (Ujet.getStatus() != UjetStatus.None) {
    // Display alert to cancel login or resume existing session
}

세션 연결 해제

진행 중인 세션을 연결 해제하려면 이 메서드를 참고하세요.

이 메서드를 사용하기 전에 Ujet.getStatus()를 사용하여 이러한 세션이 있는지 확인하세요. SDK에서 세션을 연결 해제한 후 메시지를 표시하거나 앱을 닫는 등 작업을 실행하려면 다음 섹션에 설명된 대로 응답 콜백 onFinished()를 사용하고, 그렇지 않으면 콜백을 null로 설정하세요.

Ujet.disconnect(new UjetResponseCallback() {
    @Override
    public void onFinished() {
        // `onFinished()` is triggered after CCAI Platform disconnects the session.
        finish(); // Finishes the activity.
    }
});

캐시에서 최종 사용자 데이터 삭제

앱에서 최종 사용자 관련 데이터가 업데이트되거나 변경된 경우 캐시를 지우는 것은 개발자의 책임입니다. 예를 들어 최종 사용자가 로그아웃한 경우 다음 SDK 시작 시 새 최종 사용자에 대해 새 세션이 시작되도록 해당 사용자의 캐시를 삭제하는 메서드를 호출합니다.

Ujet.clearUserData();

SDK 숨기기

Ujet.hideSDK() 메서드를 사용하여 SDK를 숨길 수 있습니다. 이는 SDK가 앱 사용자 인터페이스를 방해하는 경우에 유용합니다. 이 메서드를 호출하기 전에 Ujet.init()를 사용하여 SDK를 초기화하세요. SDK가 성공적으로 숨겨지면 Ujet.init()true를 반환하고, 그렇지 않으면 false를 반환합니다. SDK를 숨긴 후 Ujet.start() 메서드를 사용하여 다시 시작할 수 있습니다.

다음 예시에서는 SDK를 숨깁니다.

Ujet.hideSDK();

언어 환경설정

Android SDK는 다음 우선순위 순서를 사용하여 언어를 결정합니다.

  1. 앱 내 스플래시 화면에서 선택한 언어입니다.

  2. UjetOptions를 사용하여 선택한 기본 언어 UjetOptions에서 setDefaultLanguage("en")를 사용하여 기본 언어를 설정할 수 있습니다. 자세한 내용은 SDK 구성 섹션의 기본 언어를 참고하세요.

  3. 앱에서 지원하는 경우 기기에서 선택한 기기 언어 (설정 > 일반 > 언어 사용)가 사용됩니다.

  4. 앱이 기기 언어를 지원하지 않지만 가장 가까운 상위 언어를 지원하는 경우 기기 언어의 가장 가까운 방언이 사용됩니다. 예를 들어 사용자가 기기에서 스페인어(쿠바)를 언어로 선택했고 앱이 스페인어(쿠바)를 지원하지 않지만 상위 방언인 스페인어를 지원하는 경우 스페인어가 사용됩니다.

  5. 기기 언어가 앱에서 지원되지 않는 경우 영어가 기본 언어로 사용됩니다.

외부 전환 링크 아이콘 구성

앱의 드로어블 폴더에 아이콘을 업로드하여 외부 전환 링크 채널의 아이콘을 맞춤설정하고, CCAI 플랫폼 포털의 설정 > 채팅 > 외부 전환 링크 > 링크 보기 > 전환 링크 추가에서 외부 전환 링크를 만들 때 동일한 아이콘 이름을 사용해야 합니다.

CCAI 플랫폼 포털의 아이콘 이름이 앱에 업로드된 아이콘과 일치하지 않으면 Android SDK에서 기본 아이콘을 사용합니다.

설문조사 감사합니다 아이콘 구성

앱의 드로어블 폴더에 아이콘을 업로드하고 파일 이름 ujet_survey_thank_you_icon을 아이콘 이름으로 사용하여 설문조사 감사 페이지의 아이콘을 맞춤설정하거나 재정의할 수 있습니다.

맞춤설정 (선택사항)

이 섹션에서는 SDK 내에서 특정 값을 맞춤설정하는 방법을 설명합니다.

문자열

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>

설문조사 구성

텍스트 크기 맞춤설정

dimens.xml에서 다음 키를 재정의하여 애플리케이션에 사용되는 제목, 설명, 선택기 텍스트 크기를 맞춤설정합니다.

맞춤설정 가능한 텍스트 크기는 다음과 같습니다.

<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>

테마

다음 단계에 따라 테마와 배경을 맞춤설정합니다. 1단계는 테마용이고 2단계는 배경용입니다.

  1. style.xml에서 각 스타일 항목의 키를 재정의하여 테마를 맞춤설정합니다. 예를 들면 다음과 같습니다.

    <!--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>
    
  2. style.xml에서 각 스타일 항목의 키를 재정의하여 애플리케이션의 배경 색상을 맞춤설정할 수 있습니다. 맞춤설정 가능한 배경색이 스크린샷에 표시됩니다.

    <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>
    

채팅 헤더 제목 맞춤설정

UI의 채팅에서 채팅 헤더 제목 텍스트를 맞춤설정할 수 있는 옵션이 있습니다.

다음 옵션을 사용하여 채팅 헤더 제목 텍스트를 맞춤설정할 수 있습니다.

<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>

다음 옵션을 사용하여 채팅 UI에서 가상 에이전트 빠른 답장을 맞춤설정할 수 있습니다.

<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>

콘텐츠 카드

채팅 맞춤설정과 함께 콘텐츠 카드 맞춤설정을 추가할 수 있습니다. JSON 파일을 사용하거나 (app/src/main/assets/json/ujet_styles.json 파일의 content_card property 참고) 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",
            )
        )
    )
)

웹 양식 테마

채팅 맞춤설정과 함께 웹 양식 카드를 맞춤설정할 수 있습니다. JSON 파일을 사용하거나 (app/src/main/assets/json/ujet_styles.json 파일의 form_card 속성 참고) 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,
        ),
    )
)

설문조사

앱의 드로어블 폴더에 아이콘을 업로드하여 설문조사 감사 페이지의 아이콘을 변경할 수 있습니다.

ujet_survey_thank_you_icon을 아이콘 이름으로 사용해야 합니다.

문제 해결

새 채팅을 시작하는 데 30초 이상 걸림

커스텀 데이터의 위임 메서드에 응답하는지 확인합니다. 요청 시 유효한 맞춤 데이터를 반환하거나 콜백과 함께 null을 반환해야 합니다. 다음 코드를 참조하세요.

    @Override
    public void onSignPayloadRequest(Map<String, Object> payload, UjetPayloadType ujetPayloadType, UjetTokenCallback tokenCallback) {
        if (ujetPayloadType == UjetPayloadType.CustomData) {
            tokenCallback.onToken(null);
        }
    }

정책 선언 설명

Android SDK에서 사용하는 서비스 또는 권한의 정책을 선언하라는 알림이 Google Play Console에 표시되면 다음 설명 중 하나를 사용하세요.

Android SDK에서 사용하는 포그라운드 서비스 선언

Google은 Android 14에서 포그라운드 서비스 유형을 도입하고 https://developer.android.com/about/versions/14/changes/fgs-types-required#remote-messaging에 따라 포그라운드 서비스를 시작하는 동안 이를 지정하도록 요구했습니다. Contact Center AI Platform (CCAI Platform) Android SDK는 포그라운드 서비스를 사용하여 채팅과 통화를 시작하므로 텍스트 메시지를 처리하는 채팅에는 FOREGROUND_SERVICE_REMOTE_MESSAGING 서비스 유형을 사용하고 통화에는 FOREGROUND_SERVICE_MICROPHONE 서비스 유형을 사용했습니다. 이러한 서비스 유형이 없으면 Android 14 버전 기기에서 시작되는 채팅 또는 통화를 시작하는 동안 SDK가 비정상 종료됩니다.

Android SDK에서 사용하는 전체 화면 인텐트 권한 선언

기기가 잠겨 있을 때 수신 전화 푸시 알림을 표시하려면 USE_FULL_SCREEN_INTENT 권한이 필요합니다. 최종 사용자에게 알림을 보내고 수신 전화 알림을 전체 화면으로 표시합니다 (이는 내장 전화 앱이 최종 사용자에게 수신 전화를 알리는 방식임).

Android 15 지원

Android 15를 지원하려면 다음 단계를 따르세요.

  1. build.gradle(:app)에서 compileSdkVersion = 35targetSdkVersion = 35를 설정합니다.

  2. 프로젝트 Android Gradle 플러그인 (AGP) 버전이 8.5.1 이상인지 확인합니다. 자세한 내용은 공유 라이브러리의 패키징 업데이트를 참고하세요.

  3. AGP 8.0 이상을 사용하여 Android 프로젝트를 빌드하려면 JDK (Java Development Kit) 버전 17 이상을 설치하세요. 자세한 내용은 AGP 8.0을 실행하려면 JDK 17이 필요함을 참고하세요.