Business Messaging Client Side v2
Business Messaging
Version 2

Render in-app channel

Copy link

If you integrated Business Messaging SDK to your client app, you need to combine templates with messages to render messages in an in-app channel. For SDK users, Data template contain information on how to render the message, while the message itself is the content that will be rendered using the template.

The process involves the following steps:

  • Step 1 Retrieve and cache templates.
  • Step 2 Retrieve the feed channel.
  • Step 3 Create a NotificationCollection.
  • Step 4 Retrieve messages using the NotificationCollection.
  • Step 5 Combine templates and messages for rendering.
  • Step 6 Refresh the collection when it's required.

Prerequisites

Copy link

Before reading this guide, it's important to get familiar with the structure and core functionalities of the Business Messaging SDK. If you're not, we recommend reading the following guide first:


Step 1 Retrieve and cache templates

Copy link

As a message doesn't contain any information on its design, you need to get its template first which contains information about the layout and rendering values of the message. You can retrieve the template using the SendbirdChat.getNotificationTemplateListByToken function. Once you retrieve the templates, you need to cache them. Caching the templates is important because if you retrieve the templates every time, it will slow down the rendering process.

From the SendbirdChat.getNotificationTemplateListByToken function, you get a jsonPayload that contains the list of templates. You can parse the jsonPayload to a Template object and store it in a list. the json payload looks like this:

{
    "templates": [
        {
            "key": "template_key",
            "name": "template_name",
            "created_at": 1725398032993,
            "updated_at": 1725398032993,
            "label": "label",
            "message_retention_hours": 4320,
            "ui_template": {
            },
            "data_template": {
                "key1": "value1"
            },
            "color_variables": {
            }
        }
    ],
    "next": "1725398032993472",
    "has_more": false
}

Here's the code snippet to retrieve and cache templates:

kotlinswift
SendbirdChat.getNotificationTemplateListByToken(
    token = null,
    NotificationTemplateListParams().apply { limit = 100 }
) { notificationTemplateList, _, token, e ->
    if (e != null) {
        // handler error
        return@getNotificationTemplateListByToken
    }
    
    let jsonPayload = notificationTemplateList?.jsonPayload
    val templateList = parseToTemplate(jsonPayload)
    cacheTemplateList(templateList)
}

Step 2 Retrieve feed channel

Copy link

Each feed channel represents a single in-app channel. A feed channel contains the following information, which can be used to render the channel UI.

Property nameDescription

url

The unique channel URL.

name

The topic or name of the channel.

unreadMessageCount

The unread message count for this channel for the current User.

isCategoryFilterEnabled

Weather the category filter is enabled or not.

isTemplateLabelEnabled

Weather the template label is enabled or not.

notificationCategories

The list of notification categories.

To retrieve the feed channel, you can use the FeedChannel.getChannel function. Channel url can be found in Sendbird Dashboard.

kotlinswift
FeedChannel.getChannel(channelURL) { channel, e ->
    if (e != null) {
        // TODO: handling error
        return@getChannel
    }

    // Use the channel object to render the channel UI
}

Step 3 Create NotificationCollection

Copy link

The NotificationCollection is a class that manages messages in a feed channel. It supports local caching (offline support). The process of creating and initializing a NotificationCollection is as follows.

kotlinswift
fun initializeNotificationCollection(feedChannel: FeedChannel) {
    val notificationCollection = feedChannel.createNotificationCollection(
        messageListParams = MessageListParams().copy(reverse = true),
        startingPoint = Long.MAX_VALUE
    )
    notificationCollection?.initialize(
        MessageCollectionInitPolicy.CACHE_AND_REPLACE_BY_API,
        object :
            MessageCollectionInitHandler {
            override fun onCacheResult(cachedList: List<BaseMessage>?, e: SendbirdException?) {
                // TODO: Update your UI based on the cached messages
            }
            override fun onApiResult(
                apiResultList: List<BaseMessage>?,
                e: SendbirdException?
            ) {
                // TODO: Update your UI based on the messages
            }
        })
}

Step 4 Retrieve messages using NotificationCollection

Copy link

After initializing the NotificationCollection, you can use loadNext or loadPrevious to fetch the next or previous messages. Typically, when the scroll is at the bottom, you would implement a call to loadPrevious to retrieve earlier messages.

kotlinswift
notificationCollection.loadNext { messages, e ->
   if (e != null) {
       // TODO handle error
   }
   
   // TODO: update your UI based on the new messages
}

Step 5 Combine templates and messages to render

Copy link

Once you have the templates and messages, you need to combine them to render the messages in the in-app channel. The dataTemplate in the template contains the key-value pairs that are used to render the message. The templateVariables in the message contains the key-value pairs that are used to render the message. You can use these key-value pairs to render the message.

kotlinswift
fun renderMessage(templates: List<Template>, message: BaseMessage) {
    val template = templates.find {
        it.key == message.notificationData.templateKey
    }

    // Retrieve data key/value pairs 
    val dataTemplate: Map<String, String> = template.dataTemplate
    val variables: Map<String, String> = message.notificationData.templateVariables
    
    // TODO: render message using dataTemplate and variable
}

Step 6 Refresh the collection when it's required.

Copy link

To support actions like pull-to-refresh, you need to refresh the collection. You can do this by calling the refreshNotificationCollection function, which will trigger the NotificationCollectionHandler.

kotlinSwift
val notificationCollectionHandler = object : NotificationCollectionHandler {
    override fun onMessagesAdded(context: NotificationContext, channel: FeedChannel, messages: List<BaseMessage>) {
       // TODO: Update your UI based on the new messages
       // Or you can utilize the whole message list to draw the whole messages
       // `collection.succeededMessages` will return the whole message list
    }

    override fun onMessagesUpdated(
        context: NotificationContext,
        channel: FeedChannel,
        messages: List<BaseMessage>
    ) {
       // TODO: Update your UI based on the updated messages
       // Or you can utilize the whole message list to draw the whole messages
       // `collection.succeededMessages` will return the whole message list
    }

    override fun onMessagesDeleted(
        context: NotificationContext,
        channel: FeedChannel,
        messages: List<BaseMessage>
    ) {
       // TODO: Update your UI based on the deleted messages
       // Or you can utilize the whole message list to draw the whole messages
       // `collection.succeededMessages` will return the whole message list
    }

    override fun onChannelUpdated(context: FeedChannelContext, channel: FeedChannel) {
       // TODO: Update your feed channel view based on the updated channel
    }
    override fun onChannelDeleted(context: FeedChannelContext, channelUrl: String) {
       // TODO: Invalidate your feed channel view based on the deleted channel
    }
    override fun onHugeGapDetected() {
       // TODO: Need to draw whole messages again
    }
}
collection.notificationCollectionHandler = notificationCollectionHandler

// Call this when you need to refresh the collection
SendbirdChat.refreshNotifiactionCollection()