This guide covers chat channel management and messaging functionality in the Virtual Stadium Data SDK.
The ChatManager contains and handles all chat channels within your application.
getOrAddChannel(channelConfig)
Creates a new channel if it doesn't exist, or returns the existing channel with the specified ID. Always returns a ChatChannel object.
removeChannel(channelId)
Removes a specific channel from the manager.
removeAllChannels()
Removes all channels from the manager.
When creating a chat channel, you can provide callbacks to receive new insights data. The SDK provides two callback options to accommodate platform differences:
onNewInsights
Regular callback function for iOS (iOS doesn't support suspend functions in lambdas).
onNewInsightsSuspended
Suspend callback function for Android (allows async operations).
The SDK automatically uses the appropriate callback based on what you provide. These callbacks receive a list of OutcomePayloadRequest objects containing new betting insights data.
Create channels with optional insights callbacks. The ChannelConfig allows you to specify channel ID, whether to fetch stats, and other configuration options.
Handle insights data in the callback to update your UI or process betting information.
import ag.sportradar.virtualstadium.datasdk.model.ChannelConfig
import ag.sportradar.virtualstadium.datasdk.model.OutcomePayloadRequest
import ag.sportradar.virtualstadium.datasdk.services.ChatManager
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.get
class ChatManagerViewModel :
ViewModel(),
KoinComponent {
private val chatManager: ChatManager
get() = get()
val chatChannels = chatManager.channels
fun addChannelWithInsights(
channelId: String,
getChannelStats: Boolean = true
) {
val channelConfig = ChannelConfig(
channelId = channelId,
getChannelStats = getChannelStats
)
chatManager.getOrAddChannel(
channelConfig = channelConfig,
onNewInsightsSuspended = { insights ->
// Handle new insights data (suspend function)
processInsightsData(insights)
}
)
}
}The ChatChannel encapsulates all functionalities related to a chat channel within the application. It defines how chat channels behave and interact with other parts of the application.
The channel provides comprehensive state management, message handling, bet sharing, reactions, and lifecycle management through a well-defined interface.
The ChatChannel maintains observable states that allow the UI to react and update based on changes in chat messages, bet shares, network connectivity, insights, and tag filters.
MessagesState
Available as state, provides a robust, thread-safe, and reactive way to manage and observe chat messages within a channel, facilitating dynamic, real-time chat applications.
BetShareState
NetworkState
Available as networkStatusState, provides real-time information about network connectivity. Helps the application respond appropriately to network changes, such as displaying offline indicators or retrying failed operations.
InsightsState
Available as insightsState, manages match insights and predictions. Includes real-time updates about match statistics, betting odds, and other relevant information that enhances the chat experience.
filteredTagsState
Manages and observes tags that result from a search query using filterTags(query: String). Updates dynamically to reflect tags matching the search query, allowing the application to display relevant tags based on user input.
The ChatChannel facilitates sending, replying to, and managing messages. This includes message pagination, sending new messages, replying to specific messages, and requesting specific messages by ID.
loadPreviousPage()
Fetches and appends a previous page of messages to the current list. Crucial for implementing pagination or infinite scrolling in chat applications. Updates the observable MessagesState with newly fetched messages at the beginning of the list.
sendMessage(message, onFailure)
Sends a message to the chat channel with immediate UI feedback. The message displays with a "Loading" status during transmission. Includes an onFailure callback for error handling, enabling graceful error management and user notifications.
replyToMessage(message, messageId, onFailure)
Sends a new message as a reply to an existing message. Particularly useful in group chat scenarios with multiple concurrent conversations. Includes an onFailure callback for error handling.
getMessage(messageId, onSuccess, onFailure)
Retrieves details of a specific message using its unique identifier. Useful when accessing full content or metadata not immediately available in local state. Includes both onSuccess and onFailure callbacks.
Provides functionalities to share bets within the chat channel, access shared bets, and manage bet sharing activities. These functions collectively support a rich, interactive betting experience, allowing users to share, view, and manage bets in a social context.
shareBet(betPayload, comment, showStake, onSuccess, onFailure)
Allows users to share a bet within the chat channel with an optional comment. Users can decide whether to show stake and payout. Enhances the interactive aspect of chat by integrating betting functionality directly into the conversation flow.
getAllBetShares()
Retrieves all bets shared within the channel. Displays a comprehensive view of betting activity to users.
loadMoreAllBetShares()
Loads additional pages of shared bets for pagination or infinite scrolling features.
getMyBetShares()
Fetches bets shared by the currently authenticated user, enabling personalized bet history tracking.
loadMoreMyBetShares()
Loads additional pages of the current user's shared bets for pagination.
copySharedBet(messageId, onSuccess, onFailure)
Copies a bet that has been shared in the channel with success/failure callbacks.
markBetSlipsAsAlreadyShared(betSlips, onSuccess, onFailure)
Marks specified bet slips as already shared to prevent duplicate sharing. Maintains integrity of shared bet data.
Allows users to react to messages with predefined reaction types from the backend and manage these reactions. These functions enhance the chat experience by enabling dynamic, interactive reactions to messages.
reactToMessage(message, reactionType)
Adds a reaction to a message using predefined reaction types (thumbs up, heart, etc.). Enhances interactivity and engagement within the chat.
deleteReaction(message, reactionType)
Removes a previously added reaction from a message. Useful for correcting mistakes or changing reactions.
toggleReactionOnMessage(message, reactionType)
Intelligently handles both adding and removing reactions based on current state. If the user has already reacted with the specified type, the reaction is removed; otherwise, it's added. Simplifies reaction logic for developers.
Message Reporting
reportMessage(messageId, onSuccess, onFailure)
Reports inappropriate messages for moderation. Essential for community management and user safety. Provides immediate feedback via callbacks.
The backend supplies a list of tags upon channel initialization in MessagesState. These enable displaying/highlighting tags in sent messages and incorporating them into new messages.
filterTags(query, cursorPosition)
Filters tags based on query string and cursor position. Updates filteredTagsState dynamically as users type, providing real-time search feedback.
sanitizeMessage(input)
Sanitizes user input according to allowed character ranges defined in chat settings. Maintains content quality and prevents security issues from malformed input.
clearTagFilter()
Clears the current tag filter, resetting filteredTagsState to show all available tags.
Provides comprehensive insights management functionality that enhances user experience with real-time match data and betting information.
markInsightAsSeen(insightId)
Marks a specific insight as seen by the user. Tracks user engagement with insights for prioritization.
selectInsightOdds(insightId)
Handles selection of odds from an insight. Called when users interact with betting odds displayed in insights.
updateInsights(outcomesPayload)
Updates insights data with new outcomes payload. Enables real-time updates ensuring users have access to latest information and betting odds.
Manages the chat channel lifecycle including starting, stopping, restarting, resuming, and destroying channels. Ensures efficient resource allocation and cleanup.
The channel receives new messages by default, but receiving can be stopped and restarted.
isDeltaMessageActive()
Checks if the channel is currently listening for new messages. Returns boolean indicating active status.
restart()
Resets the channel to a fresh state. Clears current state, fetches latest messages, and starts listening. Useful when refreshing the chat.
stop()
Stops listening for new messages. Conserves resources when chat is not in active use, preventing unnecessary data usage and battery drain.
resume()
Resumes channel operations after being stopped. Fetches latest messages, restarts listening, and resumes insights functionality. Useful when returning to foreground.
destroy()
Completely shuts down the chat channel. Cancels all internal jobs and resets state. Used when chat functionality is no longer needed (logout, app closure).
This example demonstrates a complete chat implementation with all major features including messaging, reactions, bet sharing, tags, insights, and lifecycle management.
The ViewModel exposes all channel states and provides methods for every chat operation.
import ag.sportradar.virtualstadium.datasdk.model.*
import ag.sportradar.virtualstadium.datasdk.services.*
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.*
import org.koin.core.component.KoinComponent
import org.koin.core.component.get
class ChatViewModel : ViewModel(), KoinComponent {
private val chatManager: ChatManager get() = get()
private val userProvider: UserProvider get() = get()
private val settingsProvider: SettingsProvider get() = get()
private var channel: ChatChannel? = null
val chatSettingState by lazy { settingsProvider.settings }
fun initializeChannel(channelId: String) {
channel = chatManager.getOrAddChannel(
channelId = channelId,
getChannelStats = true
)
}
// Message operations
fun loadPreviousPage() = channel?.loadPreviousPage()
fun sendMessage(message: String) =
channel?.sendMessage(message)
fun replyToMessage(messageId: String, message: String) =
channel?.replyToMessage(message, messageId)
// Reaction operations
fun toggleReactionOnMessage(reaction: ReactionType, message: Message) =
channel?.toggleReactionOnMessage(message, reaction)
fun addReaction(reaction: ReactionType, message: Message) =
channel?.reactToMessage(message, reaction)
// Moderation
fun reportMessage(messageId: String, callback: (Boolean) -> Unit) {
channel?.reportMessage(
messageId = messageId,
onSuccess = { callback(true) },
onFailure = { callback(false) }
)
}
// Bet sharing operations
fun shareNewBet(
betPayload: BetPayload,
showStake: Boolean,
comment: String
) {
channel?.shareBet(
betPayload = betPayload,
comment = comment,
showStake = showStake,
onSuccess = { /* Handle success */ },
onFailure = { /* Handle failure */ }
)
}
fun getAllBetShares() = channel?.getAllBetShares()
fun loadMoreBetShares() = channel?.loadMoreAllBetShares()
fun getMyBetShares() = channel?.getMyBetShares()
fun loadMoreMyBetShares() = channel?.loadMoreMyBetShares()
fun copySharedBet(messageId: String) =
channel?.copySharedBet(messageId)
// Tags operations
fun filterTags(query: String, cursorPosition: Int) =
channel?.filterTags(query, cursorPosition)
fun sanitizeMessage(input: String): String =
channel?.sanitizeMessage(input) ?: input
fun clearTagFilter() = channel.value?.clearTagFilter()
// Insights operations
fun markInsightAsSeen(insightId: String) =
channel?.markInsightAsSeen(insightId)
fun selectInsightOdds(insightId: String) =
channel?.selectInsightOdds(insightId)
fun updateInsights(outcomesPayload: OutcomesPayload) =
channel?.updateInsights(outcomesPayload)
// Lifecycle management
fun stopChannel(channelId: String) {
chatManager.removeChannel(channelId = channelId)
channel = null
}
fun restartChannel() = channel?.restart()
}