Настройка
Инициализация
- В
Application.onCreate()
, или в другом удобном для вас месте необходимо инициализировать библиотекуThreadsLib.init(ConfigBuilder configBuilder)
. Пожалуйста, убедитесь, что обращений к библиотеке нет до ее инициализации
class ConfigBuilder {
private val context: Context
private val pendingIntentCreator: PendingIntentCreator = { context, appMarker ->
...
}
private val unreadMessagesCountListener: UnreadMessagesCountListener? = null
private val isDebugLoggingEnabled: Boolean = false
private val historyLoadingCount: Int = 50
class ConfigBuilder(val context: Context) {
...
}
}
Пример инициализации в нашем демо-приложении можно увидеть
в классе io.edna.threads.demo.integrationCode.fragments.launch.LaunchViewModel
, метод login(...)
).
Инициализация состоит из следущих этапов:
- Kotlin
- Java
class ThreadsDemoApplication : Application() {
override fun onCreate() {
super.onCreate()
val configBuilder = ConfigBuilder(this) // this - android context
val transportConfig = getTransportConfig(this)
configBuilder.serverBaseUrl(transportConfig.baseUrl)
.datastoreUrl(transportConfig.datastoreUrl)
.threadsGateUrl(transportConfig.threadsGateUrl)
.threadsGateProviderUid(transportConfig.threadsGateProviderUid)
.keepSocketActive(true)
.setNewChatCenterApi()
ThreadsLib.init(configBuilder)
}
fun getTransportConfig(ctx: Context?): TransportConfig? {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ctx)
val baseUrl = sharedPreferences.getString(PREF_SERVER_BASE_URL, null)
?: return null
val datastoreUrl = sharedPreferences.getString(PREF_DATASTORE_URL, null)
?: return null
val threadsGateUrl = sharedPreferences.getString(PREF_THREADS_GATE_URL, null)
?: return null
val threadsGateProviderUid =
sharedPreferences.getString(PREF_THREADS_GATE_PROVIDER_UID, null)
?: return null
return TransportConfig(
baseUrl,
datastoreUrl,
threadsGateUrl,
threadsGateProviderUid
)
}
}
public class ThreadsDemoApplication extends Application {
@Override
void onCreate() {
ConfigBuilder configBuilder = new ConfigBuilder(this); // this - android context
TransportConfig transportConfig = getTransportConfig(this);
configBuilder.serverBaseUrl(transportConfig.baseUrl)
.datastoreUrl(transportConfig.datastoreUrl)
.threadsGateUrl(transportConfig.threadsGateUrl)
.threadsGateProviderUid(transportConfig.threadsGateProviderUid);
.keepSocketActive(true)
.setNewChatCenterApi()
ThreadsLib.init(configBuilder);
}
TransportConfig getTransportConfig(Context ctx) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ctx);
String baseUrl = sharedPreferences.getString(PREF_SERVER_BASE_URL, null)
?: return null;
String datastoreUrl = sharedPreferences.getString(PREF_DATASTORE_URL, null)
?: return null;
String threadsGateUrl = sharedPreferences.getString(PREF_THREADS_GATE_URL, null)
?: return null;
String threadsGateProviderUid =
sharedPreferences.getString(PREF_THREADS_GATE_PROVIDER_UID, null)
?: return null;
return new TransportConfig(
baseUrl,
datastoreUrl,
threadsGateUrl,
threadsGateProviderUid
);
}
}
Обязательными параметрами являются context
, serverBaseUrl
, datastoreUrl
, threadsGateUrl
, threadsGateProviderUid
.
Если вы не разделяете пути для отправки файлов и для работы с backend API, вы можете передать одинаковые параметры для serverBaseUrl
и для datastoreUrl
.
Данные параметры (кроме context
) и многие другие можно прописать через манифест. Пример:
<meta-data
android:name="im.threads.getDatastoreUrl"
android:value="http://datastore.yourcompany.com/"/>
Полный список параметров, которые поддерживаются через манифест:
"im.threads.getDatastoreUrl"
, "im.threads.getServerUrl"
, "im.threads.threadsGateUrl"
, "im.threads.threadsGateProviderUid"
,
"im.threads.clientIdIgnoreEnabled"
, "im.threads.newChatCenterApi"
, "im.threads.attachmentEnabled"
, "im.threads.filesAndMediaMenuItemEnabled"
Подробную информацию о параметрах данного класса см Настройка поведения и внешнего вида
Подробнее форматы параметров и файлов вы можете посмотреть в коде тестового проекта. При возникновении вопросов обращайтесь на support@edna.ru
- Перед работой с чатом нужно инициализировать пользователя
ThreadsLib.initUser(UserInfoBuilder userInfo, boolean forceRegistration)
Если forceRegistration
установить в true
(по умолчанию false
), то sdk отправит при вызове данного метода запрос на регистрацию
девайса и, если чат еще не отображен на экране, закроет сокет. Также в этом случае, если вы сразу за forceRegistration вызовите метод
initUser(...)
, ваш бот (если он у вас настроен) не будет вам в первый раз слать сообщение в ответ. Таким образом, вы можете сделать скрытую
регистрацию пользователя до входа в чат. Рекомендуется использовать значение по умолчанию, при котором сохраняется
только UserInfoBuilder
, а запрос на регистрацию девайса вместе с остальными запросами будет отправлен при открытии чата.
Первый параметр, UserInfoBuilder
, представляет собой реализацию следующего класса:
class UserInfoBuilder(var clientId: String) {
var authToken: String?
var authSchema: String?
var clientData: String?
var clientIdSignature: String
var userName: String?
var appMarker: String?
var clientIdEncrypted: Boolean = false // true if client id is encrypted
// ...
}
Где:
authToken
- строка, которая будет передаваться в http-заголовке Authorization.authSchema
- строка, которая будет передаваться в http-заголовке X-Auth-Schema.clientIdSignature
- авторизационная подпись clientId, должна генерироваться на вашем сервере на основе clientId с помощью приватного ключа RSA, затем зашифрована в Base64. По общей схеме работы с подписью см. документацию по бэкендуuserName
- имя клиента (может быть пустым)clientData
- кастомные данные приложения, в виде json строки (может быть пустым). Параметры которые будут отображены в общей информации о клиенте:name
,phone
,email
. Пример:
{
"name": "Name Surname",
"phone": "+7-999-999-99-99",
"email": "e@mail.com",
"customField":"customValue"
}
appMarker
- идентификатор приложения. edna Android поддерживает подключение нескольких приложений к одному серверу (подробнее см Настройка поведения и внешнего вида). Для этого нужно настроить идентификатор на сервере и в приложениях. В качествеappMarker
может быть любая уникальная строка.appMarker
должен быть одинаковым у соответствующих Android и iOS приложений.clientIdEncrypted
- данный параметр должен быть true, еслиclientId
передается в зашифрованном виде.
Обязательный параметр только clientId
. Он должен быть уникальным, и всегда относится к одному и тому же пользователю. Избегайте использования в качестве идентификатора номера телефона, адреса электронной почты и прочих идентификаторов привязанных к данным пользователя.
Отображение чата
Отобразить чат можно двумя способами:
- В активности -
startActivity(new Intent(this, ChatActivity.class))
- Во фрагменте
- Создать
ChatFragment.newInstance()
и показать в нужном вам контейнере - Передавать нажатия кнопки "назад" и проверять нужно ли закрыть чат:
- Создать
override fun onBackPressed() {
val needsCloseChat: Boolean = chatFragment.onBackPressed()
if (needsCloseChat) {
//hide chatfragment
}
}
Для кастомизации внешнего вида чата необходимо использовать
ThreadsLib.applyLightTheme(ChatStyle chatStyle)
для светлой темы и
ThreadsLib.applyDarkTheme(ChatStyle chatStyle)
для темной темы. Можно также переопределять ресурсы библиотеки, но ChatStyle
приоритетнее. Полный список настроек: Настройка поведения и внешнего вида
Пример в
ChatStyleBuilderHelper
в демо-приложении