Настройка
Быстрый старт: от нуля до первого сообщения
Если вы только начинаете интеграцию SDK, начните с минимального рабочего примера. Ниже приведён сценарий «за 5 минут»: от инициализации до первого открытого чата.
Шаг 1. Инициализация в Application
Создайте собственный класс Application и инициализируйте SDK один раз при старте приложения:
class MyApp : Application() {
lateinit var chatCenterUI: ChatCenterUI
override fun onCreate() {
super.onCreate()
// 1. Конфигурация транспорта
val transportConfig = ChatTransportConfig(
"https://YOUR_REST_API_URL", // REST API base URL
"wss://YOUR_WEBSOCKET_URL", // WebSocket URL
"https://YOUR_DATASTORE_URL" // Datastore URL
)
// 2. Сетевые настройки (используем значения по умолчанию)
val networkConfig = ChatNetworkConfig()
// 3. Конфигурация SDK
val chatConfig = ChatConfig(
transportConfig,
networkConfig
// остальные параметры берут значения по умолчанию;
// включение поиска/превью/голосовых сообщений рекомендуется делать на стороне сервера
)
// 4. Создаём экземпляр SDK и вызываем init(...)
chatCenterUI = ChatCenterUI(applicationContext, loggerConfig).apply {
init(
providerUid = "YOUR_PROVIDER_UID",
config = chatConfig
)
}
}
}
Подробнее о параметрах ChatTransportConfig и ChatNetworkConfig см. раздел
«Advanced» → «Конфигурация транспорта» и «Конфигурация сети».
Шаг 2. Отображение чата
Добавьте Activity (или Fragment), в котором будет отображаться чат:
class ChatActivity : AppCompatActivity() {
private val chatCenterUI: ChatCenterUI
get() = (application as MyApp).chatCenterUI
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
val chatFragment = chatCenterUI.getChatFragment()
if (chatFragment != null) {
supportFragmentManager
.beginTransaction()
.replace(R.id.chat_container, chatFragment)
.commit()
}
}
override fun onBackPressed() {
val chatFragment = chatCenterUI.getChatFragment()
if (chatFragment != null) {
val shouldClose = chatFragment.onBackPressed()
if (shouldClose) {
finish() // или скрыть фрагмент
}
} else {
super.onBackPressed()
}
}
}
Где R.id.chat_container — это контейнер (например, FrameLayout) в разметке activity_chat.xml.
Шаг 3. Авторизация пользователя
После инициализации SDK для каждого авторизованного пользователя вызовите:
val user = ChatUser(
identifier = "USER_ID_123" // стабильный ID пользователя в вашей системе
)
val auth = ChatAuth(
token = accessTokenFromBackend, // токен, выдаваемый вашим backend
scheme = "retail",
signature = signatureFromBackend // если используется
)
chatCenterUI.authorize(user, auth)
Без вызова authorize(...) чат не сможет отправлять сообщения от имени пользователя.
Подробнее о полях ChatUser и ChatAuth см. раздел «Настройка» → «Авторизация пользователя».
Чеклист интеграции
- Подключили зависимости и настроили Gradle (см. раздел Установка).
- Создали свой
Applicationи один раз инициализировалиChatCenterUI.init(...). - Настроили экран с
ChatFragment(Activity или Fragment). - Реализовали авторизацию пользователя через
ChatUserиChatAuth. - Настроили обработку пуш-уведомлений (см. раздел «Уведомления»).
Инициализация
Конфигурация
В Application.onCreate(), или в другом удобном для вас месте необходимо инициализировать
библиотеку. Для этого создайте объект ChatCenterUI(applicationContext)
(можно также вторым параметром передать logger: ChatLoggerConfig, если вы хотите включить внутреннее логирования),
после чего вызовите через этот объект метод:
fun init(providerUid: String, appMarker: String, config: ChatConfig)
fun init(providerUid: String, config: ChatConfig)
Подробнее о его параметрах смотрите в разделе с описанием методов SDK в пакете edna.chatcenter.ui.visual.core.
Пожалуйста, убедитесь, что обращений к библиотеке нет до ее инициализации. Вместе с инициализацией можно передать параметры для
светлой и темной темы. Данные параметры опциональны.
В SDK уже заданы параметры по-умолчанию для светлой темы, если вы не определите свои. В случае, если не определена темная тема,
внутри SDK всегда будет использоваться светлая тема.
Если вы настраиваете SDK из java кода, то вместо обращений к полям будет обращение к методам. Например, chatConfig.setUserInputEnabled(server.isInputEnabled)
Подробнее смотри тут: https://kotlinlang.org/docs/java-to-kotlin-interop.html
Также см. разделы Пример авторизации на Java и Пример отображения чата на Java ниже на этой странице.
Пример инициализации:
// Задаем конфигурацию для внутреннего логирования в SDK. Необязательный параметр
val loggerConfig = ChatLoggerConfig(
applicationContext,
logFileSize = 50
)
// Задаем конфигурацию сервера
val server = ServersProvider.readServers().first()
val transportConfig = ChatTransportConfig(
server.serverBaseUrl,
server.threadsGateUrl,
server.datastoreUrl,
hashMapOf(), // задайте datastore headers, если необходимо
apiVersion = apiVersion
)
// Задаем SSL pinning, если необходимо
val certificates = server.trustedSSLCertificates.map { ChatSSLCertificate(it) }.toTypedArray()
val networkConfig = ChatNetworkConfig(
HTTPConfig(),
WSConfig(),
SSLPinningConfig(certificates, server.allowUntrustedSSLCertificate)
)
// Основная конфигурация чата
val chatConfig = ChatConfig(
transportConfig,
networkConfig,
searchEnabled = true,
linkPreviewEnabled = true,
voiceRecordingEnabled = true,
autoScrollToLatest = true
).apply {
userInputEnabled = server.isInputEnabled
}
// Создает объект класса SDK, передаем темы оформления, если необходимо,
// после чего необходимо вызвать метод "init(...)"
chatCenterUI = ChatCenterUI(applicationContext, loggerConfig).apply {
theme = chatLightTheme
darkTheme = chatDarkTheme
init(server.threadsGateProviderUid, server.appMarker, chatConfig)
}
Поля searchEnabled, linkPreviewEnabled, voiceRecordingEnabled, autoScrollToLatest в ChatConfig
помечены в коде как @Deprecated. В новых проектах рекомендуем настраивать
поиск, предпросмотр ссылок и запись голосовых сообщений на стороне сервера.
В примере выше они включены только для совместимости с уже настроенными инсталляциями.
Простейшая реализация вспомогательных объектов для локальной интеграции может выглядеть так:
// Конфигурация одного сервера edna для приложения
data class DemoServer(
val serverBaseUrl: String,
val threadsGateUrl: String,
val datastoreUrl: String,
val threadsGateProviderUid: String,
val appMarker: String,
val trustedSSLCertificates: List<String> = emptyList(),
val allowUntrustedSSLCertificate: Boolean = false,
val isInputEnabled: Boolean = true,
val apiVersion: Int = 20,
)
// Простейший провайдер серверов. В реальном приложении вы можете читать конфигурацию из файла или с backend-а.
object ServersProvider {
fun readServers(): List<DemoServer> = listOf(
DemoServer(
serverBaseUrl = "https://YOUR_REST_API_URL",
threadsGateUrl = "wss://YOUR_WEBSOCKET_URL",
datastoreUrl = "https://YOUR_DATASTORE_URL",
threadsGateProviderUid = "YOUR_PROVIDER_UID",
appMarker = "", // либо ваш appMarker, если он настроен на сервере
)
)
}
// Версия API, по умолчанию — 20, если команда поддержки edna не указала иное
val apiVersion: Int = ServersProvider.readServers().first().apiVersion
// Базовые темы для светлой и тёмной схемы. При желании вы можете настроить цвета/картинки через ChatTheme.
val chatLightTheme = ChatTheme(applicationContext)
val chatDarkTheme = ChatTheme(applicationContext)
Этот пример можно скопировать и адаптировать под ваш проект (URL-ы, appMarker, сертификаты и т.д.), чтобы код инициализации SDK из примера выше был самодостаточным.
appMarker- идентификатор приложения. edna Android поддерживает подключение нескольких приложений к одному серверу (подробнее см Настройка поведения и внешнего вида). Для этого нужно настроить идентификатор на сервере и в приложениях. В качествеappMarkerможет быть любая уникальная строка.appMarkerдолжен быть одинаковым у соответствующих Android и iOS приложений.
Мы рекомендуем делать иницализацию сдк в методе onCreate() класса Application. Любое взаимодействие с сдк должно быть всегда
и только после его иницализации.. Если вы делаете инициализацию асинхронно, следует также быть внимательным. Например, при открытии
пуш-уведомления следует также синхронизироваться с окончанием инициализации сдк, и только после этого обращатся к его методам
Подробнее форматы параметров и файлов вы можете посмотреть в коде тестового проекта. При возникновении вопросов обращайтесь на support@edna.ru
Авторизация пользователя
Перед работой с чатом нужно инициализировать пользователя: fun authorize(client: ChatUser, auth: ChatAuth?)
Пример:
chatCenterUI.authorize(
ChatUser(user.userId, data = user.userData.jsonStringToMap()),
ChatAuth(
user.authorizationHeader,
user.xAuthSchemaHeader,
signature = user.signature
)
)
Пример авторизации на Java
Map<String, String> userData = jsonStringToMap(user.getUserData());
ChatUser chatUser = new ChatUser(
user.getUserId(),
null,
userData
);
ChatAuth chatAuth = new ChatAuth(
user.getAuthorizationHeader(),
user.getXAuthSchemaHeader(),
ChatAuthType.HEADERS,
user.getSignature(),
false
);
chatCenterUI.authorize(chatUser, chatAuth);
Первый параметр, ChatUser, представляет собой реализацию следующего класса:
data class ChatUser(
/**
* Идентификатор пользователя. Обязательное поле
*/
val identifier: String,
/**
* Имя пользователя
*/
val name: String? = null,
/**
* Данные пользователя для отображения у оператора
*/
val data: Map<String, String>? = null
)
Второй параметр, ChatAuth:
data class ChatAuth(
/**
* Токен авторизации
*/
val token: String?,
/**
* Схема авторизации
*/
val scheme: String?,
/**
* Метод авторизации
*/
val method: ChatAuthType = ChatAuthType.HEADERS,
/**
* Подпись
*/
val signature: String?,
/**
* Шифрование client id
*/
val isEncrypted: Boolean = false
)
isEncrypted- данный параметр должен быть true, еслиidentifierпередается в зашифрованном виде.
Обязательный параметр только identifier. Он должен быть уникальным, постоянным и устойчивым к подбору — избегайте использования телефонов, email и других персональных данных. Если без них не обойтись, строго применяйте RSA-шифрование. При возникновении вопросов обращайтесь на support@edna.ru
Логаут пользователя
Для логаута пользователя вызовите метод chatCenterUI.logout(). Данный метод отправит запрос через сокет и очистит все данные для пользователя.
Также существует метод deauthorizeUser() - он удалит данные пользователя локально, без отправки запроса через сокет.
Отображение чата
Получить фрагмент чата можно двумя способами:
ChatFragment.newInstance()- каждый раз создает новый инстанс и возвращает его- В объекте
ChatCenterUIвызватьgetChatFragment(). Однако данный метод может вернуть null, если фрагмент еще не был создан После этого покажите данный фрагмент в нужном вам контейнере. Во фрагмент нужно передавать нажатия кнопки "назад" и проверять нужно ли закрыть чат:
override fun onBackPressed() {
val needsCloseChat: Boolean = chatFragment.onBackPressed()
if (needsCloseChat) {
//hide chatfragment
}
}
Пример отображения чата на Java
// Получаем фрагмент чата из SDK
ChatFragment chatFragment = chatCenterUI.getChatFragment();
if (chatFragment != null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.chat_container, chatFragment)
.commit();
}
@Override
public void onBackPressed() {
ChatFragment chat = chatFragment;
if (chat != null) {
boolean needsCloseChat = chat.onBackPressed();
if (needsCloseChat) {
// скрыть фрагмент или закрыть Activity
}
} else {
super.onBackPressed();
}
}
Также чат можно отобразить через встроенную в сдк активити, которая уже содержит фрагмент.
Чтобы создать новую активити и открыть ее, вызовите startActivity(new Intent(context, ChatActivity.class)).
Нужно помнить, что context должен быть либо сам активити, либо, например, указать флаг Intent.FLAG_ACTIVITY_NEW_TASK.
Например:
val intent = Intent(context, ChatActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
context.startActivity(intent)
Если вы хотите получить объект используемой активити, вызовите в объекте ChatCenterUI
метод getChatActivity(). Данный метод может вернуть null, если активити еще не была создана.
SDK представляет собой фрагмент чата - вы можете самостоятельно настроить отступы контейнера.
В Android 15 стал обязательным подход "edge-to-edge", описанный здесь: https://developer.android.com/develop/ui/views/layout/edge-to-edge
Если вам не нужен особый размер отступов, и фрагмент чата будет занимать весь экран, вы можете в ChatFlow включить настройку fullScreenMode,
которая добавит отступы для системных панелей