> For the complete documentation index, see [llms.txt](https://docs.firework.com/firework-for-developers/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.firework.com/firework-for-developers/android-sdk/integration-guide/livestream/livestream-callbacks.md).

# Livestream Callbacks

The Firework SDK provides comprehensive callback interfaces for handling user interactions during livestreams. This guide covers all available callbacks and their usage.

## Overview

Livestream callbacks allow you to respond to user actions during live broadcasts, replays, and trailers. All callbacks are accessed through `FireworkSdk.livestream` and provide video context information via the `VideoInfo` parameter.

## Link Click Listener

### setOnLinkClicked()

Handles clicks on links within livestream content (e.g., product links, external URLs, promotional links).

**Signature:**

```kotlin
fun setOnLinkClicked(listener: OnLinkClickListener?)
```

**Listener Interface:**

```kotlin
fun interface OnLinkClickListener {
    fun onLinkClick(title: String?, url: String?, videoInfo: VideoInfo)
}
```

**Parameters:**

* `title` - Link title or description (can be null)
* `url` - The URL to open (can be null)
* `videoInfo` - Context information about the current video

**Example:**

```kotlin
FireworkSdk.livestream.setOnLinkClicked { title, url, videoInfo ->
    Log.d("Livestream", "Link clicked: $title")
    Log.d("Livestream", "URL: $url")
    Log.d("Livestream", "Video ID: ${videoInfo.videoId}")
    
    // Open the link in browser or handle deep link
    url?.let { openUrl(it) }
}
```

**Use Cases:**

* Open product pages when users tap product links
* Handle deep links to specific app screens
* Track link click analytics
* Open external promotional content

**Remove Listener:**

```kotlin
// Set null to remove the listener
FireworkSdk.livestream.setOnLinkClicked(null)
```

***

## Interaction Listener

### setOnInteractionListener()

Handles various user interactions during livestreams including questions, polls, giveaways, chat messages, and likes.

**Signature:**

```kotlin
fun setOnInteractionListener(listener: OnInteractionListener?)
```

**Listener Interface:**

```kotlin
interface OnInteractionListener {
    fun onUserSubmitAnswerToQuestion(videoInfo: VideoInfo, question: QuestionInteraction): Boolean
    
    fun onUserSelectOptionForPoll(videoInfo: VideoInfo, poll: PollInteraction): Boolean
    
    fun onUserJoinGiveaway(videoInfo: VideoInfo, giveaway: GiveawayInteraction): Boolean
    
    fun onUserSendMessage(videoInfo: VideoInfo, message: ChatMessage): Boolean
    
    fun onUserSendLike(videoInfo: VideoInfo): Boolean
}
```

### onUserSubmitAnswerToQuestion()

Called when a user submits an answer to a question during a livestream.

**Parameters:**

* `videoInfo` - Context information about the current video
* `question` - Question interaction details

**Question Interaction:**

```kotlin
data class QuestionInteraction(
    val prompt: String  // The question prompt text
)
```

**Returns:** `Boolean`

* `true` - Interaction handled by your app
* `false` - Let SDK handle the interaction (default behavior)

**Example:**

```kotlin
FireworkSdk.livestream.setOnInteractionListener(object : Livestream.OnInteractionListener {
    override fun onUserSubmitAnswerToQuestion(
        videoInfo: VideoInfo,
        question: QuestionInteraction
    ): Boolean {
        Log.d("Livestream", "Question answered: ${question.prompt}")
        return false  // Let SDK handle
    }
    
    // Other methods...
})
```

### onUserSelectOptionForPoll()

Called when a user selects an option in a poll during a livestream.

**Parameters:**

* `videoInfo` - Context information about the current video
* `poll` - Poll interaction details

**Poll Interaction:**

```kotlin
data class PollInteraction(
    val prompt: String  // The poll question/prompt text
)
```

**Returns:** `Boolean`

* `true` - Interaction handled by your app
* `false` - Let SDK handle the interaction (default behavior)

**Example:**

```kotlin
override fun onUserSelectOptionForPoll(
    videoInfo: VideoInfo,
    poll: PollInteraction
): Boolean {
    Log.d("Livestream", "Poll voted: ${poll.prompt}")
    
    // Track poll participation
    trackPollVote(videoInfo.videoId, poll.prompt)
    
    // Show confirmation
    showToast("Your vote has been recorded!")
    
    return false  // Let SDK handle the default behavior
}
```

### onUserJoinGiveaway()

Called when a user joins a giveaway during a livestream.

**Parameters:**

* `videoInfo` - Context information about the current video
* `giveaway` - Giveaway interaction details

**Giveaway Interaction:**

```kotlin
data class GiveawayInteraction(
    val name: String  // The giveaway name/title
)
```

**Returns:** `Boolean`

* `true` - Interaction handled by your app
* `false` - Let SDK handle the interaction (default behavior)

**Example:**

```kotlin
override fun onUserJoinGiveaway(
    videoInfo: VideoInfo,
    giveaway: GiveawayInteraction
): Boolean {
    Log.d("Livestream", "Giveaway joined: ${giveaway.name}")
    
    // Verify user eligibility
    if (!isUserEligibleForGiveaway()) {
        showError("You must be logged in to join giveaways")
        return true  // Prevent default behavior
    }
    
    // Track giveaway participation
    trackGiveawayEntry(videoInfo.videoId, giveaway.name)
    
    // Show confirmation
    showSuccessDialog("You're entered in the giveaway!")
    
    return false  // Let SDK handle
}
```

### onUserSendMessage()

Called when a user sends a chat message during a livestream.

**Parameters:**

* `videoInfo` - Context information about the current video
* `message` - Chat message details

**Chat Message:**

```kotlin
data class ChatMessage(
    val username: String,   // The sender's username
    val messageId: String,  // Unique message identifier
    val text: String       // The message content
)
```

**Returns:** `Boolean`

* `true` - Message handled by your app (message will not be sent to chat)
* `false` - Let SDK handle the message (message will be sent)

**Example:**

```kotlin
override fun onUserSendMessage(
    videoInfo: VideoInfo,
    message: ChatMessage
): Boolean {
    Log.d("Livestream", "Message from ${message.username}: ${message.text}")
    
    // Filter inappropriate content
    if (containsInappropriateContent(message.text)) {
        showError("Message contains inappropriate content")
        return true  // Block the message
    }
    
    // Enforce rate limiting
    if (isUserSpamming(message.username)) {
        showError("You're sending messages too quickly")
        return true  // Block the message
    }
    
    // Track chat activity
    trackChatMessage(videoInfo.videoId, message.messageId)
    
    return false  // Allow message to be sent
}
```

### onUserSendLike()

Called when a user sends a like/heart during a livestream.

**Parameters:**

* `videoInfo` - Context information about the current video

**Returns:** `Boolean`

* `true` - Like handled by your app (like will not be sent)
* `false` - Let SDK handle the like (like will be sent)

**Example:**

```kotlin
override fun onUserSendLike(videoInfo: VideoInfo): Boolean {
    Log.d("Livestream", "Like sent for video: ${videoInfo.videoId}")
    
    // Track engagement
    trackLikeAction(videoInfo.videoId)
    
    return false  // Let SDK handle the default behavior
}
```

**Complete Interaction Listener Example:**

```kotlin
FireworkSdk.livestream.setOnInteractionListener(object : Livestream.OnInteractionListener {
    override fun onUserSubmitAnswerToQuestion(
        videoInfo: VideoInfo,
        question: QuestionInteraction
    ): Boolean {
        handleQuestion(videoInfo, question)
        return false
    }
    
    override fun onUserSelectOptionForPoll(
        videoInfo: VideoInfo,
        poll: PollInteraction
    ): Boolean {
        handlePoll(videoInfo, poll)
        return false
    }
    
    override fun onUserJoinGiveaway(
        videoInfo: VideoInfo,
        giveaway: GiveawayInteraction
    ): Boolean {
        handleGiveaway(videoInfo, giveaway)
        return false
    }
    
    override fun onUserSendMessage(
        videoInfo: VideoInfo,
        message: ChatMessage
    ): Boolean {
        return handleChatMessage(videoInfo, message)
    }
    
    override fun onUserSendLike(videoInfo: VideoInfo): Boolean {
        handleLike(videoInfo)
        return false
    }
})
```

**Remove Listener:**

```kotlin
// Set null to remove the listener
FireworkSdk.livestream.setOnInteractionListener(null)
```

***

## Giveaway Terms and Conditions Listener

### setOnGiveawayTermsAndConditionsClickListener()

Handles clicks on giveaway terms and conditions links.

**Signature:**

```kotlin
fun setOnGiveawayTermsAndConditionsClickListener(
    listener: OnGiveawayTermsAndConditionsClickListener?
)
```

**Listener Interface:**

```kotlin
fun interface OnGiveawayTermsAndConditionsClickListener {
    fun onGiveawayTermsAndConditionsClick(
        type: WidgetType,
        title: String,
        url: String?,
        videoInfo: VideoInfo
    )
}
```

**Parameters:**

* `type` - Widget type where the click occurred
* `title` - Title of the terms and conditions
* `url` - URL to the terms and conditions page (can be null)
* `videoInfo` - Context information about the current video

**Example:**

```kotlin
FireworkSdk.livestream.setOnGiveawayTermsAndConditionsClickListener { 
    type, title, url, videoInfo ->
    
    Log.d("Livestream", "T&C clicked: $title")
    Log.d("Livestream", "Widget type: $type")
    
    // Open terms and conditions in a custom WebView or browser
    url?.let { 
        openTermsAndConditions(it)
    } ?: run {
        showError("Terms and conditions not available")
    }
}
```

**Use Cases:**

* Open terms and conditions in a WebView
* Display terms in a custom dialog
* Track T\&C view analytics
* Enforce user agreement before giveaway entry

**Remove Listener:**

```kotlin
FireworkSdk.livestream.setOnGiveawayTermsAndConditionsClickListener(null)
```

***

## Username Update Listener

### setOnUpdateUsernameListener()

Monitors username update results (success or failure).

**Signature:**

```kotlin
fun setOnUpdateUsernameListener(listener: OnUpdateUsernameListener?)
```

**Listener Interface:**

```kotlin
interface OnUpdateUsernameListener {
    fun onUsernameUpdateSuccessfully(videoInfo: VideoInfo, username: String)
    
    fun onUsernameUpdateFailed(videoInfo: VideoInfo, username: String?, error: String?)
}
```

### onUsernameUpdateSuccessfully()

Called when username is updated successfully.

**Parameters:**

* `videoInfo` - Context information about the current video
* `username` - The new username that was set

**Example:**

```kotlin
override fun onUsernameUpdateSuccessfully(videoInfo: VideoInfo, username: String) {
    Log.d("Livestream", "Username updated to: $username")
    
    // Show success message
    showToast("Username updated to $username")
    
    // Save to preferences
    saveUsername(username)
    
    // Update UI
    updateUserProfileDisplay(username)
}
```

### onUsernameUpdateFailed()

Called when username update fails.

**Parameters:**

* `videoInfo` - Context information about the current video
* `username` - The username that failed to update (can be null)
* `error` - Error message describing why the update failed (can be null)

**Example:**

```kotlin
override fun onUsernameUpdateFailed(
    videoInfo: VideoInfo,
    username: String?,
    error: String?
) {
    Log.e("Livestream", "Failed to update username to: $username")
    Log.e("Livestream", "Error: $error")
    
    // Show error message
    val errorMsg = error ?: "Failed to update username"
    showError(errorMsg)
    
    // Revert UI changes
    revertUsernameDisplay()
}
```

**Complete Example:**

```kotlin
FireworkSdk.livestream.setOnUpdateUsernameListener(object : Livestream.OnUpdateUsernameListener {
    override fun onUsernameUpdateSuccessfully(videoInfo: VideoInfo, username: String) {
        // Handle success
        showToast("Welcome, $username!")
        saveUsernameToPreferences(username)
    }
    
    override fun onUsernameUpdateFailed(
        videoInfo: VideoInfo,
        username: String?,
        error: String?
    ) {
        // Handle failure
        val message = error ?: "Username update failed"
        showErrorDialog(message)
    }
})
```

**Remove Listener:**

```kotlin
FireworkSdk.livestream.setOnUpdateUsernameListener(null)
```

***

## VideoInfo Context

All callbacks provide a `VideoInfo` object containing context about the current video:

```kotlin
data class VideoInfo(
    val videoId: String,           // Unique video identifier
    val channelId: String?,        // Channel identifier
    val title: String?,            // Video title
    val description: String?,      // Video description
    val thumbnailUrl: String?,     // Thumbnail image URL
    // ... additional properties
)
```

**Common Uses:**

* Track analytics with video context
* Implement video-specific logic
* Display video information in custom UI
* Link interactions to specific content

***

## Best Practices

### Return Values

* **Return `true`** when you handle the interaction completely and want to prevent default SDK behavior
* **Return `false`** when you want SDK to handle the interaction after your custom logic

### Performance

* Keep callback implementations lightweight
* Avoid blocking operations
* Use coroutines for async work
* Cache frequently accessed data

## Related Documentation

* [Livestream Overview](/firework-for-developers/android-sdk/integration-guide/livestream.md) - Complete livestream integration guide
* [Livestream Chat](/firework-for-developers/android-sdk/integration-guide/livestream/livestream-chat.md) - Chat management and username configuration
* [FireworkSdk API Reference](/firework-for-developers/android-sdk/integration-guide/firework-sdk-api.md) - Complete API documentation
* [Getting Started](/firework-for-developers/android-sdk/integration-guide/getting-started.md) - SDK initialization

## API Summary

| Callback                                         | Description                  | Return Type |
| ------------------------------------------------ | ---------------------------- | ----------- |
| `setOnLinkClicked()`                             | Handle link clicks           | `void`      |
| `setOnInteractionListener()`                     | Handle all user interactions | `void`      |
| `onUserSubmitAnswerToQuestion()`                 | Handle question submissions  | `Boolean`   |
| `onUserSelectOptionForPoll()`                    | Handle poll votes            | `Boolean`   |
| `onUserJoinGiveaway()`                           | Handle giveaway entries      | `Boolean`   |
| `onUserSendMessage()`                            | Handle chat messages         | `Boolean`   |
| `onUserSendLike()`                               | Handle like actions          | `Boolean`   |
| `setOnGiveawayTermsAndConditionsClickListener()` | Handle T\&C clicks           | `void`      |
| `setOnUpdateUsernameListener()`                  | Monitor username updates     | `void`      |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.firework.com/firework-for-developers/android-sdk/integration-guide/livestream/livestream-callbacks.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
