Skip to main content

Inbox SDK for Android

SDK integration

  1. You can see what's new and download the sdk here
  2. Add the SDK to your project

Demo App

A demo app has been created to understand the integration and usage of the SDK. It can be found here https://github.com/yellowmessenger/Inbox-SDK-Demo-App-Android

Initialization

The SDK can be initialised by passing API_KEY, USER_ID and BOT_ID to the init method.

YellowInbox.init(applicationContext : Context,
apiKey : String,
userId: String,
botId : String
) : LiveData<Resource<Void>>

applicationContext

Application context is used to initialise the service which runs XMPP.

apiKey

API_KEY will be provided by yellow.ai, It is clients responsibility to keep the API_KEY safe. This is a mandatory parameter.

userId

UserId will be the id registered/provided to yellow.ai by the client to authenticate their employee. This is a mandatory parameter.

botId

BOT_ID will be provided by yellow.ai. This is a mandatory parameter.

Example

import android.app.Application
import androidx.lifecycle.ProcessLifecycleOwner
import com.yellowmessenger.YellowInbox
import com.yellowmessenger.YmAppProcessLifeCycleListener

class TestApplication : Application() {

override fun onCreate() {
super.onCreate()

//Set Process lifecycle listener
// This is required to listen to application state
ProcessLifecycleOwner.get()
.lifecycle
.addObserver(YmAppProcessLifeCycleListener())

// Initialise the SDK
YellowInbox.init(applicationContext, "API_KEY", "USER_ID", "BOT_ID")
.observe(lifecycleOwner, Observer {
when(it.status) {
SUCCESS-> Log.d(TAG, "SDK initialised successfully")
ERROR -> Log.d(TAG, "Error while initialising the SDK")
else-> null
}
})
}
}

Overview

Overview view is provided as a fragment and activity

Overview Activity

If clients want to use Overview Activity in their application, they can call the following method to get the Activity.

YellowInbox.startOverviewActivity(context:Context)

Overview Fragment

If clients want to use Overview Fragment in their application, they can call the following method to get the fragment

val fragment =YellowInbox.getOverviewFragment()

Clients can embed this fragment in their activity and begin the transaction as they do for any other fragment.

My Chat

Chats view is provided as a fragment and activity

My Chat Activity

If clients want to use MyChat Activity in their application, they can call the following method to get the Activity.

YellowInbox.startMyChatActivity(context:Context)

My Chat Fragment

If clients want to use MyChat Fragment in their application, they can call the following method to get the fragment

val fragment =YellowInbox.getMyChatsFragment()

Clients can embed this fragment in their activity and begin the transaction as they do for any other fragment.

Notifications

Background Notification

To receive firebase notification clients need to send Firebase device token to SDK. To do so the following method can be used.

YellowInbox.setFirebaseDeviceToken("FIRE_BASE_DEVICE_TOKEN")
note

Make sure to call this function when the device token is changed.

Clients will receive firebase notification if the app is not running in foreground or in background, or if Ticket Create, User Message or Agent is added as collaborator actions happening on a ticket.

Clients need not to listen to these notifications when the app is running, SDK will take care of such events.

Clients need to call following method if they want to take user to appropriate view once user clicks on notification delivered in system tray and sent by yellow.ai

fun getDataFromIntent(): MutableMap<String, Any?> {
val data = mutableMapOf<String, Any?>()
if (intent.extras != null) {
for (key in intent.extras!!.keySet()) {
val value = intent.extras!![key]
data[key] = value
}
this.intent.putExtras(Bundle.EMPTY)
}
return data
}

val data: Map<String, Any?> = getDataFromIntent()

if (data.containsKey("ym")) {
YellowInbox.handleBackgroundNotification(
context = applicationContext,
data = data
)
}

Notification data will get delivered as intent extra in launcher Activity. Clients can use the above mentioned method to fetch data from Intent and create a map.

Local Notification

Clients will receive local notification that will be triggered by the SDK based on the events received over XMPP. In case a client wants to override the normal behaviour of notification or want to update title/body, they can do so by overriding the YmMessageReceiver class.

Clients need to call following method for listening to local event notification and modifying them

YellowInbox.setLocalReceiver(receiver:BroadcastReceiver)

Example (How to use YmMessageReceiver)

import com.yellowmessenger.YmMessageReceiver
import com.yellowmessenger.ui.xmpp.model.YmTicketCreateModel
import com.yellowmessenger.ui.xmpp.model.YmXMPPMessageModel

class TestMessageReceiver : YmMessageReceiver() {
override fun onTicketCreateEventReceived(
title: String?,
body: String?,
model: YmTicketCreateModel
) {
super.onTicketCreateEventReceived(title, body, model)
}

override fun onTicketUpdateEventReceived(
title: String?,
body: String?,
model: YmXMPPMessageModel
) {
super.onTicketUpdateEventReceived(title, body, model)
}
}

Clients will receive events for Ticket Create and Ticket Update (new message, agent added as collaborator). We recommend not to modify model data as it may result in not showing notification at all. Model is exposed so the client can make use of data present in it to create the required title and body.

Video call Notification

If a client is receiving a video call notification while the app is in background, there is no special handling required for it. Simply tapping on notification will take the user to the appropriate view and show a dialog to answer/decline the call.

In case the app is running and in the foreground, the client needs to listen to Firebase notification and call the following function.

Assuming client has already have a service which overrides FirebaseMessagingService

  1. Client need to set the Firebase token in case device token changes by calling
YellowInbox.setFirebaseDeviceToken(token)
  1. In onMessageReceived(message:RemoteMessage) function client need to check if message contains “callJoinUrl” call the SDK function to handle it
if (message.data.containsKey("callJoinUrl") && !message.data["callJoinUrl"].isNullOrEmpty()) {
YellowInbox.handleBackgroundNotification(applicationContext, message.data)
}

Example

class YmSupportFirebaseMessagingService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
sendRegistrationToServer(token)
}

private fun sendRegistrationToServer(token: String) {
val hasValidData = hasValidData(this.applicationContext)
if (hasValidData) {
YellowInbox.setFirebaseDeviceToken(token)
}
}

override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
if (message.data.containsKey("callJoinUrl") && !message.data["callJoinUrl"].isNullOrEmpty()) {
YellowInbox.handleBackgroundNotification(applicationContext, message.data)
}
}
}

A call declined from notification can be joined from the Chat view by tapping on the call icon

Agent Status

Get All Agent Statuses

To get all possible statuses of logged in User against the bot id (Used for initialising the SDK), client can call the following method. This can be used to show all the possible status when Agent want to change the status.

YellowInbox.getAllAgentStatus(): List<YmAgentStatus>

Get Agent Status

To get availability status of logged in User against the bot id (Used for initialising the SDK), client can call the following method and observe on it.

YellowInbox.getAgentStatus(): LiveData<Resource<YmAgentStatus>>

Example

YellowInbox.getAgentStatus().observe(lifecycleOwner, Observer {
when(it.status) {
Resource.SUCCESS -> {
val data:YmAgentStatus = it.data
}
Resource.ERROR -> {
val msg:String = it.message
}
else -> {

}
}
})

Set Agent Status

To set the status of logged in user against the bot id (Used for initialising the SDK), the client can call the following method and observe on it. Client need to pass the YmAgentStatus object received from making YellowInbox.getAllAgentStatus() call.

YellowInbox.setAgentStatus(status: YmAgentStatus): LiveData<Resource<Void>>

Example

YellowInbox.setAgentStatus(status)
.observe(lifecycleOwner,Observer{
when(it.status){
Resource.SUCCESS -> {
showToast("Status changed")
}
Resource.ERROR -> {
val msg:String = it.message
}
else -> {

}
}
})

Logout

By calling logout, all the services and notifications will be terminated. You can call this function when user logs out of the app

YellowInbox.logout(): MutableLiveData<Resource<Void>>

Example

YellowInbox.logout()
.observe(lifecycleOwner,Observer{
when(it.status){
Resource.SUCCESS -> {
showToast("Logout Success!")
}
Resource.ERROR -> {
val msg:String = it.message
}
else -> {

}
}
})

Mandatory overrides

Please add the following key in your strings.xml file and change the value.

<string name="application_id_for_provider">your.app.id.fileprovider</string>

By doing this all the images/files will be sandboxed for your app.

Optional overrides

colors.xml

You can update your colors.xml. By overriding these value you can the color as per your app design

<color name="ym_app_bar_color">@color/primaryColor</color>
<color name="ym_status_bar_color">@color/primaryDarkColor</color>
<color name="ym_app_bar_text_color">@color/white</color>
<color name="ym_app_bar_icon_color">@color/white</color>
<color name="ym_text_color_primary">@color/primaryTextColor</color>
<color name="ym_text_color_secondary">@color/secondaryTextColor</color>
<color name="ym_accent_color">@color/colorAccent</color>
<color name="ym_icon_color">#707E8A</color>
<color name="ym_event_msg_background_color">#EAF5FB</color> //light color
<color name="ym_sent_msg_background_color">#007ED4</color> //dark color
<color name="ym_rcv_msg_background_color">#F5F8FA</color> // light color
<color name="ym_progressbar_color">#14568E</color>

Dimens.xml

By overriding the client can control size texts and progress bar.

<dimen  name="ym_title_size">16sp</dimen>
<dimen name="ym_subtitle_size">14sp</dimen>
<dimen name="ym_caption_size">12sp</dimen>
<dimen name="ym_body_size">14dp</dimen>
<dimen name="ym_progress_bar_size">36dp</dimen>
<dimen name="ym_in_view_progress_bar_size">24dp</dimen>

Informational

Versions

YellowInbox SDK usage following minimumSdkVersion targetSdkVersion.

minSdkVersion 21 targetSdkVersion 30

Dependencies

YellowInbox SDK usage following dependencies.

dependencies {

implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.5.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.gridlayout:gridlayout:1.0.0'

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.7.2'

implementation 'com.google.dagger:dagger:2.27'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
kapt 'com.google.dagger:dagger-compiler:2.27'

implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.3.1'

// Glide
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

//Smack
implementation "org.igniterealtime.smack:smack-android-extensions:4.2.0"
implementation "org.igniterealtime.smack:smack-tcp:4.2.0"

//Event bus
implementation 'org.greenrobot:eventbus:3.2.0'

testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

Permissions

YellowInbox SDK usage following permissions.

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />