benshi.ai SDK

benshi.ai Android SDK

Benshi Android SDK Setup

This documentation covers the steps to integrating SDK in your android apps. We’ll also discuss a few fundamentals of how the dashboard works in tandem with your app usage to view your users and engage them with contextually personalized messages.

There are two types of data we collect from the partner's side:

  1. content data (static content / items in the app)
  2. event data (event names, event details)

item data are static data of certain items (e.g. video, audio, a product, etc.). Event data is time-series data generated by the user.

Getting Started

The easiest way to integrate Benshi Android SDK in your Android project is with Maven Central. Add dependencies of Benshi Android SDK and Android Lifecycle Components in the app/build.gradle file.

dependencies {
// Benshi SDK
implementation 'ai.benshi.android.sdk:1.0.0'

//LifecycleComponents
implementation 'androidx.lifecycle:lifecycle-process:2.3.1'
}

Lifecycle components are required, if you already have them in your project you may skip them.

Initialization

Create an Application class in your project and include LifecycleObserver Components. Initialize Android SDK with your SDK Token from onCreate callback of your Application class as shown below.

class MyApplication : Application(), LifecycleObserver {

    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get()
            .lifecycle.addObserver(this) // to observe Application lifecycle events

        BenshiLog.init(applicationContext, appSDKToken) //init SDK with your SDK token
        registerActivityLifecycleCallbacks(AppLifecycleTracker(applicationContext))

    }
}

/*
In onAppStop() function include the following function to dispatch WorkManager to update app events collected offline or isUpdateImmediately false
*/

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onAppStop() {
        BenshiLog.updateAppEvents(applicationContext) //this line
    }

Benshi Android SDK also allows you to update track events after the user’s usage session is over. SDK sends the events whenever the app goes into background. This helps in not overloading the user’s phone while in use. SDK handles the events even in offline mode and ensures that they get uploaded to the portal whenever the user connects to the internet.

Don't forget to include android:name=".MyApplication" in your manifest's application tag.

Add the following broadcast receivers in your app's manifest to listen for the app connectivity change and nudge feedback (opened/dismissed).

<receiver android:name="ai.benshi.android.benshi_ingest.nudge.NudgeActionReceiver" />
<receiver android:name="ai.benshi.android.benshi_ingest.nudge.NotificationOnCancelBroadcastReceiver" />
<receiver android:name="ai.benshi.android.benshi_ingest.nudge.NotificationOnClickBroadcastReceiver" />
<receiver android:name="ai.benshi.android.benshi_ingest.nudge.GetNotificationService">
    <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>

Android SDK - Event Tracking

Benshi Android SDK automatically starts tracking user data (e.g., Upload/download speed, OS version, device IDs) and engagement with the basic setup above. This data can be stored on the device and uploaded in batches to reduce network and power usage, and to increase the likelihood of successful uploads while you can also upload the events as soon as they happen. The upload is done when the user device session ends. SDK also starts tracking user sessions with this basic setup.

Each event can further be understood in the context of its attributes which includes details like time, upload/download speed, device details, locale, online/offline usage, screen time, interactions and so on. This enables you to gain in-depth insights into user interactions across your app. You can also leverage this data to segment users, personalize messages and configure campaign targeting.

Let’s take a look at the general structure of the attributes sent using that SDK:

Property NameReported on PortalDescription
User Idu_idUser Id assigned in your Database, if you don’t have any signup/login process SDK defaults that to deviceID
Device Idd_idUser’s Device ID to uniquely recognise them
OSosThe current OS they are using. It is specified in {os.Name (os.Version)} e.g. android (30) Having the device OS and version help us to deliver content better presentable on their device.
SDK Versionsdk_verCurrent SDK version you are using.
Online StatusonlineTracks if the device was online or not when the event was recorded.
TimestamptsTrack the timestamp of the event in RFC 3339 format
Upload SpeedupTrack the upload speed of the device when the event was recorded
Download SpeeddownTrack the download speed of the device when the event was recorded
Event TypetypeType of event being tracked, use EventType class predefined events
Event NamenameName of the event you are tracking
PropertiespropsProperties of the event being tracked. SDK provides predefined property models for you to integrate with ease. You can also track custom events too.

For example, if a user needs to click on a product to view its details, then it is advisable to track this action as the event, product viewed as it brings them a step closer to making a purchase.

SDK events are divided into 3 main categories: User Events, System Events and Custom Events.

Tracking User Events

SDK automatically starts detecting the users across your platforms as soon as they're integrated. These visitors are classified as Unknown Users and Known Users.

Let's walk you through this:

Unknown Users

Each time a new user uses your app, they are tracked as anonymous users in your dashboard and an Unknown User Profile is created for them. The Android SDK automatically assigns them a unique ID (based on their device ID) and starts populating their user profile with all their data (System Events, Custom Events).

Known Users (Identity Events)

As and when the users share details that help you identify them in your platform, you can assign them a unique ID (Your Platform based UserId) to track them as Known Users. This user is now stored in our database as the ‘Identified/Registered’ ones. A new user profile is created for them that contains all their data from the previous anonymous user profiles, too merged with the new account. You can optionally include Personally identifiable information (PII) for them in order to get more personalized results.

Known users have some user attributes as data points that paint a complete picture of who your user is, where they're from, what they do, and much more, depending on your business. Such granular user data enables you to segment them into contextually relevant segments and personalize experience through all the channels of engagement (nudges). We have predefined several generic user details that all digital businesses can track for their users. These details are referred to as Known User Attributes include information like the user's name, Date of Birth, country, and so on. Here's a list of all of these attributes you can use to set:

Identity EventsData TypeWhat it Tracks
firstNameStringFirst Name
lastNameStringLast Name
emailStringEmail ID
phoneStringPhone number, as shared by the user. eg. +551166259345, +917874060978
countryStringCountry
regionStateStringRegion or State
districtStringDistrict
cityStringCity
dateOfBirthStringBirth date in YYYY-MM-DD format
genderStringGender which can be one of male/ female/ other
metaAnyUsed to include any other event related data, can be an object, string or number.

Image1

Implementation

To Log identity events which involves events regarding the user of the app: signup, login or update user profile use: EventType.identify Identity log events are divided into 3 different types. For convenience, you can use IdentityType.{event name} in the log function. examples are:

  • IdentifyType.register for new user (signup)
  • IdentifyType.login for login (sign in)
  • IdentifyType.update for updating user Profile (User Model)

SDK also provides a model/data class for the logging events in the required format.

val userObjectSDK = UserRegisterObject(
            userId, //String
            firstName, //String
            lastName, //String
            email, //String
            phone, //String
            country, //String
            region, //String
            district, //String
            city, //String
            dateOfBirth, //String
            gender, //String
            meta //Any [obj

You can integrate SDK using 2 methods:

/*
Using function pattern, make sure to call `updateUserId` function before identity to update user id for logs
*/

BenshiLog.updateUserId(
    appSDKToken, // Required  - String - Token
    userId, // Required  - String
    context //Required - Context
    )

BenshiLog.track(
    context //Required - Context
    EventType.identify, // Required
    IdentifyType.register.name, // Required
    userRegisterObject // Optional  - UserRegisterObject
    )

/*
Using the Builder pattern, you don't need to call the `updateUserId` function as SDK will manage that.
*/

BenshiLogIdentifyEvent.Builder()
    .init(this) //Required -  Context
    .setAppSdkToken(appSDKToken) //Required - String
    .setAppUserId(userId) //Required String
    .setIdentifyType(IdentifyType.register) //Required
    .setEmail(email) //Optional - String
    .setFirstName(firstName) //Optional - String
    .setLastName(lastName) //Optional - String
    .setDateOfBirth(dateOfBirth) //Optional - String - Format[year-month-day, 1980-02-09]
    .setPhone(phone) //Optional - String
    .setCountry(country) //Optional - String
    .setRegionState(region) //Optional - String
    .setCity(city) //Optional - String
    .setDistrict(district) //Optional - String
    .setGender(gender)) //Optional - String
    .setMeta(meta) //Optional - Any [object, string, int]
    .build()

/*
You can also set use the Log event as:
*/

BenshiLogIdentifyEvent.Builder()
    .init(this) //Required -  Context
    .setAppSdkToken(appSDKToken) //Required - String
    .setAppUserId(userId) //Required String
    .setIdentifyType(IdentifyType.register) //Required
    .setUserRegisterObject(userObjectSDK) //Optional - UserRegisterObject
    .setMeta(meta) //Optional - Any [object, string, int]
    .build()


For updating user profile you can use the same identity event above but with IdentifyType.update

For Login event you can integrate any of the 2 ways:

/*
Using function pattern, make sure to call `updateUserId` function before identity to update user id for logs
*/

BenshiLog.updateUserId(appSDKToken, userId, this)
BenshiLog.track(this, EventType.identify, IdentifyType.login.name, null)


/*
Using the Builder pattern, you don't need to call the `updateUserId` function as SDK will manage that.
*/

BenshiLogIdentifyEvent.Builder()
    .init(this) //Required -  Context
    .setAppSdkToken(appSDKToken) //Required - String
    .setAppUserId(userId) //Required - String
    .setIdentifyType(IdentifyType.login) //Required
    .build()

Make sure to use IdentifyType.login for login identity event.

Tracking System Events

We have pre-defined several generic actions that users can perform while interacting with your app. These actions are referred to as System Events that help in tracking elements on your app with user interaction. Some of these events are automated so that you don’t have to spend time integrating them.

Here's a list of System Events that can be tracked using predefined models for all your users:

Event NameCalling in SDKDescription
PageEventType.pageTrack screen/activity changes and session timing. (Auto Tracked)
LevelEventType.levelTrack user experience
AttemptEventType.attemptTrack user attempts to complete a task
AwardEventType.awardTrack is user is awarded in the app
PurchaseEventType.purchaseTrack in-App purchases
ScrollEventType.scrollTrack scroll ratio and session length to know what interests them the most
MessageEventType.messageTrack any message shown to the user to design more interactive campaigns
MessageActionEventType.message_actionTrack how the user responded to your campaigns
MediaEventType.mediaTrack how your users interact with media to offer better

SDK provides 2 ways to integrate System Events into your app. You can follow the function based approach where you need to include predefined models for event tracking or you can also use the builder pattern approach that will do the model mapping work for you.

Examples for above mentioned events with both approaches are given below:

Page Event

To Log page/screen change events you can use: EventType.page

By default SDK auto listens for Screen/Activity/Page changes in the app along with session timings that implicates how log a user spends on an activity but you can also log any specific event you want to track using below 2 approaches:

/*
Using function pattern, make sure to use the SDK defined `PageObject` for mapping elements.
*/

val pageObject = PageObject(
    activity.packageName, // Required - String
    activity.localClassName, // Required - String
    duration, // Required - Double - Time in Nanoseconds user spend on that screen/activity/page
    meta, //Optional - Any [object, String, Int]
    )

BenshiLog.track(
    context, // Required - Context
    EventType.page, // Required
    activity.localClassName, // Required - String
    pageObject, // Required
    updateImmediately = false // Optional
    )

/*
Using the Builder pattern, you don't need to use the `PageObject` function as SDK will manage that.
*/

BenshiLogPageEvent.Builder()
    .init(context) //Required -  Context
    .setPageName(activity.localClassName) // Required - String
    .setPath(activity.packageName) // Required - String
    .setTitle(activity.localClassName) // Required - String
    .setDuration(sessionLength.toDouble()) // Required - Double - Time in Nanoseconds, user spend on that screen/activity/page
    .updateImmediately(false) //Optional - Boolean
    .setMeta(meta) //Optional - Any [object, String, Int]
    .build()

updateImmediately is default set to true, you can use that to log events when the app goes in background or closed.

Level Events

To Log Level change events you can use: EventType.level

/*
Using function pattern, make sure to use the SDK defined `LevelObject` for mapping elements.
*/

val levelObject = LevelObject(
    levelNumber, //Required - Int
    meta //Optional - Any [object, String, Int]
    )

BenshiLog.track(
    context, //Required -  Context
    EventType.level, //Required
    eventName, //Required -  String
    levelObject //Required,
    )

/*
Using the Builder pattern, you don't need to use the `LevelObject` function as SDK will manage that.
*/

BenshiLogLevelEvent.Builder()
    .init(context) //Required -  Context
    .setLevelName(levelName) // Required - String
    .setLevelNumber(levelNumber) // Required - Int
    .setTitle(activity.localClassName) // Required - String
    .setMeta(meta) //Optional - Any [object, String, Int]
    .updateImmediately(false) //Optional - Boolean
    .build()

updateImmediately is default set to true, you can use that to log events when the app goes in background or closed.

Attempt Events

To Log User Attempt events you can use: EventType.attempt

/*
Using function pattern, make sure to use the SDK defined `AttemptObject` for mapping elements.
*/
val attemptObject = AttemptObject(
    awardID, //Required - String
    success, //Required - Boolean
    meta //Optional - Any [object, String, Int]
    )

 BenshiLog.track(
    context, //Required -  Context
    EventType.attempt, //Required
    eventName, //Required - String
    attemptObject //Required
    )

/*
Using the Builder pattern, you don't need to use the `AttemptObject` function as SDK will manage that.
*/

BenshiLogAttemptEvent.Builder()
    .init(context) //Required -  Context
    .setAttemptName(attemptName) // Required - String
    .setAwardId(awardId) // Required - String
    .setSuccess(isSuccessful) // Required - Boolean
    .setMeta(meta) //Optional - Any [object, String, Int]
    .updateImmediately(false) //Optional - Boolean
    .build()

updateImmediately is default set to true, you can use that to log events when the app goes in background or closed.

Award Events

To Log User Attempt events you can use: EventType.award

/*
Using function pattern, make sure to use the SDK defined `AwardObject` for mapping elements.
*/

val awardObject = AwardObject(
    awardID, //Required - String
    meta //Optional - Any [object, String, Int]
    )

 BenshiLog.track(
    context, //Required -  Context
    EventType.award, //Required
    eventName, //Required - String
    awardObject //Required
    )

/*
Using the Builder pattern, you don't need to use the `AttemptObject` function as SDK will manage that.
*/

BenshiLogAwardEvent.Builder()
    .init(context) //Required -  Context
    .setAwardName(awardName) // Required - String
    .setAwardId(awardId) // Required - String
    .setMeta(meta) //Optional - Any [object, String, Int]
    .updateImmediately(false) //Optional - Boolean
    .build()

updateImmediately is default set to true, you can use that to log events when the app goes in background or closed.

Purchase Events

To Log User Purchase (In-app or Custom) events you can use: EventType.purchase

/*
Using function pattern, make sure to use the SDK defined `PurchaseObject` for mapping elements.
*/
 val purchaseObject = PurchaseObject(
    price, //Required - Double
    currency, //Required - String
    purchaseId, //Required - String
    meta //Optional - Any [object, String, Int]
    )

BenshiLog.track(
    context, //Required -  Context
    EventType.purchase, //Required
    eventName, //Required - String
    purchaseObject //Required
)


/*
Using the Builder pattern, you don't need to use the `PurchaseObject` function as SDK will manage that.
*/

BenshiLogPurchaseEvent.Builder()
    .init(context) //Required -  Context
    .setItemName(purchaseItemName) // Required - String
    .setPrice(price) // Required - Double
    .setCurrency(currency) // Required - String
    .setItemId(itemId) // Required - String
    .setMeta(meta) //Optional - Any [object, String, Int]
    .updateImmediately(false) //Optional - Boolean
    .build()

updateImmediately is default set to true, you can use that to log events when the app goes in background or closed.

Scroll Events

To Log User Scroll events you can use: EventType.scroll

Scroll events can be used with a scroll view, SDK provides methods to get scrollview content percentages that are currently visible to the user. You also need to get the session time (in nanoseconds) the user stayed on a specific screen. To get Scroll Percentages you can use the SDK provided Utility method ScrollUtil.getScrollViewPercentageInt by just passing the scrollview itself.

For a detail preview on using scroll event, you can view ArticleActivity in the demo app

val startScroll = ScrollUtil.getScrollViewPercentageInt(articleScrollView, //Required - scrollView
isStartScrollValue // Required - Boolean (For starting point set to 'true')
)

val endScroll = ScrollUtil.getScrollViewPercentageInt(articleScrollView, //Required - scrollView
isStartScrollValue // Required - Boolean (For end point set to 'false')
)


/*
Using function pattern, make sure to use the SDK defined `ScrollObject` for mapping elements.
*/

val scrollObject = ScrollObject(
    startScroll.toDouble(), //Required - Double
    endScroll.toDouble(), //Required - Double
    sessionLength.toDouble() //Required - Double - Time in nanoseconds
    )

BenshiLog.track(
    context, //Required -  Context
    EventType.scroll, //Required
    eventName, //Required - String
    scrollObject, //Required
    updateImmediately = false // Optional - Boolean
    )

/*
Using the Builder pattern, you don't need to use the `ScrollObject` function as SDK will manage that.
*/

BenshiLogScrollEvent.Builder()
    .init(context) //Required -  Context
    .setEventName(eventName) // Required - String
    .setStartPercentage(startScroll) // Required - Double
    .setEndPercentage(endScroll) // Required - Double
    .setDuration(sessionLength) // Required - Double
    .setMeta(meta) //Optional - Any [object, String, Int]
    .updateImmediately(false) //Optional - Boolean
    .build()


updateImmediately is default set to true, you can use that to log events when the app goes in background or closed.

Message Events

To Log User Message events you can use: EventType.message

Message events can be used when you show any particular message to a user, a notification or an in-app message. For SDK fired nudges/in-app messages, you don't need to log this event as SDK will manage that itself.

/*
Using function pattern, make sure to use the SDK defined `MessageObject` for mapping elements.
*/

val messageObject = MessageObject(
    notificationId, //Required - String
    MessageType.push, //Required - MessageType.push, MessageType.in_app
    title, //Required - String
    content, //Required - String
    "en", //Required - String - Language
    messageActionList //Optional - ArrayList<MessageActionObject>
    )

BenshiLog.track(
    context, //Required -  Context
    EventType.message, //Required
    eventName, //Required - String
    messageObject //Required
    )


/*
Using the Builder pattern, you don't need to use the `MessageObject` function as SDK will manage that.
*/

BenshiLogMessageEvent.Builder()
    .init(context) //Required -  Context
    .setEventName(eventName) // Required - String
    .setMessageId(messageId) // Required - String
    .setMessageType(MessageType.push) // Required - Required - MessageType.push, MessageType.in_app
    .setMessageTitle(title) // Required - String
    .setMessageContent(content) // Required - String
    .setMessageLanguage(language) // Required - String
    .addMessageActions(messageActionsObject) // Optional - MessageActionsObject
    .setMeta(meta) //Optional - Any [object, String, Int]
    .updateImmediately(false) //Optional - Boolean
    .build()

/*
MessageActionsObject is used to store title for notification Action buttons (if any)
*/
val messageActionsObject = MessageActionsObject(
    title //Required - String
)

updateImmediately is default set to true, you can use that to log events when the app goes in background or closed.

Message Action Events

To Log User Message/Notification Action events you can use: EventType.message_action

You can use message actions to track action items for the notifications. It can help you for having the log on what items on the notifications user most interacted with.

/*
Using the function pattern, make sure to use the SDK defined `MessageReactionObject` for mapping elements.
*/

val messageReactionObject = MessageReactionObject(
    messageId, //Required - String
    messageAction, //Required - String
    meta //Optional - Any [object, String, Int]
    )

 BenshiLog.track(
    context, //Required -  Context
    EventType.message_action, //Required
    eventName, //Required - String
    messageReactionObject, //Required
    updateImmediately  //Optional - Boolean
    )

/*
Using the Builder pattern, you don't need to use the `MessageReactionObject` function as SDK will manage that.
*/

BenshiLogMessageActionsEvent.Builder()
    .init(context) //Required -  Context
    .setEventName(eventName) // Required - String
    .setMessageId(messageId) // Required - String
    .setMessageAction(messageAction) // Required - String
    .setMeta(meta) //Optional - Any [object, String, Int]
    .updateImmediately(false) //Optional - Boolean
    .build()

updateImmediately is default set to true, you can use that to log events when the app goes in background or closed.

Media Events

To Log User Media events you can use: EventType.media

You can use a media object to Track how your users interact with media items in your app. You can track the sessions they play a video and when they pause it. It can help you in coming up with a strategy to deliver media files in a way that is loved by your users.

/*
Using function pattern, make sure to use the SDK defined `MediaObject` for mapping elements.
*/

val mediaObject = MediaObject(
    mediaId, //Required - String
    MediaType.video, //Required - MediaType.video, MediaType.audio
    MediaAction.start, //Required
    duration //Required - Double
    meta //Optional - Any [object, String, Int]
    )

BenshiLog.track(
    context, //Required -  Context
    EventType.media, //Required
    eventName, //Required - String
    mediaObject //Required
    )

/*
Using the Builder pattern, you don't need to use the `MediaObject` function as SDK will manage that.
*/

BenshiLogMediaEvent.Builder()
    .init(context) //Required -  Context
    .setEventName(eventName) // Required - String
    .setMediaId(mediaId) // Required - String
    .setMediaType(MediaType.video) //Required - MediaType.video, MediaType.audio
    .setMediaAction(MediaAction.start) // Required - MediaAction
    .setTime(time) // Required - Double
    .setMeta(meta) //Optional - Any [object, String, Int]
    .updateImmediately(false) //Optional - Boolean
    .build()

updateImmediately is default set to true, you can use that to log events when the app goes in background or closed.

MediaAction includes different types of media actions that can help you with logging desired events.

start, // Start playing media
pause, // Pause media playing
seek, // When user seeks the controller
finish, // Media finishes playing
playing, // Media is playing , auto play
stop, // User stopped playing, change in context
delete, // User deletes media
download, // User downloads media

For detailed implementation of the events, you can refer to QuestionActivity in the demo app.

Tracking Custom Events

You can create Custom Events to track any other user interactions that are crucial for your business. Each Custom Event can further be defined by Event Attributes like event name, interact type, meta and so on. Such granular data enables you to engage users through highly contextual and personalized campaigns through nudges.

Here's a list of Custom Events that can be used based on your integration:

Event NameCalling in SDKDescription
InteractEventType.interactTrack User Interactions like click/tap, double tap, swipe, etc.
TrackEventType.trackTrack any event you want based on your models.

SDK provides 2 ways to integrate Custom Events into your app. You can follow the function based approach where you need to include predefined models for event tracking or you can also use the builder pattern approach that will do the model mapping work for you.

Examples for above mentioned events with both approaches are given below:

Interact Events

To Log User Interact events you can use: EventType.interact

Interact events can be used to log events related to click listeners, swipes, double tap or long press.

/*
Using function pattern, make sure to use the SDK defined `InteractObject` for mapping elements.
*/

val interactObject = InteractObject(
    InteractType.click, //Required - click, doubleclick, long press, swipe
    eventName, //Required - String
    meta //Optional - Any [object, String, Int]
    )

 BenshiLog.track(
    context, //Required -  Context
    EventType.interact, //Required
    eventName, //Required - String
    interactObject, //Required
    updateImmediately  //Optional - Boolean
    )

/*
Using the Builder pattern, you don't need to use the `InteractObject` function as SDK will manage that.
*/

BenshiLogInteractEvent.Builder()
    .init(context) //Required -  Context
    .setEventName(eventName) // Required - String
    .setActionType(InteractType.click) //Required - click, doubleclick, long press, swipe
    .setElementName(elementName) // Required - String
    .setMeta(meta) //Optional - Any [object, String, Int]
    .updateImmediately(false) //Optional - Boolean
    .build()

updateImmediately is default set to true, you can use that to log events when the app goes in background or closed.

Track Events

To Log User Track events you can use: EventType.track

You can use track events to log any custom events you want to log with SDK.

/*
Using function pattern, You can log custom interact details by passing your own params in the meta section.
*/

BenshiLog.track(
    context, //Required -  Context
    EventType.track, //Required
    eventName, //Required - String
    meta, //Optional - Any [object, String, Int]
    updateImmediately  //Optional - Boolean
    )

/*
Using the Builder pattern, you can track events. To log any specific data with a Track event you can use meta to log that. with .setMeta you can log any data type, object, string, integer or any other data Type. Another way is to use hashmap for key separated data.
*/

BenshiLogTrackEvent.Builder()
    .init(context) //Required -  Context
    .setEventName(eventName) // Required - String
    .setMeta(meta) //Optional - Any [object, String, Int]
    .updateImmediately(false) //Optional - Boolean
    .build()

updateImmediately is default set to true, you can use that to log events when the app goes in background or closed.

An example to use track method with hashmap is below:

val hashMap:HashMap<String, Any> = HashMap<String,Any>() //define empty hashmap

// Set key, value hashmap
hashMap.put("media_type",MediaType.image)
hashMap.put("media_action",MediaAction.upload)
hashMap.put("media_id",imageId)
hashMap.put("time",System.nanoTime().toDouble())

// log via BenshiLogTrackEvent
BenshiLogTrackEvent.Builder().init(context)
    .setEventName("profile_image_upload")
    .setMeta(hashMap).build()

Android SDK - Nudge Integration

With Nudges you can utilize experiment based data-driven insights and predictions for individual behaviors towards shaping strategies for collective behaviors. Nudges help you to interact with your users. You can use nudge to send push notifications, in-app messages or use other methods to interact with your users.

App publishers can send them at any time; even if the recipients aren’t currently engaging with the app or using their devices. You can start sending Push Notifications to your users via Benshi Portal by configuring Firebase Cloud Messaging (FCM).

Here's how you can go about it:

Add Firebase to Your Project

Ensure that all apps within a project are platform variants of the same application from an end-user perspective. It's advisable to register the iOS, Android, and web versions of the same app or game with the same Firebase project. All the apps in a project generally share the same Firebase resources (database, storage buckets, etc.).

If you have multiple build variants with different iOS bundle IDs or Android package names defined, you can register each variant with a separate Firebase project. However, if you have variants that share the same Firebase resources, register them with the same Firebase project.

Please follow these instructions for adding Firebase to Your Android Project.

Add Firebase Cloud Messaging Dependency

Add the dependency for Firebase Cloud Messaging in your module’s build.gradle.

dependencies {
    // Import the BoM for the Firebase platform
    implementation platform('com.google.firebase:firebase-bom:28.4.2')

    // Declare the dependencies for the Firebase Cloud Messaging and Analytics libraries
    // When using the BoM, you don't specify versions in Firebase library dependencies
    implementation 'com.google.firebase:firebase-messaging-ktx'
    implementation 'com.google.firebase:firebase-analytics-ktx'
}

Pass Firebase Token to SDK

Firebase tokens can be passed to SDK using FirebaseMessagingService

class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onNewToken(token : String) {
BenshiLog.setFCMRegistrationID(token) // this one
    }
}

It is also recommended that you pass Firebase token to SDK from onCreate of your Application class as shown below. This will ensure that changes in the user's Firebase token are communicated to the SDK.

FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w(TAG, "Fetching FCM registration token failed", task.exception)
        return@OnCompleteListener
    }

    // Get new FCM registration token
val token = task.result
BenshiLog.setFCMRegistrationID(token) // this one
})

Pass Messages to SDK

By overriding the method FirebaseMessagingService.onMessageReceived, you can perform actions based on the received RemoteMessage object and get the message data. All incoming messages from Benshi Portal will contain key source with the value as benshi.

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    val data: Map<String, String> = remoteMessage.getData()
if(data != null) {
  if(data.containsKey("source") && "benshi" == data["source"]){
        NudgeScheduler.showMessage(remoteMessage)
   }
}
}

Next, register the service to the application element of your AndroidManifest.xml as follows.

<service
    android:name=".MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

Add Your Firebase Credentials to Benshi Portal

Step 1: Log in to the Firebase Developers Console.

Step 2: Select your Firebase project.

Step 3: Navigate to Project Settings > Cloud Messaging and copy your server key as shown in the image below.

Image1

Step 4: Log in to your Benshi Portal as admin and navigate to Admin > Integrations > Nudge FCM Setup and Paste the copied server key under the field labeled FCM Server Key.

No further integration for nudge is required. SDK will manage the listeners and auto track the events involving user response to the nudge.

Guidelines

  • EventType class is predefined in the SDK so make sure to use it to track any event.
  • Custom Event Attributes can be of these data types: String, Number, Boolean, Date, List, Map.
  • EventName is a required attribute and must be in a string format.
  • Context is required to pass with each log.
  • updateImmediately is an optional param, by default it’s value is true. You can decide for each event if it needs to be updated immediately or it can wait until the end of the app session.
  • Please ensure consistent usage of the names of Custom Events and their Custom Attributes across all your apps (Android, iOS) and website.
  • In case you have an identity based app that requires signup/signin don't forget to call the following method in your signout function.

BenshiLog.releaseListeners(context) //Required - Context

  • Nudge may not be delivered to apps which were put into background restriction by the user (such as via: Setting -> Apps and Notification -> [appname] -> Battery). Once your app is removed from background restriction, new messages to the app will be delivered as before. In order to prevent lost messages and other background restriction impacts, make sure to avoid bad behaviors listed by the Android vitals effort. These behaviors could lead to the Android device recommending to the user that your app be background restricted. Your app can check if it is background restricted using: isBackgroundRestricted() .

Please feel free to drop in a few lines at support@benshi.ai in case you have any further queries. We're always just an email away!

connection-icon

Get started with benshi.ai today

Get in Touch
connection-icon
connection-icon
connection-icon
connection-icon
connection-icon