Все публичные классы, методы и свойства SDK Android (ru.shtab.helpdesk) и iOS (ShtabHelpdesk) версии 1.0.0-beta.2. Как встроить чат по шагам — в руководствах Android и iOS. Вкладка языка запоминается для всей страницы.
Весь API вызывается из главного потока: в Kotlin методы помечены @MainThread, в Swift HelpdeskSDK — @MainActor.
Инициализация
SDK настраивается один раз при старте приложения: адрес установки (только origin, https) и ключ размещения приложения из Интеграции → Мобильные приложения. Обычный http:// принимается только в отладочной сборке приложения — для стенда.
| Символ | Что делает |
|---|
HelpdeskSdk | Точка входа SDK — объект: настройка, вход пользователя, экран чата, push. Методы доступны из Java как статические. |
HelpdeskSdk.configure(context, installationUrl, placementKey, options) | Настраивает SDK: установка, ключ размещения и необязательные HelpdeskOptions. Неверный адрес, ключ, язык, версия приложения или пин — IllegalArgumentException. |
HelpdeskSdk.isConfigured | true, если configure уже вызван. openChat, registerPushToken, handleNotification и logout до настройки бросают IllegalStateException. |
HelpdeskSdk.VERSION | Версия SDK (semver), например 1.0.0-beta.2. |
HelpdeskSdk.BRIDGE_VERSION | Версия моста между SDK и интерфейсом чата: установка, не поддерживающая её, получает вшитый интерфейс. |
class App : Application() {
override fun onCreate() {
super.onCreate()
HelpdeskSdk.configure(
this,
installationUrl = "https://support.example.com",
placementKey = "pk_…",
options = HelpdeskOptions(appVersion = BuildConfig.VERSION_NAME),
)
}
}
| Символ | Что делает |
|---|
HelpdeskSDK | Точка входа SDK: настройка, вход пользователя, экран чата, push. |
HelpdeskSDK.configure(installationURL:placementKey:options:) | Настраивает SDK: установка, ключ размещения и необязательные HelpdeskOptions. Бросает HelpdeskError. |
HelpdeskSDK.isConfigured | true, если configure уже вызван. |
HelpdeskSDK.version | Версия SDK (semver), например 1.0.0-beta.2. |
HelpdeskSDK.bridgeVersion | Версия моста между SDK и интерфейсом чата: установка, не поддерживающая её, получает вшитый интерфейс. |
import ShtabHelpdesk
func application(_ application: UIApplication,
didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
try? HelpdeskSDK.configure(
installationURL: URL(string: "https://support.example.com")!,
placementKey: "pk_…",
options: HelpdeskOptions(appVersion: "2.4.1")
)
return true
}
Параметры
Все параметры необязательны.
| Символ | Что делает |
|---|
HelpdeskOptions | Параметры configure; из Java — перегрузки конструктора. |
HelpdeskOptions.locale | ru или en, пока окно размещения не назовёт свой язык; null — русский. |
HelpdeskOptions.appVersion | Версия приложения для диагностики регистраций push, например 2.4.1. |
HelpdeskOptions.certificatePins | Пины ключей установки sha256/<base64>, их даёт администратор установки; пусто — без пиннинга. Что они покрывают — в руководстве. |
HelpdeskOptions.logger | Куда идёт диагностика; null — Logcat, только предупреждения и ошибки. |
HelpdeskLogger | Приёмник диагностики — функциональный интерфейс. |
HelpdeskLogger.log(level, code) | Получает уровень и код (ui.bundled.offline, token.timeout…) — никогда текст сообщений, токены или персональные данные. |
LogLevel | Уровень диагностического кода. |
LogLevel.DEBUG | Отладочный код. |
LogLevel.INFO | Сведения о работе, например ui.installation — открыт интерфейс установки. |
LogLevel.WARN | Предупреждение; по умолчанию попадает в Logcat. |
LogLevel.ERROR | Ошибка; по умолчанию попадает в Logcat. |
HelpdeskOptions(
locale = "ru",
appVersion = BuildConfig.VERSION_NAME,
logger = HelpdeskLogger { level, code -> analytics.log("helpdesk", level.name, code) },
)
| Символ | Что делает |
|---|
HelpdeskOptions | Параметры configure. |
HelpdeskOptions.init(locale:appVersion:certificatePins:logger:) | Создаёт параметры; у каждого есть значение по умолчанию. |
HelpdeskOptions.locale | ru или en, пока окно размещения не назовёт свой язык; nil — язык устройства. |
HelpdeskOptions.appVersion | Версия приложения для диагностики регистраций push, например 2.4.1. |
HelpdeskOptions.certificatePins | Пины ключей установки sha256/<base64>, их даёт администратор установки; пусто — без пиннинга. Что они покрывают — в руководстве. |
HelpdeskOptions.logger | Куда идёт диагностика; nil — системный журнал, только предупреждения и ошибки. |
HelpdeskLogger | Приёмник диагностики: замыкание (HelpdeskLogLevel, String) -> Void, вызывается в главном потоке. Получает только коды — никогда текст сообщений, токены или персональные данные. |
HelpdeskLogLevel | Уровень диагностического кода. |
HelpdeskLogLevel.debug | Отладочный код. |
HelpdeskLogLevel.info | Сведения о работе, например ui.installation — открыт интерфейс установки. |
HelpdeskLogLevel.warn | Предупреждение; по умолчанию попадает в системный журнал. |
HelpdeskLogLevel.error | Ошибка; по умолчанию попадает в системный журнал. |
HelpdeskOptions(
locale: "ru",
appVersion: "2.4.1",
logger: { level, code in analytics.log("helpdesk", level.rawValue, code) }
)
Вход пользователя
Пользователь приложения входит в чат токеном чата (chat token): его подписывает бэкенд приложения для своего вошедшего пользователя — iss, aud = ключ размещения, sub, exp не дольше 10 минут, jti. SDK просит токен при каждом открытии чата и когда сессия чата закончилась, использует один раз и не хранит. Нет ответа за 15 секунд — чат открывается без входа. Поля токена — те же, что у виджета.
| Символ | Что делает |
|---|
HelpdeskSdk.setChatTokenProvider(provider) | Откуда SDK берёт токен чата; null — нет вошедшего пользователя, доступны только гостевые размещения. |
ChatTokenProvider | Поставщик токена чата — функциональный интерфейс. |
ChatTokenProvider.requestChatToken(callback) | SDK просит свежий токен; ответить в callback один раз, из любого потока. |
ChatTokenCallback | Ответ поставщика. |
ChatTokenCallback.onChatToken(chatToken) | Токен или null, если в приложении никто не вошёл: чат попросит войти в приложении снова. |
HelpdeskSdk.logout() | Пользователь вышел: экран чата закрывается, сессия завершается на сервере (он отключает push устройства), данные чата в WebView удаляются. Без сети сервер узнает об этом при следующем configure. |
HelpdeskSdk.setChatTokenProvider { callback ->
backend.issueSupportToken { token -> callback.onChatToken(token) }
}
HelpdeskSdk.logout()
| Символ | Что делает |
|---|
HelpdeskSDK.setChatTokenProvider(_:) | Откуда SDK берёт токен чата: async-замыкание, возвращающее токен или nil, либо вариант с completion handler — вызвать его один раз, из любого потока. nil вместо поставщика — доступны только гостевые размещения. |
HelpdeskSDK.logout() | Пользователь вышел: экран чата закрывается, сессия завершается на сервере (он отключает push устройства), данные чата в WebView удаляются. Без сети сервер узнает об этом при следующем configure. |
HelpdeskSDK.setChatTokenProvider {
try? await backend.issueSupportToken()
}
HelpdeskSDK.logout()
Экран чата
| Символ | Что делает |
|---|
HelpdeskSdk.openChat(activity) | Открывает экран чата поверх activity. Обращение из нажатого push открывается в нём после входа пользователя. |
HelpdeskChatActivity | Экран чата: WebView с интерфейсом установки или вшитым. Объявлен в манифесте SDK; открывается только через openChat. |
supportButton.setOnClickListener { HelpdeskSdk.openChat(this) }
| Символ | Что делает |
|---|
HelpdeskSDK.presentChat(from:animated:) | Показывает чат поверх presenter (sheet). Обращение из нажатого push открывается в нём после входа пользователя. |
HelpdeskSDK.makeChatViewController() | Экран чата для своей навигации: стек, вкладка. |
HelpdeskChatView | Экран чата в SwiftUI: .sheet или destination стека навигации. |
HelpdeskChatView.init() | Создаёт экран. |
HelpdeskChatView.makeUIViewController(context:) | Часть UIViewControllerRepresentable: SwiftUI создаёт экран сам, приложение не вызывает. |
HelpdeskChatView.updateUIViewController(_:context:) | Часть UIViewControllerRepresentable; экрану обновлять нечего. |
HelpdeskChatView.dismantleUIViewController(_:coordinator:) | Часть UIViewControllerRepresentable: sheet закрыт, экран отпускает мост и выбранные файлы. |
HelpdeskSDK.presentChat(from: viewController)
.sheet(isPresented: $support) { HelpdeskChatView() }
Push
Сервер шлёт push без текста сообщения: заголовок «Новый ответ» на языке размещения и данные conversation_id и kind (new_reply, у проверки из консоли — test). Обращение из push открывается только после входа пользователя в чат.
| Символ | Что делает |
|---|
HelpdeskSdk.registerPushToken(token) | FCM registration token устройства (onNewToken и при старте): SDK хранит его под защитой Keystore и регистрирует при каждом входе в чат. |
HelpdeskSdk.handleNotification(intent, activity) | Нажатие на уведомление принесло intent: true, если это push установки. С activity чат открывается сразу, без неё — при следующем openChat. |
HelpdeskNotifications | Помощники для push установки. |
HelpdeskNotifications.KEY_CONVERSATION_ID | Ключ conversation_id в data push. |
HelpdeskNotifications.KEY_KIND | Ключ kind в data push. |
HelpdeskNotifications.DEFAULT_CHANNEL_ID | Канал уведомлений SDK — shtab_helpdesk; свой канал называют в настройках FCM в консоли. |
HelpdeskNotifications.isHelpdeskPush(data) | Это data FCM — push установки? |
HelpdeskNotifications.createChannel(context, name, channelId) | Создаёт канал уведомлений; name пользователь видит в настройках приложения. |
HelpdeskNotifications.show(context, data, smallIcon, title, text, channelId) | Показывает push, пришедший, пока приложение на экране: нажатие откроет launch activity с ключами push. false — push не наш или уведомления выключены. |
class Messaging : FirebaseMessagingService() {
override fun onNewToken(token: String) {
Handler(Looper.getMainLooper()).post { HelpdeskSdk.registerPushToken(token) }
}
override fun onMessageReceived(message: RemoteMessage) {
if (HelpdeskNotifications.isHelpdeskPush(message.data)) {
HelpdeskNotifications.show(this, message.data, R.drawable.ic_notification)
}
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
HelpdeskSdk.handleNotification(intent, this)
}
| Символ | Что делает |
|---|
HelpdeskSDK.registerPushToken(_:) | Device token APNs (Data из didRegisterForRemoteNotificationsWithDeviceToken) или токен в hex: SDK хранит его в Keychain и регистрирует при каждом входе в чат. Вариант со строкой бросает HelpdeskError. |
HelpdeskSDK.handleNotification(_:presentingFrom:) | Нажатие на уведомление — userInfo или UNNotificationResponse: true, если это push установки. С presentingFrom чат показывается сразу, без него — при следующем presentChat. |
HelpdeskNotifications | Помощники для push установки. |
HelpdeskNotifications.keyConversationID | Ключ conversation_id рядом с aps. |
HelpdeskNotifications.keyKind | Ключ kind рядом с aps. |
HelpdeskNotifications.isHelpdeskPush(_:) | Этот userInfo — push установки? |
HelpdeskNotifications.presentationOptions(for:) | Для willPresent: пока чат на экране — ничего не показывать, иначе баннер; nil — push не наш, решает приложение. |
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
HelpdeskSDK.registerPushToken(deviceToken)
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification,
withCompletionHandler completion: @escaping (UNNotificationPresentationOptions) -> Void) {
completion(HelpdeskNotifications.presentationOptions(for: notification) ?? [.banner, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse,
withCompletionHandler completion: @escaping () -> Void) {
HelpdeskSDK.handleNotification(response, presentingFrom: rootViewController)
completion()
}
События
Непрочитанные ответы в открытом чате и отклонённый токен чата приходят в главном потоке.
| Символ | Что делает |
|---|
HelpdeskSdk.setEventListener(listener) | Подписывает приложение на события чата; null — отписаться. |
HelpdeskEventListener | Слушатель событий; у методов есть пустые реализации по умолчанию. |
HelpdeskEventListener.onUnreadChanged(count) | Изменилось число непрочитанных ответов в открытом чате; 0 — прочитаны. |
HelpdeskEventListener.onSessionExpired() | Токен чата отклонён: пользователь не войдёт в чат, пока поставщик не выдаст новый. |
HelpdeskSdk.setEventListener(object : HelpdeskEventListener {
override fun onUnreadChanged(count: Int) {
badge.text = count.toString()
}
})
| Символ | Что делает |
|---|
HelpdeskSDK.onEvent | Замыкание, получающее HelpdeskEvent. |
HelpdeskSDK.delegate | Те же события вызовами делегата (UIKit); слабая ссылка. |
HelpdeskEvent | Событие чата. |
HelpdeskEvent.unreadChanged | Изменилось число непрочитанных ответов в открытом чате; 0 — прочитаны. |
HelpdeskEvent.sessionExpired | Токен чата отклонён: пользователь не войдёт в чат, пока поставщик не выдаст новый. |
HelpdeskDelegate | Делегат событий; у методов есть пустые реализации по умолчанию. |
HelpdeskDelegate.helpdeskUnreadChanged(_:) | То же, что HelpdeskEvent.unreadChanged. |
HelpdeskDelegate.helpdeskSessionExpired() | То же, что HelpdeskEvent.sessionExpired. |
HelpdeskSDK.onEvent = { event in
if case let .unreadChanged(count) = event {
supportButton.badge = count
}
}
Отладка
Помощники проверяют обработку push и переход к обращению до того, как придут настоящие push. Работают только в отладочной сборке приложения.
| Символ | Что делает |
|---|
HelpdeskDebug | Отладочные помощники; в релизной сборке методы бросают IllegalStateException. |
HelpdeskDebug.testPushData(context, conversationId) | data, который шлёт сервер: с обращением — new_reply, без него — test. |
HelpdeskDebug.testNotificationIntent(context, conversationId) | Launch intent, который приносит приложению нажатие на такой push: его передают в handleNotification. |
HelpdeskSdk.handleNotification(HelpdeskDebug.testNotificationIntent(context, conversationId), activity)
| Символ | Что делает |
|---|
HelpdeskDebug | Отладочные помощники; в сборках TestFlight и App Store методы бросают HelpdeskError.debugOnly. |
HelpdeskDebug.testPushUserInfo(conversationID:) | userInfo, который шлёт сервер: с обращением — new_reply, без него — test. |
HelpdeskDebug.scheduleTestNotification(conversationID:after:) | Ставит такое локальное уведомление: его нажатие приходит в делегат уведомлений приложения, как настоящий push. Нужно разрешение на уведомления. |
try await HelpdeskDebug.scheduleTestNotification(conversationID: conversationID, after: 3)
Ошибки
SDK Android сообщает о неверном вызове стандартными исключениями: IllegalArgumentException — неверный адрес, ключ, параметр или push-токен, IllegalStateException — вызов до configure или отладочный помощник в релизной сборке. В iOS ошибки — HelpdeskError.
Своих типов ошибок в SDK Android нет.
| Символ | Что делает |
|---|
HelpdeskError | Ошибка вызова SDK. |
HelpdeskError.invalidInstallationURL | Адрес установки — не origin на https (в отладочной сборке — и http). |
HelpdeskError.invalidPlacementKey | Строка не похожа на ключ размещения. |
HelpdeskError.invalidLocale | Язык не ru и не en. |
HelpdeskError.invalidAppVersion | Версия приложения длиннее 32 символов или с недопустимыми символами. |
HelpdeskError.invalidPin | Пин не вида sha256/<base64>. |
HelpdeskError.invalidPushToken | Строка не похожа на push-токен. |
HelpdeskError.notConfigured | Вызов до configure. |
HelpdeskError.debugOnly | Отладочный помощник в сборке, которая не является отладочной. |