Skip to main content
Documentation for version v73

SDK Functionality

Working with subscription statuses


Getting a subscription status

AltcraftSDK
└── val pushSubscriptionFunctions: PublicPushSubscriptionFunctions
// Status of the profile’s latest subscription
├── suspend fun getStatusOfLatestSubscription(
│ context: Context
│ ): DataClasses.ResponseWithHttpCode?
// Status for the current token/provider
├── suspend fun getStatusForCurrentSubscription(
│ context: Context
│ ): DataClasses.ResponseWithHttpCode?
// Status of the latest subscription for the given provider (if null — current provider is used)
└── suspend fun getStatusOfLatestSubscriptionForProvider(
context: Context,
provider: String? = null
): DataClasses.ResponseWithHttpCode?

Subscription status request functions:

  • fun getStatusOfLatestSubscription() — status of the profile’s latest subscription;
  • fun getStatusOfLatestSubscriptionForProvider() — status for the current token/provider;
  • fun getStatusForCurrentSubscription() — status of the latest subscription by provider. If null is passed, the current provider is used.

suspend fun getStatusOfLatestSubscription(context: Context): DataClasses.ResponseWithHttpCode?

Retrieves the status of the profile’s latest subscription. Returns a ResponseWithHttp? object containing response?.profile?.subscription — the latest subscription created in the profile. If no such subscription exists, null is returned.

Usage example:

// Status of the profile’s latest subscription
AltcraftSDK.pushSubscriptionFunctions.getStatusOfLatestSubscription(context)

suspend fun getStatusForCurrentSubscription(context: Context): DataClasses.ResponseWithHttpCode?

Retrieves the status for the current token/provider. Returns a ResponseWithHttp? object containing response?.profile?.subscription — the subscription found by the current push token and provider. If no such subscription exists, null is returned.

Usage example:

// Status matching the current token/provider
AltcraftSDK.pushSubscriptionFunctions.getStatusForCurrentSubscription(context)

suspend fun getStatusOfLatestSubscriptionForProvider(context: Context, provider: String? = null): DataClasses.ResponseWithHttpCode?

Retrieves the status of the latest subscription for a provider. Returns a ResponseWithHttp? object containing response?.profile?.subscription — the latest subscription created with the specified push provider. If the provider is not specified (provider = null), the current token’s provider is used. If no such subscription exists, null is returned.

// Latest subscription status for a provider (uses current if null)
AltcraftSDK.pushSubscriptionFunctions.getStatusOfLatestSubscriptionForProvider(context, provider = null)

Below is an example of extracting profile, subscription, and category data from a status response. This approach applies to all status-fetching functions:

Data from status functions
CoroutineScope(Dispatchers.IO).launch {
AltcraftSDK.pushSubscriptionFunctions
.getStatusForCurrentSubscription(this@App)
?.let { it ->
val httpCode = it.httpCode
val response = it.response
val error = response?.error
val errorText = response?.errorText
val profile = response?.profile
val subscription = profile?.subscription
val cats = subscription?.cats
}
}

Changing a subscription status

AltcraftSDK
└─ val pushSubscriptionFunctions: PublicPushSubscriptionFunctions
// Subscribe (status = SUBSCRIBED)
├─ fun pushSubscribe(
│ context: Context,
│ sync: Boolean = true,
│ profileFields: Map<String, Any?>? = null,
│ customFields: Map<String, Any?>? = null,
│ cats: List<DataClasses.CategoryData>? = null,
│ replace: Boolean? = null,
│ skipTriggers: Boolean? = null
): Unit
// Suspend (status = SUSPENDED)
├─ fun pushSuspend(
│ context: Context,
│ sync: Boolean = true,
│ profileFields: Map<String, Any?>? = null,
│ customFields: Map<String, Any?>? = null,
│ cats: List<DataClasses.CategoryData>? = null,
│ replace: Boolean? = null,
│ skipTriggers: Boolean? = null
): Unit
// Unsubscribe (status = UNSUBSCRIBED)
└─ fun pushUnSubscribe(
context: Context,
sync: Boolean = true,
profileFields: Map<String, Any?>? = null,
customFields: Map<String, Any?>? = null,
cats: List<DataClasses.CategoryData>? = null,
replace: Boolean? = null,
skipTriggers: Boolean? = null
): Unit

Subscription status change functions:

  • fun pushSubscribe() — subscribes to push notifications;
  • fun pushUnSubscribe() — cancels the push subscription;
  • fun pushSuspend() — suspends the push subscription (no notifications are delivered, and an unsubscribe event is not created in the user’s profile);
  • fun unSuspendPushSubscription() — used to implement LogIn/LogOut transitions.

These functions share the same signature with the following parameters:


context: Context

Required: Yes Description: Android Context.


sync: Boolean

Default: true Required: No Description: Flag that sets synchronous execution of the request.

Successful request execution:

On success, this group of functions emits an event with code 230 that contains event.value, which depends on the sync flag:

If sync == true
ResponseWithHttpCode
├─ httpCode: 200
└─ response
├─ error: 0
├─ errorText: ""
└─ profile
├─ id: "your id"
├─ status: "subscribed"
├─ isTest: false
└─ subscription
├─ subscriptionId: "your subscriptionId"
├─ hashId: "c52b28d2"
├─ provider: "ios-apns"
├─ status: "subscribed"
├─ fields
│ ├─ _os_ver: {"raw":"18.6.2","ver":"[\"18.0\", \"6.0\", \"2.0\"]"}
│ ├─ _device_type: "Mobile"
│ ├─ _ad_track: false
│ ├─ _device_name: "iPhone"
│ ├─ _os_language: "en"
│ ├─ _os_tz: "+0300"
│ ├─ _os: "IOS"
│ └─ _device_model: "iPhone14,7"
└─ cats
└─ [ { name: "developer_news", title: "dev_news", steady: false, active: false } ]

For synchronous requests, event.value["response_with_http_code"] exposes:

  • httpCode – transport status code;

  • Response – a public struct containing:

    • error: Int? — internal server error code (0 if no errors),

    • errorText: String? — error text (empty if no errors),

    • profile: ProfileData? — profile data if the request is successful:

      • profile info (ProfileData)
      • subscription (SubscriptionData)
      • subscription categories (CategoryData)
      • if the request fails, profile = null will be returned only
Data structures
public struct Response {
let error: Int? // Internal error code
let errorText: String? // Error text
let profile: ProfileData?
}

public struct ProfileData {
let subscription: SubscriptionData?
let cats: [CategoryData]?
}

public struct SubscriptionData {
// Subscription data
}

public struct CategoryData {
// Subscription category data
}
If sync == false
ResponseWithHttpCode
├─ httpCode: Int?
└─ response: Response?
├─ error: Int?
├─ errorText: String?
└─ profile: ProfileData? = null

For asynchronous requests, event.value["response_with_http_code"] exposes:

  • httpCode – transport status code;

  • Response – a public struct containing:

    • error: Int? — internal server error code (0 if no errors),
    • errorText: String? — error text (empty if no errors),
    • profile: ProfileData? — profile data, always null for async requests.

Failed request execution:

If a request from this group fails, an event with one of the following codes will be emitted:

  • 430 – error without automatic retry on the SDK side;
  • 530 – error with automatic retry on the SDK side.

Event contents:

  • only httpCode if the Altcraft server was unavailable;
  • error and errorText if the server returned an error.
Reading push event values
AltcraftSDK.eventSDKFunctions.subscribe { event ->
if (event.eventCode in listOf(230, 430, 530)) {
(event.eventValue?.get("response_with_http_code")
as? DataClasses.ResponseWithHttpCode)?.let { responseWithHttp ->
// HTTP code
val httpCode = responseWithHttp.httpCode

// Response
val response = responseWithHttp.response
val error = response?.error
val errorText = response?.errorText

// Profile
val profile = response?.profile
val profileId = profile?.id
val profileStatus = profile?.status
val profileIsTest = profile?.isTest

// Subscription
val subscription = profile?.subscription
val subscriptionId = subscription?.subscriptionId
val hashId = subscription?.hashId
val provider = subscription?.provider
val subscriptionStatus = subscription?.status

// Fields (Map<String, JsonElement>)
val fields = subscription?.fields

// Categories (List<CategoryData>)
val cats = subscription?.cats
val firstCat = cats?.firstOrNull()
val catName = firstCat?.name
val catTitle = firstCat?.title
val catSteady = firstCat?.steady
val catActive = firstCat?.active
}
}

profileFields:Map<String, Any?>?

Default: null
Required: No
Description: A map containing profile fields.

The parameter may include system fields (e.g., _fname — first name or _lname — last name) as well as optional fields (pre-created manually in the platform UI). Allowed JSON-compatible structures:

  • Scalar values:
    • String
    • Boolean
    • Int
    • Long
    • Float
    • Double
    • null
  • Objects: Map<String, *>
  • Lists: List<*>
  • Array of maps: Array<Map<String, *>>

If an invalid optional field is passed, the request will fail with:

SDK error: 430
http code: 400
error: 400
errorText: Platform profile processing error: with field "field_name": Incorrect field

customFields:Map<String, Any?>?

Default: null Required: No Description: A map containing subscription fields.

May include system fields (e.g., _device_model — device model or _os — operating system) as well as optional fields (pre-created manually in the platform UI). Allowed value types (JSON-compatible, scalars only):

  • String
  • Boolean
  • Int
  • Long
  • Float
  • Double
  • null

If an invalid optional field is passed, the request will fail with:

SDK error: 430
http code: 400
error: 400
errorText: Platform profile processing error: field "field_name" is not valid: failed convert custom field
Note

Most subscription system fields are collected automatically by the SDK and added to push requests. These include: "_os", "_os_tz", "_os_language", "_device_type", "_device_model", "_device_name", "_os_ver", "_ad_track", "_ad_id".


cats:listOf(CategoryData)

Default: null Required: No Description: Subscription categories.

Category structure:

data class CategoryData(
val name: String? = null,
val title: String? = null,
val steady: Boolean? = null,
val active: Boolean? = null
)

When sending a push request with categories, use only the name (category name) and active (category active status) fields; other fields are not used for request processing. title and steady are populated when retrieving subscription info.

Example:

val cats = listOf(
DataClasses.CategoryData(name = "football", active = true),
DataClasses.CategoryData(name = "hockey", active = true)
)

Categories used in the request must be created beforehand and added to the resource in the Altcraft platform. If a category not present in the resource is used, the request will fail:

SDK error: 430
http code: 400
error: 400
errorText: Platform profile processing error: field "subscriptions.cats" is not valid: category not found in resource

replace:Boolean?

Default: null Required: No Description: When enabled, all subscriptions of other profiles with the same push token in the current database are set to unsubscribed after a successful request.


skipTriggers:Boolean?

Default: null Required: No Description: When enabled, the profile containing this subscription will be ignored by campaign and scenario triggers.


Request implementation examples

Example: subscribing to push notifications

Minimal working setup:

AltcraftSDK.pushSubscriptionFunctions.pushSubscribe(context)

Passing all available parameters:

AltcraftSDK.pushSubscriptionFunctions.pushSubscribe(
context = this,
sync = true,
profileFields = mapOf("_fname" to "Andrey", "_lname" to "Pogodin"),
customFields = mapOf("developer" to true),
cats = listOf(DataClasses.CategoryData(name = "developer_news", active = true)),
replace = false,
skipTriggers = false
)
Note

For pushSubscribe, pushSuspend, and pushUnSubscribe, the SDK automatically retries the request if the HTTP status code is in 500..599. No retry occurs for codes outside this range.


Function unSuspendPushSubscription()

The function fun unSuspendPushSubscription() is intended to implement LogIn/LogOut transitions. It works as follows:

  • searches for subscriptions with the same push token as the current one that do not belong to the profile referenced by the current JWT token;
  • changes the status of the found subscriptions from subscribed to suspended;
  • changes the status of subscriptions in the profile referenced by the current JWT from suspended to subscribed (if the JWT-referenced profile exists and contains subscriptions);
  • returns a ResponseWithHttpCode? data class in which response.profile is the current profile referenced by the JWT (if the profile does not exist, response.profile will be null).
Recommended LogIn / LogOut implementation

LogIn transition:

  • An anonymous user enters the app. The user is assigned JWT_1, pointing to database #1Anonymous.
  • A push subscription is created; the profile is created in #1Anonymous.
  • The user registers and is assigned JWT_2, pointing to database #2Registered.
  • Call unSuspendPushSubscription() — the anonymous user’s subscription in #1Anonymous is suspended.
  • Search the profile in #2Registered to restore the subscription.
  • Since a subscription with this push token does not exist in #2Registered, unSuspendPushSubscription() returns null.
  • After receiving null, call pushSubscribe() to create a new profile in #2Registered.

LogOut transition:

  • The user logs out in the app (LogOut).
  • The user is assigned JTW_1, pointing to database #1Anonymous.
  • Call unSuspendPushSubscription(), which will suspend the subscription in #2Registered and set the subscription status in #1Anonymous to subscribed.
  • The request returns #1Anonymous != null — the subscription already exists; no new one is required.

Example:

private suspend fun unSuspend(context: Context, logIn: Boolean) {

// Change JWT before the request
setAuth(context, logIn)

AltcraftSDK.pushSubscriptionFunctions
.unSuspendPushSubscription(context)
?.let { result ->
if (result.httpCode == 200 && result.response?.profile?.subscription == null) {
AltcraftSDK.pushSubscriptionFunctions.pushSubscribe(
context = context
// Specify required params
)
}
}
}

fun logIn(context: Context) = CoroutineScope(Dispatchers.IO).launch { unSuspend(context, true) }
fun logOut(context: Context) = CoroutineScope(Dispatchers.IO).launch { unSuspend(context, false) }

Managing provider push tokens


AltcraftSDK
└── val pushTokenFunctions: PublicPushTokenFunctions
|
// Save a token manually (onNewToken)
├── fun setPushToken(context: Context, provider: String, token: String): Unit
|
// Get current device token data
├── suspend fun getPushToken(context: Context): DataClasses.TokenData?
|
// Set Firebase Cloud Messaging provider (null — remove)
├── fun setFCMTokenProvider(provider: FCMInterface?): Unit
|
// Set Huawei Mobile Services provider (null — remove)
├── fun setHMSTokenProvider(provider: HMSInterface?): Unit
|
// Set RuStore provider (null — remove)
├── fun setRuStoreTokenProvider(provider: RustoreInterface?): Unit
|
// Delete the push token for the specified provider
├── suspend fun deleteDeviceToken(context: Context, provider: String, complete: () -> Unit): Unit
|
// Force token refresh (delete → refresh)
├── fun forcedTokenUpdate(context: Context, complete: () -> Unit): Unit
|
// Change provider priority list and trigger token refresh
└── suspend fun changePushProviderPriorityList(context: Context, priorityList: List<String>): Unit

SDK functions for working with a provider token:

  • fun setPushToken() — manually set the device push token and provider in UserDefaults;
  • fun getPushToken() — get the current push token;
  • fun setFCMTokenProvider() — set or clear the FCM push token;
  • fun setHMSTokenProvider() — set or clear the HMS push token;
  • fun setRuStoreTokenProvider() — set or clear the RuStore push token;
  • fun changePushProviderPriorityList() — dynamically switch provider and refresh the subscription’s push token;
  • fun deleteDeviceToken() — delete the push token of the specified provider;
  • fun forcedTokenUpdate() — delete the current push token and then refresh it.

fun setPushToken(context: Context, provider: String, token: String): Unit

Used to manually set the device push token and provider. Should be called in the push provider service’s onNewToken(). Serves as a simplified way to pass the token to the SDK without implementing provider interfaces.

Using this function to pass the token is not recommended. The recommended approach is to implement FCMInterface, HMSInterface, or APNSInterface.

Usage example:

// Manually save the token (onNewToken)
AltcraftSDK.pushTokenFunctions.setPushToken(context, provider, token)

Passing a token in FCMService.onNewToken():

class FCMService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)

// Pass the new token manually
AltcraftSDK.pushTokenFunctions.setPushToken(this, FCM_PROVIDER, token)
}

override fun onDeletedMessages() {}

override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
AltcraftSDK.PushReceiver.takePush(this@FCMService, message.data)
}
}

suspend fun getPushToken(context: Context): DataClasses.TokenData?

The function returns the current device push-token data and its provider as the data class TokenData(val provider: String, val token: String). If the token is unavailable, null will be returned.

Usage example:

// Get current push token data
AltcraftSDK.pushTokenFunctions.getPushToken(context)

Example of a push token data request:

CoroutineScope(Dispatchers.IO).launch {
AltcraftSDK.pushTokenFunctions.getPushToken(context).let {
val provider = it?.provider
val token = it?.token
}
}

fun setFCMTokenProvider(provider: FCMInterface?): Unit

Sets or removes the Firebase Cloud Messaging push-token provider. To disable the provider, pass null.

Usage example:

// Set Firebase Cloud Messaging provider (null — remove)
AltcraftSDK.pushTokenFunctions.setFCMTokenProvider(FCMProvider())
Important

Call setFCMTokenProvider() in Application.onCreate() before calling AltcraftSDK.initialization(). This guarantees registration at the start of the app process, regardless of the lifecycle state and whether the app is running in the foreground or background.


fun setHMSTokenProvider(provider: HMSInterface?): Unit

Sets or removes the Huawei Mobile Services push-token provider. To disable the provider, pass null.

Usage example:

// Set Huawei Mobile Services provider (null — remove)
AltcraftSDK.pushTokenFunctions.setHMSTokenProvider(HMSProvider())
Important

Call setHMSTokenProvider() in Application.onCreate() before calling AltcraftSDK.initialization(). This guarantees registration at the start of the app process, regardless of the lifecycle state and whether the app is running in the foreground or background.


fun setRuStoreTokenProvider(provider: RustoreInterface?): Unit

Sets or removes the RuStore push-token provider. To disable the provider, pass null.

Usage example:

// Set RuStore provider (null — remove)
AltcraftSDK.pushTokenFunctions.setRustoreTokenProvider(RustoreProvider())
Important

Call setRustoreTokenProvider() in Application.onCreate() before calling AltcraftSDK.initialization(). This guarantees registration at the start of the app process, regardless of the lifecycle state and whether the app is running in the foreground or background.


suspend fun changePushProviderPriorityList(context: Context, priorityList: List<String>): Unit

Allows dynamic switching of the push provider with subscription token refresh. Pass a new list with a different provider order, for example: listOf(HMS_PROVIDER, RUSTORE_PROVIDER, FCM_PROVIDER).

// Apply a new provider priority list and trigger token refresh
AltcraftSDK.pushTokenFunctions.changePushProviderPriorityList(context, listOf(HMS_PROVIDER, RUSTORE_PROVIDER, FCM_PROVIDER))

suspend fun deleteDeviceToken(context: Context, provider: String, complete: () -> Unit): Unit

Deletes the push token for the specified provider. The token is invalidated and removed from the device’s local cache and from the push-provider’s server. After deletion, a new token can be requested.

// Delete the push token for the given provider (invalidate locally and on the server)
AltcraftSDK.pushTokenFunctions.deleteDeviceToken(context, provider) {
// callback after deletion
}

fun forcedTokenUpdate(context: Context, complete: () -> Unit): Unit

Deletes the current push token and then refreshes it.

Usage example:

// Force token refresh (delete → update)
AltcraftSDK.pushTokenFunctions.forcedTokenUpdate(context) {
// callback after update
}

Example of provider registration

We do not recommend using the setPushToken function to set a push token manually. Instead, configure token retrieval functions separately for each provider you use. Below is an example implementation of this approach:

Recommended provider registration method
class App : Application() {
override fun onCreate() {
super.onCreate()

// initialize RuStore provider
RuStorePushClient.init(this, "rustore project id")

// set JWT provider
AltcraftSDK.setJWTProvider(JWTProvider(applicationContext))

// set FCM provider
AltcraftSDK.pushTokenFunctions.setFCMTokenProvider(FCMProvider())

// set HMS provider
AltcraftSDK.pushTokenFunctions.setHMSTokenProvider(HMSProvider())

// set RuStore provider
AltcraftSDK.pushTokenFunctions.setRuStoreTokenProvider(RuStoreProvider())

// create AltcraftConfiguration
val config = AltcraftConfiguration.Builder(
apiUrl = "your api url",
R.drawable.ic_altcraft_label
).build()

// initialize SDK
AltcraftSDK.initialization(context = this@App, configuration = config)
}
}

Passing push notifications to the SDK


PushReceiver is a public class that contains the function that accepts notifications.

AltcraftSDK
└── open class PushReceiver
// Incoming push handling
├── open fun pushHandler(
│ context: Context,
│ message: Map<String, String>
): Unit
// SDK entry point for push delivery
└── companion object
└── fun takePush(
context: Context,
message: Map<String, String>
): Unit

Functions for passing push notifications to the SDK:

  • fun takePush() — accepts notifications in the push providers’ service for further processing on the SDK side;
  • fun pushHandler() — launches the standard Altcraft push-notification handling mechanism in the SDK.

Receiving a notification

fun takePush(context: Context, message: Map<String, String>): Unit

Accepts push notifications for further processing on the SDK side.

Usage example:

   override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)

AltcraftSDK.PushReceiver.takePush(this@FCMService, message.data)
}
// message.data — message payload

Handling a notification

open fun pushHandler(context: Context, message: Map<String, String>): Unit

Starts the standard Altcraft push-notification handling mechanism in the SDK.


Receiving notifications in any app package (optional)

To receive notifications in any application package, do the following:

Step 1. Create an AltcraftPushReceiver class extending PushReceiver. Override the pushHandler() function in this class:

import android.content.Context
import androidx.annotation.Keep
import com.altcraft.sdk.AltcraftSDK

@Keep
class AltcraftPushReceiver : AltcraftSDK.PushReceiver() {
override fun pushHandler(context: Context, message: Map<String, String>) {
// standard processing of push messages and displaying notifications
super.pushHandler(context, message)
}
}
Note

The class must be named AltcraftPushReceiver. If you name it differently, the SDK will not be able to find it to deliver the notification.


Step 2. Depending on your business goals, configure the logic of the AltcraftPushReceiver class:

  • If you want the SDK to handle and display notifications:

    • use super.pushHandler(context, message).
  • If you want to handle notifications yourself:

    • do not call super.pushHandler();
    • manually register open events using the openEvent() function; otherwise, it will not be registered by the Altcraft platform.

“deliveryEvent” delivery events are registered automatically. Creating AltcraftPushReceiver classes does not affect the registration of this event.

Note

If you created multiple AltcraftPushReceiver classes, calling super.pushHandler() in each of them will display a message to the user. To avoid duplicate notifications, call super.pushHandler() in only one class.


Step 3. Add the package names that contain AltcraftPushReceiver classes to the pushReceiverModules configuration parameter. After that, the SDK will automatically detect the presence of AltcraftPushReceiver classes in the specified packages via reflection.

If the application code will be obfuscated, the class must be annotated with @Keep or added to the R8/ProGuard rules, otherwise the SDK will not be able to discover it.

Example of adding a package to the pushReceiverModules parameter:

pushReceiverModules = listOf(
context.packageName, // application package
"com.altcraft.altcraftmobile.test"
)

Mobile Events

// Function of the PublicMobileEventFunction object

AltcraftSDK
└── val mobileEventFunction: PublicMobileEventFunction

// Send a mobile event to the server
└── 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: DataClasses.Subscription? = null,
utm: DataClasses.UTM? = null
): Unit

To register a mobile event, use the mobileEvent() function. It has the following parameters:


context: Context

Required: Yes
Description: Android Context.


sid: String

Required: Yes
Description: String identifier of the pixel to which mobile events are linked.


eventName: String

Required: Yes
Description: The name of the mobile event.


sendMessageId: String?

Required: No
Description: SMID identifier of the sent message (if the event is associated with a specific campaign).


payload: String

Required: No
Description: Event data — a map with string keys and values, where only scalar data types are allowed:

  • String
  • Boolean
  • Int
  • Long
  • Float
  • Double
  • null

matching: Map<String, Any?>?

Required: No
Description: A map for passing values with matching types and identifiers.


matchingType: String?

Required: No
Description: The type of matching.


profileFields: Map<String, Any?>?

Required: No
Description: Profile fields — a map with string keys and JSON-compatible values:

  • Scalar values:

    • String
    • Boolean
    • Int
    • Long
    • Float
    • Double
    • null
  • Objects: Map<String, *>

  • Lists: List<*>

  • Arrays of maps: Array<Map<String, *>>

Note

This parameter is used only when working with JWT authorization.



utm: DataClasses.UTM?

Required: No
Description: UTM tags. Added using the UTM data class, where each UTM type is a separate parameter.

data class UTM (
val campaign: String? = null,
val content: String? = null,
val keyword: String? = null,
val medium: String? = null,
val source: String? = null,
val temp: String? = null
)


subscription: DataClasses.Subscription?

Required: No
Description: Parameter for adding a subscription for a selected channel.

Possible values are implementations (subtypes) of the sealed interface Subscription:

  • EmailSubscription — email subscription
  • SmsSubscription — SMS subscription
  • PushSubscription — push subscription
  • CcDataSubscription — subscription in Telegram, WhatsApp, Viber, or Notify.
Note

Used only when working with JWT authorization.



Implementations of the Subscription interface

General model: Subscription

Purpose — base (sealed) interface for all types of subscriptions. Serialization is polymorphic, with the discriminator field channel.

Common fields (for all implementations):

FieldTypeRequiredDescription
resource_idIntYesIdentifier of the subscription resource/source
statusString?NoSubscription status (e.g., active/suspended)
priorityInt?NoDelivery priority for the subscription
custom_fieldsMap<String, Any?>?NoCustom fields (key–value) for extended segmentation
catsList<String>?NoSubscription categories
channelStringYesChannel type; defined by the implementation


Subscription types:


1. Email channel subscription

EmailSubscription (channel = "email")

Additional fields:

FieldTypeRequiredDescription
emailStringYesRecipient email address

Notes: channel is always "email".


2. SMS channel subscription

SmsSubscription (channel = "sms")

Purpose: subscription to the SMS channel.

Additional fields:

FieldTypeRequiredDescription
phoneStringYesPhone number in international format

Notes: channel is always "sms".


3. Push notification subscription

PushSubscription (channel = "push")

Additional fields:

FieldTypeRequiredDescription
providerStringYesProvider (e.g., "android-firebase", etc.)
subscription_idStringYesUnique provider subscription identifier

Notes: channel is always "push".


4. Subscription for custom communication channels

CcDataSubscription (channel ∈ {"telegram_bot","whatsapp","viber","notify"})

Additional fields:

FieldTypeRequiredDescription
channelStringYesOne of: "telegram_bot", "whatsapp", "viber", "notify".
cc_dataJsonObjectYesChannel-specific data (e.g., chat ID, phone number, tokens).

Notes: channel must explicitly match one of the supported values.


Receiving SDK Events in the Application


// Functions of the Events object

AltcraftSDK
└── val eventSDKFunctions: Events
// Subscribe to SDK events (replaces the existing subscriber)
├── fun subscribe(
│ newSubscriber: (DataClasses.Event) -> Unit
): Unit
// Unsubscribe from events
└── fun unsubscribe(): Unit

The application can have only one active subscriber to SDK events.


Event Subscription

fun subscribe(newSubscriber: (DataClasses.Event) -> Unit): Unit

Used to subscribe and receive SDK events in the application. When an SDK event occurs, it calls the callback and passes an instance of the Event class (or one of its subclasses).

Usage example:

AltcraftSDK.eventSDKFunctions.subscribe { event ->
// Handle event
}

All events provided by the SDK are instances of Event or its subclasses:

  • Event — general event (info, successful requests);
  • Error — error event;
  • RetryError — error event for a request that will be automatically retried by the SDK.

Each event contains the following fields:

  • function — the name of the function that triggered the event;
  • eventCode — internal SDK event code (see "SDK Events");
  • eventMessage — event message;
  • eventValue — arbitrary [String: Any?]? data passed as event payload;
  • date — timestamp of the event.
SDK Events
open class Event(
val function: String,
val eventCode: Int? = null,
val eventMessage: String? = null,
val eventValue: Map<String, Any?>? = null,
val date: Date = Date(),
)

open class Error(
function: String,
eventCode: Int? = 0,
eventMessage: String? = null,
eventValue: Map<String, Any?>? = null,
date: Date = Date(),
) : Event(function, eventCode, eventMessage, eventValue, date)

class RetryError(
function: String,
eventCode: Int? = 0,
eventMessage: String? = null,
eventValue: Map<String, Any?>? = null,
date: Date = Date(),
) : Error(function, eventCode, eventMessage, eventValue, date)
Example of a successful push subscription event
├─ function: processResponseprocessResponse
├─ eventCode: 230
├─ eventMessage: "successful request: push/subscribe"
├─ eventValue
│ ├─ http code: 200
│ └─ response
│ ├─ error: 0
│ ├─ errorText: ""
│ └─ profile
│ ├─ id: "your id"
│ ├─ status: "subscribed"
│ ├─ isTest: false
│ └─ subscription
│ ├─ subscriptionId: "your subscriptionId"
│ ├─ hashId: "c52b28d2"
│ ├─ provider: "android-firebase"
│ ├─ status: "subscribed"
│ ├─ fields
│ │ ├─ _device_name: "Pixel 7"
│ │ ├─ _device_model: "Google Pixel 7"
│ │ ├─ _os_tz: "+0300"
│ │ ├─ _os_language: "ru"
│ │ ├─ _os_ver: {"raw":"14","ver":[14]}
│ │ ├─ _ad_track: true
│ │ ├─ _os: "Android"
│ │ └─ _device_type: "Mobile"
│ └─ cats
│ └─ [ { name: "developer_news", title: "dev_news", steady: false, active: false } ]
└─ date: 2025-09-03 09:01:44 +0000

Unsubscribing from events

fun unsubscribe(): Unit

This function unsubscribes from SDK events. It stops event delivery while keeping the callback assigned.

Usage example:

// Unsubscribe from SDK events
AltcraftSDK.eventSDKFunctions.unsubscribe()

Additional SDK Functions


Manual Push Event Registration

Note

These functions are only used if you implement your own notification handling logic and do not pass them to the Altcraft SDK. By default, the Altcraft SDK automatically processes notifications, so these methods are only required when you need custom client-side handling.

// Functions of the PublicPushEventFunctions object

AltcraftSDK
└── val pushEventFunction: PublicPushEventFunctions

// Register Altcraft push delivery (triggers delivery event)
├── fun deliveryEvent(
│ context: Context,
│ message: Map<String, String>? = null,
│ uid: String? = null
): Unit

// Register Altcraft push open (triggers open event)
└── fun openEvent(
context: Context,
message: Map<String, String>? = null,
uid: String? = null
): Unit

Manual event registration functions:

  • fun deliveryEvent() — registers push delivery;
  • fun openEvent() — registers push open.

fun deliveryEvent(context: Context, message: Map<String, String>? = null, uid: String? = null): Unit

Registers a push delivery event manually on the Altcraft platform. To log the event on the server, pass the notification data in the message or uid parameter.

Usage example:

// Register Altcraft push delivery (triggers delivery event)
AltcraftSDK.pushEventFunction.deliveryEvent(context, message, uid)

fun openEvent(context: Context, message: Map<String, String>? = null, uid: String? = null): Unit

Registers a push open event manually on the Altcraft platform. To log the event on the server, pass the notification data in the message or uid parameter.

Usage example:

// Register Altcraft push open (triggers open event)
AltcraftSDK.pushEventFunction.openEvent(context, message, uid)

SDK Data Clearing

fun clear(context: Context, onComplete: (() -> Unit)? = null)

This function clears all SDK data and cancels all pending background tasks. It cancels WorkManager jobs, deletes Room database entries, and clears SharedPreferences.

Usage example:

AltcraftSDK
// Full SDK data cleanup (DB, SharedPreferences, background tasks)
└── fun clear(
context: Context,
onComplete: (() -> Unit)? = null
): Unit

The function includes an optional completion parameter, which is called after cleanup and task cancellation are complete.


Functional Profile Field Update

AltcraftSDK
└─ val pushSubscriptionFunctions: PublicPushSubscriptionFunctions
└─ fun actionField(key: String): ActionFieldBuilder

fun actionField(key: String): ActionFieldBuilder

A helper function for simplifying the functional profile field update process. It supports the following operations:

    .set(value)
.unset(value)
.incr(value)
.add(value)
.delete(value)
.upsert(value)

Usage example:

AltcraftSDK.pushSubscriptionFunctions.pushSubscribe(
context = context,
// "_fname" — field to be changed
// .set("Andrey") — command that sets the value "Andrey" for this field
profileFields = AltcraftSDK.pushSubscriptionFunctions
.actionField("_fname").set("Andrey")
)

Resetting the performPushModuleCheck() Restriction

Note

The performPushModuleCheck() function runs background jobs that handle push-notification-related retries and device token refresh requests. Its execution is limited to a single run within one application process lifecycle.

Sometimes, you may need to reset this restriction. In such cases, use the function described below.

fun reinitializePushModuleInThisSession(): Unit

This function resets the flag preventing repeated execution of performPushModuleCheck().


Requesting Notification Permission

Note

Starting from Android 13 (API 33, Tiramisu), apps must explicitly request the POST_NOTIFICATIONS permission before sending notifications. On earlier Android versions, this call is not required — the permission is granted automatically.

fun requestNotificationPermission(context: Context, activity: ComponentActivity)

Checks the current notification permission status and, if necessary, displays the system permission request dialog to the user. If the user has previously denied notifications, calling this function again will re-prompt the permission dialog.