Публичный API SDK
object AltcraftSDK
AltcraftSDK
// Инициализация SDK и установка конфигурации
├─ fun initialization(context: Context, configuration: AltcraftConfiguration, complete: ((Result<Unit>) -> Unit)? = null): Unit
// Полная очистка данных SDK (БД, SP, фоновые задачи)
├─ fun clear(context: Context, onComplete: (() -> Unit)? = null): Unit
// Регистрация провайдера JWT
├─ fun setJWTProvider(provider: JWTInterface?): Unit
// Разрешить переинициализацию push-модуля в текущей сессии
├─ fun unlockInitialOperationsInThisSession(): Unit
// Запрос разрешения на отправку уведомлений (Android 13+)
├─ fun requestNotificationPermission(context: Context, activity: ComponentActivity): Unit
// Базовый получатель Altcraft push (можно переопределить)
├─ open class PushReceiver
│ // Обработка входящего push-сообщения
│ ├─ open suspend fun pushHandler(context: Context, message: Map<String, String>): Unit
│ // Точка входа доставки push в SDK
│ └─ companion object
│ ├─ fun takePush(context: Context, message: Map<String, String>): Unit
│ └─ fun isAltcraftPush(message: Map<String, String>): Boolean
// Публичные функции подписки
├─ val pushSubscriptionFunctions: PublicPushSubscriptionFunctions
│ // Подписка на push-уведомление (status = SUBSCRIBED)
│ ├─ fun pushSubscribe(
│ │ context: Context,
│ │ sync: Boolean = true,
│ │ profileFields: Map<String, Any?>? = null,
│ │ customFields: Map<String, Any?>? = null,
│ │ cats: List<CategoryData>? = null,
│ │ replace: Boolean? = null,
│ │ skipTriggers: Boolean? = null
│ │ ): Unit
│ // Приостановка подписки на push-уведомления (status = SUSPENDED)
│ ├─ fun pushSuspend(
│ │ context: Context,
│ │ sync: Boolean = true,
│ │ profileFields: Map<String, Any?>? = null,
│ │ customFields: Map<String, Any?>? = null,
│ │ cats: List<CategoryData>? = null,
│ │ replace: Boolean? = null,
│ │ skipTriggers: Boolean? = null
│ │ ): Unit
│ // Отписка от push-уведомлений (status = UNSUBSCRIBED)
│ ├─ fun pushUnSubscribe(
│ │ context: Context,
│ │ sync: Boolean = true,
│ │ profileFields: Map<String, Any?>? = null,
│ │ customFields: Map<String, Any?>? = null,
│ │ cats: List<CategoryData>? = null,
│ │ replace: Boolean? = null,
│ │ skipTriggers: Boolean? = null
│ │ ): Unit
│ // Смена статуса подписки указанной в JWT с suspended на subscribed, остальные подписки содержащие указанный push-токен сменят статус с subscribed на suspended.
│ ├─ suspend fun unSuspendPushSubscription(context: Context): ResponseWithHttpCode<ResponseWithProfile>?
│ // Статус последней подписки профиля
│ ├─ suspend fun getStatusOfLatestSubscription(context: Context): ResponseWithHttpCode<ResponseWithProfile>?
│ // Статус последней подписки профиля по указанному провайдеру push-уведомлений
│ ├─ suspend fun getStatusOfLatestSubscriptionForProvider(context: Context, provider: String? = null): ResponseWithHttpCode<ResponseWithProfile>?
│ // Статус подписки с текущим токеном устройства.
│ ├─ suspend fun getStatusForCurrentSubscription(context: Context): ResponseWithHttpCode<ResponseWithProfile>?
│ // Добавить функциональное поле профиля (set/incr/...)
│ └─ fun actionField(key: String): ActionFieldBuilder
// Публичные функции управления токенами
├─ val pushTokenFunctions: PublicPushTokenFunctions
│ // Сохранить токен провайдера вручную (onNewToken)
│ ├─ fun setPushToken(context: Context, provider: String?, token: String?): Unit
│ // Получить текущий токен устройства
│ ├─ suspend fun getPushToken(context: Context): TokenData?
│ // Зарегистрировать провайдера FCM
│ ├─ fun setFCMTokenProvider(provider: FCMInterface?): Unit
│ // Зарегистрировать провайдера HMS
│ ├─ fun setHMSTokenProvider(provider: HMSInterface?): Unit
│ // Зарегистрировать провайдера RuStore
│ ├─ fun setRuStoreTokenProvider(provider: RustoreInterface?): Unit
│ // Удалить токен у выбранного провайдера
│ ├─ fun deleteDeviceToken(context: Context, provider: String, complete: () -> Unit): Unit
│ // Форс-обновление токена (удалить —> обновить)
│ ├─ fun forcedTokenUpdate(context: Context, complete: () -> Unit): Unit
│ // Изменить приоритет провайдеров и обновить токен
│ └─ suspend fun changePushProviderPriorityList(context: Context, priorityList: List<String>): Unit
// Публичные функции отправки событий по пушам
├─ val pushEventFunctions: PublicPushEventFunctions
│ // Зафиксировать доставку Altcraft-push (вызывает delivery-ивент)
│ ├─ fun deliveryEvent(context: Context, message: Map<String, String>? = null, messageUID: String? = null): Unit
│ // Зафиксировать открытие Altcraft-push (вызывает open-ивент)
│ └─ fun openEvent(context: Context, message: Map<String, String>? = null, messageUID: String? = null): Unit
//
// Регистрация мобильных событий
├─ val mobileEventFunctions: PublicMobileEventFunctions
│ // Регистрирует мобильное событие Altcraft
│ └─ fun mobileEvent(
│ context: Context,
│ sid: String,
│ eventName: String,
│ sendMessageId: String? = null,
│ payload: Map<String, Any?>? = null,
│ matching: Map<String, Any?>? = null,
│ matchingType: String? = null,
│ profileFields: Map<String, Any?>? = null,
│ subscription: Subscription? = null,
│ utm: UTM? = null
│ ): Unit
//
// Обновление полей профиля
├─ val profileFunctions: PublicProfileFunctions
│ // Обновляет поля профиля Altcraft
│ └─ fun updateProfileFields(
│ context: Context,
│ profileFields: Map<String, Any?>? = null,
│ skipTriggers: Boolean? = null
│ ): Unit
//
// Публичные функции In-App уведомлений
├─ val inAppFunctions: PublicInAppFunctions
│ // Настроить анимацию In-App уведомления
│ ├─ fun setAnimation(block: Animator.() -> Unit): Unit
│ // Установить маркер текущего экрана (используется при фильтрации In-App уведомлений)
│ ├─ fun setScreen(screen: String): Unit
│ // Триггер кастомного In-App уведомления по имени
│ ├─ fun inAppTrigger(context: Context, name: String): Unit
│ // Запрос доступных In-App placements
│ ├─ fun getInAppPlacements(context: Context): Unit
│ // Подписаться на жизненный цикл Activity для автоматического показа In-App
│ ├─ fun subscribeOnActivityLifecycle(context: Context): Unit
│ // Подписка на In-App уведомления (status = SUBSCRIBED)
│ ├─ fun inAppSubscribe(
│ │ context: Context,
│ │ sync: Boolean = true,
│ │ profileFields: Map<String, Any?>? = null,
│ │ customFields: Map<String, Any?>? = null,
│ │ cats: List<CategoryData>? = null,
│ │ replace: Boolean? = null,
│ │ skipTriggers: Boolean? = null
│ │ ): Unit
│ // Отписка от In-App уведомлений (status = UNSUBSCRIBED)
│ ├─ fun inAppUnSubscribe(
│ │ context: Context,
│ │ sync: Boolean = true,
│ │ profileFields: Map<String, Any?>? = null,
│ │ customFields: Map<String, Any?>? = null,
│ │ cats: List<CategoryData>? = null,
│ │ replace: Boolean? = null,
│ │ skipTriggers: Boolean? = null
│ │ ): Unit
│ // Статус подписки на In-App уведомления
│ └─ suspend fun getInAppSubscriptionStatus(context: Context): ResponseWithHttpCode<ResponseWithProfile>?
//
// Публичные функции аутентификации
├─ val authFunctions: PublicAuthFunctions
│ // Аутентификация пользователя
│ ├─ fun authenticate(context: Context): Unit
│ // Выход пользователя
│ ├─ fun logOut(context: Context): Unit
│ // Проверка статуса аутентификации
│ └─ suspend fun isAuthenticated(context: Context): Boolean
//
// События SDK (один подписчик)
└─ val eventSDKFunctions: Events
// Подписаться на события SDK
├─ fun subscribe(newSubscriber: (Event) -> Unit): Unit
// Отписаться от событий SDK
└─ fun unsubscribe(): Unit
class AltcraftConfiguration
com.altcraft.sdk.config
└─ class AltcraftConfiguration private constructor(...)
// Класс инициализации конфигурации Altcraft SDK:
// URL API, ресурсный токен, сведения о приложении, флаг использования foreground service
// и настройки push-уведомлений (канал, модули получателя и приоритет провайдеров).
├─ class Builder(
│ apiUrl: String, // Базовый URL Altcraft API (обязательный)
│ icon: Int? = null, // ID ресурса иконки уведомлений (опционально)
│ rToken: String? = null, // Ролевой токен
│ appInfo: AppInfo? = null, // Метаданные Firebase Analytics (опционально)
| enableLogging: Boolean? = null, // Включает/отключает ведение логов (опционально)
│ providerPriorityList: List<String>? = null, // Приоритет провайдеров push-уведомлений (опционально)
│ pushReceiverModules: List<String>? = null, // Пакеты модулей, где может быть переопределён PushReceiver (опционально)
│ pushChannelName: String? = null, // Имя канала push-уведомлений (опционально)
│ pushChannelDescription: String? = null // Описание канала push-уведомлений (опционально)
│ )
│ └─ fun build(): AltcraftConfiguration // Построить валидную конфигурацию
│
├─ fun getApiUrl(): String // Возвращает базовый URL Altcraft API
├─ fun getIcon(): Int? // Возвращает ID иконки для уведомлений (опционально)
├─ fun getRToken(): String? // Возвращает ресурсный токен (опционально)
├─ fun getAppInfo(): AppInfo? // Сведения о приложении (ID/IID/версия) (опционально)
├─ fun getEnableLogging(): Boolean? // Включает/отключает ведение логов (опционально)
├─ fun getProviderPriorityList(): List<String>? // Приоритет провайдеров push-уведомлений (опционально)
├─ fun getPushReceiverModules(): List<String>? // Модули с переопределениями PushReceiver (опционально)
├─ fun getPushChannelName(): String? // Имя канала уведомлений (опционально)
└─ fun getPushChannelDescription(): String? // Описание канала уведомлений (опционально)
Event Classes
Event
// Базовое событие SDK (универсальная телеметрия).
function: String
event: SDKEvent?
eventMessage: String?
eventValue: Map<String, Any?>?
date: Date
internal: Boolean
Error
// Ошибка SDK, наследует Event.
function: String
event: SDKEvent?
eventMessage: String?
eventValue: Map<String, Any?>?
date: Date
RetryError
// Ошибка запроса, для которого предусмотрен автоматический повтор и выполнение
function: String
event: SDKEvent?
eventMessage: String?
eventValue: Map<String, Any?>?
date: Date
SDKEvent Enum
// Enum-класс, содержащий все типы событий SDK.
// Каждое значение содержит строковое сообщение (message).
enum class SDKEvent(val message: String) {
// Общие события SDK
ConfigIsSet("SDK configuration is installed"),
PushProviderSet("push provider set: "),
NotAcPush("received a notification unrelated to the Altcraft Platform"),
AcPush("received Altcraft push notification"),
PushIsPosted("push is posted"),
SdkCleared("SDK data has been cleared"),
ReceiverRedefined("receiver is redefined"),
NotAuthenticatedError("User is not authenticated"),
UserLogOut("User logged out. Anonymous session started."),
// Внутренние ошибки без повтора
ConfigIsNotSet("the configuration is not set"),
ConfigNotValid("invalid configuration"),
SdkInitWaitingExpired("SDK initialization timeout has expired"),
MobileEventPartsIsNull("mobile event parts is null"),
InvalidPushProvider("invalid provider. Available - android-firebase, android-huawei, android-rustore."),
PushDataIsNull("push data is null"),
PushUidIsNull("uid in the push data is null or empty, it is impossible to send a push event to the server."),
ErrorImgLoad("error uploading the notification image"),
NotificationErr("couldn't create notification"),
ChannelNotCreated("the notification channel has not been created"),
SmidIsNull("send message ID is null"),
InvalidStaticField("invalid in-app static field"),
RoomMigrationError("Room database migration failed. The local SDK database will be recreated."),
// Отсутствующие payload запросов (без повтора)
UnSuspendRequestDataIsNull("unsuspend request data is null"),
SubscriptionStatusRequestDataIsNull("status request data is null"),
InAppSubscriptionStatusRequestDataIsNull("status request data is null"),
AuthorizeRequestDataIsNull("authorize request data is null"),
// Лимит повторов достигнут
PushSubscribeRetryLimit("push subscribe retry limit"),
PushEventRetryLimit("push event retry limit"),
MobileEventRetryLimit("mobile event retry limit"),
ProfileUpdateRetryLimit("profile update retry limit"),
InAppSubscribeRetryLimit("in-app subscribe retry limit"),
AuthRequestRetryLimit("auth request retry limit"),
InAppEventRetryLimit("in-app event retry limit"),
// Проблемы состояния SDK или окружения
ConfigIsNull("config data is null"),
PushTokenIsNull("current push token is null"),
UserTagIsNull("userTag is null. It is impossible to identify the user"),
PermissionDenied("no permission to send notifications"),
NoInternetConnect("no internet connection, retry when connection is restored"),
NotUpdated("failed to update the push token. The subscription request was rejected"),
ResponseDataIsNull("response data is null"),
JwtTokenIsNull("JWT token is null"),
MatchingIsNull("matching mode is null"),
JwtTooLarge("JWT payload exceeds allowed size (16 KB limit): input rejected to prevent DoS"),
PayloadIsMissing("JWT does not contain a payload"),
InternalAuthIsNull("internal auth data is null"),
ExternalAuthIsNull("external auth data is null"),
MatchingIdIsNull("matching claim does not contain a matching ID"),
InvalidPayload("invalid mobile event payload: not all values are primitives"),
InvalidCustomFields("invalid custom fields: not all values are primitives"),
// Отсутствующие payload запросов (с повтором)
PushSubscribeRequestDataIsNull("push subscribe request data is null"),
TokenUpdateRequestDataIsNull("token update request data is null"),
PushEventRequestDataIsNull("push event request data is null"),
InAppEventRequestDataIsNull("in-app event request data is null"),
MobEventRequestDataIsNull("mobile event request data is null"),
ProfileUpdateRequestDataIsNull("profile update request data is null"),
InAppSubscribeRequestDataIsNull("profile update request data is null"),
InAppPlacementsRequestDataIsNull("in-app placements request data is null"),
// Успешные API-запросы
PushUnsubscribeRequestSuccessful("successful request: push/unsubscribe"),
PushSubscribeRequestSuccessful("successful request: push/subscribe"),
PushSuspendRequestSuccessful("successful request: push/suspend"),
InAppUnsubscribeRequestSuccessful("successful request: inapp/unsubscribe"),
InAppSubscribeRequestSuccessful("successful request: inapp/subscribe"),
InAppStatusRequestSuccessful("successful request: inapp/status"),
InAppEventRequestSuccessful("successful request: inapp/event"),
InAppPlacementsRequestSuccessful("successful request: in_app/placements"),
PushStatusRequestSuccessful("successful request: push/status"),
TokenUpdateRequestSuccessful("successful request: push/update"),
PushEventRequestSuccessful("successful request: event/push"),
MobileEventRequestSuccessful("successful request: event/post"),
UnsuspendRequestSuccessful("successful request: push/unsuspend"),
ProfileUpdateRequestSuccessful("successful request: profile/update"),
AuthenticateSuccessful("successful request: profile/authenticate"),
// Неудачные API-запросы
PushUnsubscribeRequestFailed("failed request: push/unsubscribe"),
PushSubscribeRequestFailed("failed request: push/subscribe"),
PushSuspendRequestFailed("failed request: push/suspend"),
InAppUnsubscribeRequestFailed("failed request: inapp/unsubscribe"),
InAppSubscribeRequestFailed("failed request: inapp/subscribe"),
InAppStatusRequestFailed("failed request: inapp/status"),
InAppEventRequestFailed("failed request: inapp/event"),
InAppPlacementsRequestFailed("failed request: in_app/placements"),
PushStatusRequestFailed("failed request: push/status"),
TokenUpdateRequestFailed("failed request: push/update"),
PushEventRequestFailed("failed request: event/push"),
MobileEventRequestFailed("failed request: event/post"),
ProfileUpdateRequestFailed("failed request: profile/update"),
UnsuspendRequestFailed("failed request: push/unsuspend"),
AuthenticateFailed("failed request: profile/authenticate"),
InAppStaticErrorLoad("error loading in-app notification static resources"),
InAppContentErrorLoad("error loading in-app notification content"),
}
Data Classes
// Токен push-провайдера устройства
data class TokenData(
provider: String,
token: String
)
// Опциональные данные для Firebase Analytics (если используется)
data class AppInfo(
appID: String = "",
appIID: String = "",
appVer: String = ""
)
// Обёртка ответа API вместе с HTTP-кодом
data class ResponseWithHttpCode<T : ResponseData>(
httpCode: Int?,
response: T?
)
// Ответ запроса (реализация ResponseData)
data class ResponseWithProfile(
error: Int? = null,
@SerialName("error_text") errorText: String? = null,
profile: ProfileData? = null
)
// Данные профиля пользователя
data class ProfileData(
id: String? = null,
status: String? = null,
acid: String? = null,
@SerialName("is_test") isTest: Boolean? = null,
subscription: SubscriptionData? = null
)
// Текущая подписка профиля
data class SubscriptionData(
@SerialName("subscription_id") subscriptionId: String? = null,
@SerialName("hash_id") hashId: String? = null,
provider: String? = null,
status: String? = null,
fields: Map<String, JsonElement>? = null,
cats: List<CategoryData>? = null
)
// Категория подписки (имя, заголовок, флаги)
data class CategoryData(
name: String?,
title: String? = null,
steady: Boolean? = null,
active: Boolean?
)
// Подписка на канал Email (добавляется мобильным событием)
data class EmailSubscription(
@SerialName("resource_id") resourceId: Int,
email: String,
status: String? = null,
priority: Int? = null,
@SerialName("custom_fields") customFields: Map<String, @Contextual Any?>? = null,
cats: List<String>? = null,
@SerialName("channel") channel: String = "email"
)
// Подписка на канал SMS (добавляется мобильным событием)
data class SmsSubscription(
@SerialName("resource_id") resourceId: Int,
phone: String,
status: String? = null,
priority: Int? = null,
@SerialName("custom_fields") customFields: Map<String, @Contextual Any?>? = null,
cats: List<String>? = null,
@SerialName("channel") channel: String = "sms"
)
// Подписка на push-канал (добавляется мобильным событием)
data class PushSubscription(
@SerialName("resource_id") resourceId: Int,
provider: String,
@SerialName("subscription_id") subscriptionId: String,
status: String? = null,
priority: Int? = null,
@SerialName("custom_fields") customFields: Map<String, @Contextual Any?>? = null,
cats: List<String>? = null,
@SerialName("channel") channel: String = "push"
)
// Подписка с cc_data (Telegram, WhatsApp, Viber, Notify)
data class CcDataSubscription(
@SerialName("resource_id") resourceId: Int,
@SerialName("channel") channel: String,
@SerialName("cc_data") ccData: JsonObject,
status: String? = null,
priority: Int? = null,
@SerialName("custom_fields") customFields: Map<String, @Contextual Any?>? = null,
cats: List<String>? = null
)
// Контейнер UTM-параметров для атрибуции мобильных событий (все поля опциональны)
data class UTM(
campaign: String? = null,
content: String? = null,
keyword: String? = null,
medium: String? = null,
source: String? = null,
temp: String? = null
)
Constants
com.altcraft.sdk.data
└─ object Constants
// Провайдеры push-уведомлений
├─ const val FCM_PROVIDER: String = "android-firebase"
├─ const val HMS_PROVIDER: String = "android-huawei"
└─ const val RUS_PROVIDER: String = "android-rustore"
// Статусы подписки
├─ const val SUBSCRIBED: String = "subscribed"
├─ const val UNSUBSCRIBED: String = "unsubscribed"
└─ const val SUSPENDED: String = "suspended"
Interfaces
JWTInterface:
JWTInterface
// Доступ к текущему JWT
└─ fun getJWT(): String?
// Возвращает JWT или null
FCMInterface:
FCMInterface
// Контракт операций с FCM-токеном
├─ suspend fun getToken(): String?
│ // Возвращает токен FCM и ли null
└─ fun deleteToken(completion: (Boolean) -> Unit)
// Удаляет токен FCM
HMSInterface:
HMSInterface
// Контракт операций с HMS-токеном
├─ suspend fun getToken(context: Context): String?
│ // Возвращает токен HMS или null
└─ fun deleteToken(context: Context, complete: (Boolean) -> Unit)
// Удаляет токен HMS
RuStoreInterface:
RustoreInterface
// Контракт операций с RuStore-токеном
├─ suspend fun getToken(): String?
│ // Возвращает токен RuStore или null
└─ fun deleteToken(complete: (Boolean) -> Unit)
// Удаляет токен RuStore
Subscription:
Subscription (sealed interface)
// Базовый контракт модели подписки для всех каналов
├─ val resourceId: Int
│ // Обязательный ID ресурса Altcraft (JSON: "resource_id")
├─ val status: String?
│ // Необязательный статус подписки
├─ val priority: Int?
│ // Необязательный приоритет
├─ val customFields: Map<String, @Contextual Any?>?
│ // Необязательные стандартные и кастомные поля (JSON: "custom_fields")
├─ val cats: List<String>?
│ // Необязательные категории подписки
└─ val channel: String
// Обязательный тип канала (например, "email", "sms", "push", "telegram_bot", ...)