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:
Site Channels: Two-way communication between drivers and site managers
Order Channels: Three-way communication between drivers, customers, and site managers related to an order
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
Method | Description |
---|---|
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 managerChatChannel.Order
: Three-way channel related to an orderChatChannel.Stop
: Three-way channel related to a route stop
Message
Represents a chat message.
Properties
Property | Type | Description |
---|---|---|
id | String? | Unique identifier of the message (null if not yet sent) |
correlId | String | Correlation ID for tracking the message |
channelId | String | ID of the channel the message belongs to |
username | String | Name of the user who sent the message |
content | String | Content of the message |
timestamp | String | Timestamp when the message was sent |
messageSender | MessageSender | The type of sender (CUSTOMER, USER, or SITE) |
isFromLocalCache | Boolean | Indicates whether this message is from local cache |
isFailed | Boolean | Whether the message failed to send |
Contact
Represents a contact in the system.
Properties
Property | Type | Description |
---|---|---|
title | String | Name or title of the contact |
subtitle | String? | Additional information about the contact |
contactType | ContactType | Type of the contact (SITE, DRIVER, CUSTOMER) |