ChatMyWay SDK

The ChatMyWay SDK provides developers with a complete solution for integrating real-time chat functionality into mobile applications. This SDK enables communication between drivers, customers, and site managers through different types of chat channels.

Note: ChatMyWay SDK depends on the Background SDK. Ensure that Background SDK is properly configured before using ChatMyWay SDK.

Table of Contents

Getting Started

  • Installation

  • Dependencies

  • Configuration

Core Features

  • Setting Up the SDK

  • Chat Channels

  • Messages

  • Contacts

  • Firebase Notifications

Advanced Usage

  • Error Handling

  • Logging

  • Resource Management

Other Sections

  • Sample Code

  • API Reference

Getting Started

Installation

To use the ChatMyWay SDK in your project, include it as a dependency:

dependencies {
implementation("com.localz:background-sdk:1.1.10")
implementation("com.localz:chatmyway-sdk:1.1.10")
}

Dependencies

The ChatMyWay SDK has the following dependencies:

  • Background SDK: Required for authentication and user session management. The ChatMyWay SDK relies on the Background SDK for user authentication and session handling.

Configuration

Before using the SDK, you need to configure both the Background SDK and the ChatMyWay SDK in the correct order:

import com.localz.backgroundsdk.LocalzBackgroundSDK
import com.localz.chatmyway.LocalzChatMyWaySDK
import com.localz.common.LocalzEnvironment
import kotlinx.coroutines.launch

// Create instance of ChatMyWay SDK
val chatMyWaySDK = LocalzChatMyWaySDK(useMemoryCache = false)

// Step 1: Configure the Background SDK first
coroutineScope.launch {
LocalzBackgroundSDK.configure(
key = "your-localz-sdk-key",
environment = LocalzEnvironment.PROD,
appVersion = "1.0.0"
)

// Step 2: Configure the ChatMyWay SDK immediately after
chatMyWaySDK.configure(
localzSdkKey = "your-localz-sdk-key",
environment = LocalzEnvironment.PROD
)
}

Important: Always configure the Background SDK first, followed by the ChatMyWay SDK. This ensures proper initialization of dependent services.

Core Features

Setting Up the SDK

After configuring both SDKs and successfully logging in through the Background SDK, you need to set up the ChatMyWay SDK for the current user:

import kotlinx.coroutines.launch

// IMPORTANT: This should be called only AFTER the user has successfully logged in
// through the Background SDK (LocalzBackgroundSDK.loginBasicAuth or LocalzBackgroundSDK.loginMDLPSSO)
coroutineScope.launch {
// First ensure the user is logged in via Background SDK
val username = LocalzBackgroundSDK.currentUsername()

// Then set up the ChatMyWay SDK
chatMyWaySDK.setup(username = username)
}

Note: The setup method must be called only after a successful login through the Background SDK. All other ChatMyWay SDK methods will only work after setup has been successfully completed.

Chat Channels

The SDK provides several ways to interact with chat channels.

Getting Chat Channels

To retrieve all chat channels for the current user:

import com.localz.chatmyway.models.ChatChannel
import com.localz.common.LocalzResult
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect

// Observe chat channels
val channelsFlow: Flow<LocalzResult<List<ChatChannel>>> = chatMyWaySDK.chatChannelFlow()

// Collect channel updates
coroutineScope.launch {
channelsFlow.collect { result ->
when (result) {
is LocalzResult.Success -> {
val channels = result.payload
// Process channels
}
is LocalzResult.Error -> {
val errorMessage = result.message
// Handle error
}
}
}
}

Channel Types

The SDK supports three main types of chat channels:

  1. Site Channels: Two-way communication between drivers and site managers

  2. Order Channels: Three-way communication between drivers, customers, and site managers related to an order

  3. Route Stop Channels: Three-way communication related to a specific stop on a delivery route

You can identify the channel type by checking the instance:

when (channel) {
is ChatChannel.Site -> {
val siteId = channel.siteId
// Handle site channel
}
is ChatChannel.Order -> {
val orderNumber = channel.orderNumber
val subProjectId = channel.subProjectId
// Handle order channel
}
is ChatChannel.Stop -> {
val routeId = channel.routeId
val stopId = channel.stopId
// Handle route stop channel
}
}

Messages

Getting Messages for a Channel

To retrieve messages for a specific channel:

import com.localz.chatmyway.models.Message
import kotlinx.coroutines.flow.collect

// Get messages for a specific channel
val messagesFlow = chatMyWaySDK.getChatMessages(channelId = "channel_id")

// Collect messages
coroutineScope.launch {
messagesFlow.collect { result ->
when (result) {
is LocalzResult.Success -> {
val messages = result.payload
// Process messages
}
is LocalzResult.Error -> {
val errorMessage = result.message
// Handle error
}
}
}
}

Sending Messages

The SDK provides methods for sending messages to different types of channels:

// Send message to a site channel
suspend fun sendMessageToSite(siteId: String, messageContent: String) {
chatMyWaySDK.sendMessageBySite(
siteId = siteId,
content = messageContent
)
}

// Send message to an order channel
suspend fun sendMessageToOrder(orderNumber: String, subProjectId: String?, messageContent: String) {
chatMyWaySDK.sendMessageByOrder(
orderNumber = orderNumber,
subProjectId = subProjectId,
content = messageContent
)
}

// Send message to a route stop channel
suspend fun sendMessageToRouteStop(routeId: String, stopId: String, messageContent: String) {
chatMyWaySDK.sendMessageByRouteStopId(
routeId = routeId,
stopId = stopId,
content = messageContent
)
}

Marking Messages as Seen

To update the last seen timestamp for a channel:

suspend fun markChannelAsSeen(channelId: String) {
val result = chatMyWaySDK.updateLastSeen(channelId)

when (result) {
is LocalzResult.Success -> {
// Successfully marked as seen
}
is LocalzResult.Error -> {
// Handle error
}
}
}

Contacts

To retrieve contacts for the current user:

import com.localz.chatmyway.models.Contact
import kotlinx.coroutines.flow.collect

// Get contacts
val contactsFlow = chatMyWaySDK.getContactList()

// Collect contacts
coroutineScope.launch {
contactsFlow.collect { result ->
when (result) {
is LocalzResult.Success -> {
val contacts = result.payload
// Process contacts
}
is LocalzResult.Error -> {
val errorMessage = result.message
// Handle error
}
}
}
}

Firebase Notifications

The SDK can handle Firebase Cloud Messaging (FCM) notifications to update chat channels and messages in real-time:

import com.google.firebase.messaging.RemoteMessage

// In your Firebase Messaging Service
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)

val data = remoteMessage.data

// Process with ChatMyWay SDK
coroutineScope.launch {
chatMyWaySDK.handleFirebasePush(data)
}
}

Advanced Usage

Error Handling

The SDK uses LocalzResult to represent operation outcomes:

when (result) {
is LocalzResult.Success -> {
// Handle success case
val data = result.payload
}
is LocalzResult.Error -> {
// Handle error case
val errorMessage = result.message
val exception = result.throwable

when (exception) {
is ChatMyWaySdkNotConfiguredException -> {
// SDK not configured
}
is ChatMyWaySdkException -> {
// General SDK exception
}
else -> {
// Other exceptions
}
}
}
}

Logging

The SDK provides built-in logging that you can observe:

import com.localz.common.logging.LogReport
import com.localz.common.logging.LogLevel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

// Observe log reports
val logFlow = chatMyWaySDK.logReportFlow()

coroutineScope.launch {
logFlow.collect { logReport ->
// Process log report
val tag = logReport.tag
val message = logReport.message
val logLevel = logReport.logLevel

// Example: Forward to your logging system
when (logLevel) {
LogLevel.DEBUG -> Log.d(tag, message)
LogLevel.INFO -> Log.i(tag, message)
LogLevel.WARNING -> Log.w(tag, message)
LogLevel.ERROR -> Log.e(tag, message)
LogLevel.VERBOSE -> Log.v(tag, message)
LogLevel.FATAL -> Log.wtf(tag, message)
}
}
}

Resource Management

To properly manage resources, you should cancel the SDK when it's no longer needed:

// Cancel the SDK
override fun onDestroy() {
super.onDestroy()
chatMyWaySDK.cancel()
}

Sample Code

Here's a sample demonstrating how to use the ChatMyWay SDK in an Android app:

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.lifecycle.lifecycleScope
import com.localz.backgroundsdk.BackgroundSdkState
import com.localz.backgroundsdk.LocalzBackgroundSDK
import com.localz.chatmyway.LocalzChatMyWaySDK
import com.localz.chatmyway.models.ChatChannel
import com.localz.chatmyway.models.Message
import com.localz.common.LocalzEnvironment
import com.localz.common.LocalzResult
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

class ChatActivity : ComponentActivity() {
private lateinit var chatMyWaySDK: LocalzChatMyWaySDK

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

// Initialize SDK
chatMyWaySDK = LocalzChatMyWaySDK(useMemoryCache = false)

lifecycleScope.launch {
// Step 1: Configure Background SDK first
LocalzBackgroundSDK.configure(
key = "your-localz-sdk-key",
environment = LocalzEnvironment.PROD,
appVersion = "1.0.0"
)

// Step 2: Configure ChatMyWay SDK right after
chatMyWaySDK.configure(
localzSdkKey = "your-localz-sdk-key",
environment = LocalzEnvironment.PROD
)

// Step 3: Initialize Background SDK
val initResult = LocalzBackgroundSDK.initialize()
if (initResult is LocalzResult.Success) {
// Step 4: Login with Background SDK
val loginResult = LocalzBackgroundSDK.loginBasicAuth(
username = "driver_username",
password = "driver_password"
)

if (loginResult is LocalzResult.Success) {
// Step 5: Setup ChatMyWay SDK AFTER successful login
val username = LocalzBackgroundSDK.currentUsername()
chatMyWaySDK.setup(username = username)

// NOW you can use ChatMyWay SDK features

// Observe chat channels
chatMyWaySDK.chatChannelFlow().collect { result ->
when (result) {
is LocalzResult.Success -> {
val channels = result.payload
updateChannelsList(channels)
}
is LocalzResult.Error -> {
showError(result.message)
}
}
}

// Observe log reports
chatMyWaySDK.logReportFlow().collect { logReport ->
// Process log report
}
}
}
}
}

private fun updateChannelsList(channels: List<ChatChannel>) {
// Update UI with channels
}

private fun showError(message: String) {
// Show error in UI
}

fun onChannelSelected(channelId: String) {
lifecycleScope.launch {
// Mark channel as seen
chatMyWaySDK.updateLastSeen(channelId)

// Get messages for selected channel
chatMyWaySDK.getChatMessages(channelId).collect { result ->
when (result) {
is LocalzResult.Success -> {
val messages = result.payload
updateMessagesList(messages)
}
is LocalzResult.Error -> {
showError(result.message)
}
}
}
}
}

private fun updateMessagesList(messages: List<Message>) {
// Update UI with messages
}

fun sendMessage(channelId: String, content: String) {
val channel = getChannelById(channelId)

lifecycleScope.launch {
when (channel) {
is ChatChannel.Site -> {
chatMyWaySDK.sendMessageBySite(
siteId = channel.siteId,
content = content
)
}
is ChatChannel.Order -> {
chatMyWaySDK.sendMessageByOrder(
orderNumber = channel.orderNumber,
subProjectId = channel.subProjectId,
content = content
)
}
is ChatChannel.Stop -> {
chatMyWaySDK.sendMessageByRouteStopId(
routeId = channel.routeId,
stopId = channel.stopId,
content = content
)
}
}
}
}

private fun getChannelById(channelId: String): ChatChannel {
// Find channel by ID
// This is just a placeholder - implement according to your app's structure
}

override fun onDestroy() {
super.onDestroy()
chatMyWaySDK.cancel()
}
}

API Reference

LocalzChatMyWaySDK

Main class for interacting with the ChatMyWay SDK.

Constructor

LocalzChatMyWaySDK(useMemoryCache: Boolean)
  • useMemoryCache: Whether to use in-memory caching for messages

Methods

MethodDescription
configure(localzSdkKey: String, environment: LocalzEnvironment)Configures the SDK
setup(username: String)Sets up the SDK for the given username
chatChannelFlow(): Flow<LocalzResult<List<ChatChannel>>>Provides a real-time flow of chat channels
getChatMessages(channelId: String): Flow<LocalzResult<List<Message>>>Provides a real-time flow of messages for a channel
updateLastSeen(channelId: String): LocalzResult<Unit>Updates the last seen timestamp for a channel
getContactList(): Flow<LocalzResult<List<Contact>>>Provides a real-time flow of contacts
chatEventFlow(): Flow<LocalzResult<ChatEvent>>Provides a real-time flow of chat events
handleFirebasePush(remoteMessageData: Map<String, String>)Handles Firebase push notifications
sendMessageBySite(siteId: String, content: String)Sends a message to a site channel
sendMessageByOrder(orderNumber: String, subProjectId: String?, content: String)Sends a message to an order channel
sendMessageByRouteStopId(routeId: String, stopId: String, content: String)Sends a message to a route stop channel
logReportFlow(): Flow<LogReport>Provides a flow of log reports
cancel()Cancels ongoing operations and releases resources

ChatChannel

Represents a chat channel in the system.

Types

  • ChatChannel.Site: Two-way channel between driver and site manager

  • ChatChannel.Order: Three-way channel related to an order

  • ChatChannel.Stop: Three-way channel related to a route stop

Message

Represents a chat message.

Properties

PropertyTypeDescription
idString?Unique identifier of the message (null if not yet sent)
correlIdStringCorrelation ID for tracking the message
channelIdStringID of the channel the message belongs to
usernameStringName of the user who sent the message
contentStringContent of the message
timestampStringTimestamp when the message was sent
messageSenderMessageSenderThe type of sender (CUSTOMER, USER, or SITE)
isFromLocalCacheBooleanIndicates whether this message is from local cache
isFailedBooleanWhether the message failed to send

Contact

Represents a contact in the system.

Properties

PropertyTypeDescription
titleStringName or title of the contact
subtitleString?Additional information about the contact
contactTypeContactTypeType of the contact (SITE, DRIVER, CUSTOMER)

Packages

Link copied to clipboard
common
Link copied to clipboard
common