Android
Open Channel Advanced

Open Channel: Advanced

This page explains the advanced features for open channels. Some of them are the premium features available only to a paying user.


Send an admin message

If you are using the Custom Plan, you can send an admin message to an open channel using Sendbird Dashboard or Chat Platform API. To send the admin message through your dashboard, on the Chat > Open channels, select an open channel, find a message box below, click the Admin message tab, and then write your message in the box. An admin message is limited to 1,000 characters.

Note: For clients using the Free Plan, a suggesting message to upgrade to the Custom Plan will be returned when attempting to send an admin message using the Chat API.


Add extra data to a message

You have the option to create further actions in a channel by using extra data in a message. You can add one or more key-values items to a message which you can save, update, or remove, when necessary. Based on those items, you can design and implement several different actions such as measuring user engagement within a chosen time limit through polls or counting how many times a message has been copied by participants.

Note: For the quality of performance, every Sendbird application has its own limits to how many key-values items you can add to a single message, as well as the maximum number of values an item can have. If you would like more information on these limits, contact our sales team.

Light Color Skin
Copy
// When a message has been successfully sent to a channel, create items with keys.
List<String> itemKeysToCreate = new ArrayList<>();
itemKeysToCreate.add("referees");
itemKeysToCreate.add("games");

openChannel.createMessageMetaArrayKeys(BASE_MESSAGE, itemKeysToCreate, new BaseChannel.MessageMetaArrayHandler() {
    @Override
    public void onResult(BaseMessage baseMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

// Adding values to specific items by their keys.
List<String> people = new ArrayList<>();
people.add("John");
people.add("Brandon");
people.add("Harry");
people.add("Jay");

List<String> event = new ArrayList<>();
events.add("soccer");
events.add("baseball");
events.add("basketball");

Map<String, List<String>> valuesToAdd = new HashMap<>();
valuesToAdd.put("referees", people);
valuesToAdd.put("games", events);

openChannel.addMessageMetaArrayValues(BASE_MESSAGE, valuesToAdd, new BaseChannel.MessageMetaArrayHandler() {
    @Override
    public void onResult(BaseMessage baseMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

// Removing existing values of specific items by their keys.
List<String> notAvailablePeople = new ArrayList<>();
notAvailablePeople.add("Brandon");
notAvailablePeople.add("Jay");

Map<String, List<String>> valuesToRemove = new HashMap<>();
valuesToRemove.put("referees", notAvailablePeople);

openChannel.removeMessageMetaArrayValues(BASE_MESSAGE, valuesToRemove, new BaseChannel.MessageMetaArrayHandler() {
    @Override
    public void onResult(BaseMessage baseMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});


// Deleting items by their keys.
List<String> itemKeysToDelete = new ArrayList<>();
itemKeysToDelete.add("referees");
itemKeysToDelete.add("games");

openChannel.deleteMessageMetaArrayKeys(BASE_MESSAGE, itemKeysToDelete, new BaseChannel.MessageMetaArrayHandler() {
    @Override
    public void onResult(BaseMessage baseMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

To get the key-values items of a message, use the message.getAllMetaArrays() method.


Display Open Graph tags in a message

The Chat SDK supports the URL link preview when a message text contains the URL of a web page.

Note: Starting in 2021, this feature will be turned on by default. For the time being, contact our support team to enable the feature.

OGMetaData for Android

OGMetaData

OGMetaData is a class that holds the Open Graph (OG) protocol-related data, including the four properties: title, URL, description, and image of an OG object.

Note: Some websites don’t provide the OG metadata fields mentioned above. In that case, even though the Open Graph protocol states them as requirements, all of the four getter methods may return null.

MethodDescription

getTitle()

Returns the title of the OG object as it should appear within the graph. The value can be null.

getUrl()

Returns the canonical URL of the object that can be used as its permanent ID in the graph. The value can be null.

getDescription()

Returns the description of the object. The value can be null.

getOGImage()

Returns an OGImage object that contains information about the image that this Open Graph points to. The OGImage also holds its own properties such as type, URL, and size. However, the value can be null.

OGImage

OGImage is a class that holds image-related data for an OGMetaData object. The OGImage class can also have six optional structured properties of URL, secure URL, type, width, height, and alt.

Note: Except for width and height, other fields such as URL, secure URL, type, and alt can be null. Width and height are set to 0 if the target website doesn’t provide such data.

MethodDescription

getUrl()

Returns the URL of an image object within the Open Graph. The value can be null.

getSecureUrl()

Returns an alternative url to use if the webpage requires HTTPS. The value can be null.

getType()

Returns a media type or MIME type of this image. The value can be null.

getWidth()

Returns the number of pixels horizontal. When the value is unavailable, this method returns 0.

getHeight()

Returns the number of pixels vertical. When the value is unavailable, this method returns 0.

getAlt()

Returns a description of what is in the image, not a caption of the image. The alt attribute is designed to provide a fuller context of the OGImage object and help users better understand it when they can’t load or see the image. The value can be null.

How it works

If a user sends a message with a web page URL and the linked web page possesses Open Graph (OG) tags, or OG metadata, Sendbird server parses the message content, extracts the URL in the message, gets the OG metadata from it, and creates an OG metadata object for the message. Then message recipients will get the parsed message with its OG metadata object through the onMessageReceived() method in the channel event handler of the SDK. On the other hand, the message sender will do the same through the onMessageUpdated().

Displaying an OG metadata object is available for two subtypes of BaseMessage: UserMessage and AdminMessage. If the content of a BaseMessage object includes a web page URL containing OG metadata, the BaseMessage.getOgMetaData() method returns OGMetaData and OGImage objects.

If Sendbird server doesn’t have cache memory of the OG metadata of the given URL, the BaseMessage.getOgMetaData() method can return null due to the time it takes to fetch the OG metadata from the corresponding remote web page. In the meantime, the message text containing the URL will be delivered first to message recipients’ client app through the onMessageReceived() method. When the server completes fetching, the onMessageUpdated() method will be called and the message with its OG metadata object will be delivered to the recipients’ client app. However, if Sendbird server has already cached the OG metadata of the URL, the BaseMessage.getOgMetaData() method returns the message and its OGMetaData object instantly and the onMessageUpdated() method won’t be called.

Light Color Skin
Copy
// Send a user message containing the URL of a web page.
UserMessageParams params = new UserMessageParams()
        .setMessage("sendbird.com")
        ...

openChannel.sendUserMessage(params, new BaseChannel.SendUserMessageHandler() {
    @Override
    public void onSent(UserMessage userMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});
Light Color Skin
Copy
// Receive a user message containing OG metadata of the web page through a channel event handler.
SendBird.addChannelHandler(UNIQUE_HANDLER_ID, new SendBird.ChannelHandler() {
    @Override
    public void onMessageReceived(BaseChannel channel, BaseMessage message) {
        final OGMetaData ogMetaData = message.getOgMetaData();
        if (ogMetaData == null) {
            // The getOgMetaData() returns null if the message doesn’t have an OGMetadata object yet.
            return;
        } else {
            // TODO: Your custom implementation for the Open Graph metadata of the message.
            String url = ogMetaData.getUrl();
            int width = ogMetaData.getWidth();
            ...

        }
        ...
    
    }

    @Override
    public void onMessageUpdated(BaseChannel channel, BaseMessage message) {
        final OGMetaData ogMetaData = message.getOgMetaData();
        if (ogMetaData == null) {
            return;
        } else {    
            // TODO: Your custom implementation for the Open Graph metadata of the message.
            String url = ogMetaData.getUrl();
            int width = ogMetaData.getWidth();
            ...

        }
        ...
    
    }
});

Categorize channels by custom type

When creating a channel, you can additionally specify a custom channel type for further channel grouping. This custom type takes on the form of a String, and can be handy in searching or filtering channels.

Note: The DATA and CUSTOM_TYPE are both String fields that allow you to append information to your channels. As mentioned above, a common use case for the CUSTOM_TYPE is to contain information for channel grouping (for example, categorizing into School and Work channels). However, both these fields can be flexibly utilized.

Light Color Skin
Copy
OpenChannel.createChannel(NAME, COVER_IMAGE_OR_URL, DATA, OPERATOR_USERS, CUSTOM_TYPE, new OpenChannel.OpenChannelCreateHandler() {
    @Override
    public void onResult(OpenChannel openChannel, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

To get a channel's custom type, use the openChannel.getCustomType() method.


Categorize messages by custom type

When sending a message, you can additionally specify a custom message type for further message grouping. This custom type takes on the form of a String, and can be useful in searching or filtering messages.

Note: The DATA and CUSTOM_TYPE are both String fields that allow you to append information to your messages. As mentioned above, a common use case for the CUSTOM_TYPE is to contain information for message grouping (for example, categorizing into Notes and Contacts messages). However, both these fields can be flexibly utilized.

To embed a custom type into a message, set a value of the type to a UserMessageParams or FileMessageParams object, and then pass the object as an argument to a parameter in the sendUserMessage() or sendFileMessage() methods.

Light Color Skin
Copy
UserMessageParams params = new UserMessageParams()
    .setMessage(TEXT_MESSAGE)
    .setCustomType(CUSTOM_TYPE)
    ...

openChannel.sendUserMessage(params, new BaseChannel.SendUserMessageHandler() {
    @Override
    public void onSent(UserMessage userMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

To get a message's custom type, use the message.getCustomType() method.


Search channels by name, URL, or custom type

You can search for specific open channels by adding keywords to an OpenChannelListQuery instance. There are two types of keywords: a Name and a URL. The code sample below shows the query instance which returns a list of open channels that partially match the specified Name keyword in the names of the channels.

Light Color Skin
Copy
channelListQuery = OpenChannel.createOpenChannelListQuery();
channelListQuery.setNameKeyword("Sendbird");

channelListQuery.next(new OpenChannelListQuery.OpenChannelListQueryResultHandler() {
    @Override
    public void onResult(List<OpenChannel> openChannels, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
        // A list of open channels that have "Sendbird" in their names is returned.
    }
});

The following shows the query instance which returns a list of open channels that partially match the specified URL keyword in the URLs of the channels.

Light Color Skin
Copy
channelListQuery = OpenChannel.createOpenChannelListQuery();
channelListQuery.setUrlKeyword("seminar");

channelListQuery.next(new OpenChannelListQuery.OpenChannelListQueryResultHandler() {
    @Override
    public void onResult(List<OpenChannel> openChannels, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
        // A list of open channels that have "seminar" in their URLs is returned.
    }
});

Using the setCustomTypeFilter() like the following, you can also search for open channels with a specific custom type.

Light Color Skin
Copy
channelListQuery = OpenChannel.createOpenChannelListQuery();
channelListQuery.setCustomTypeFilter("movie");

channelListQuery.next(new OpenChannelListQuery.OpenChannelListQueryResultHandler() {
    @Override
    public void onResult(List<OpenChannel> openChannels, SendBirdException e) {
        if (e != null) {        // Error.
            return;
        }
        // A list of open channels with a "movie" custom type is returned.
    }
});

Generate thumbnails of a file message

When sending an image file, you can determine whether to create thumbnails of the image to fetch and render into your UI. You can specify up to 3 different dimensions to generate thumbnail images in for supporting various display densities.

Note: Supported file types are files whose media type is image/* or video/*. The Chat SDK doesn't support creating thumbnails when sending a file message via a file URL.

The sendFileMessage() method requires passing a FileMessageParams object as an argument to a parameter, containing an array of items which each specify the maximum values of width and height of a thumbnail image. The callback function subsequently returns a list of Thumbnail items that each contain the URL of the generated thumbnail image file.

Light Color Skin
Copy
// Create and add a ThumbnailSize object (allowed number of thumbnail images: 3).
List<FileMessage.ThumbnailSize> thumbnailSizes = new ArrayList<>();
thumbnailSizes.add(new ThumbnailSize(100,100));
thumbnailSizes.add(new ThumbnailSize(200,200));

FileMessageParams params = new FileMessageParams()
        ... 
        .setFile(FILE)
        .setFileName(FILE_NAME)
        .setFileSize(FILE_SIZE)
        .setMimeType(MIME_TYPE)
        .setThumbnailSizes(thumbnailSizes);

openChannel.sendFileMessage(params, new BaseChannel.SendFileMessageHandler() {
    @Override
    public void onSent(FileMessage fileMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }

        Thumbnail first = fileMessage.getThumbnails.get(0);
        Thumbnail second = fileMessage.getThumbnails.get(1);

        int maxHeightFirst = first.getMaxHeight(); // 100
        int maxHeightSecond = second.getMaxHeight(); // 200

        String urlFirst = first.getUrl(); // The URL of first thumbnail file.
        String urlSecond = second.getUrl(); // The URL of second thumbnail file.
    }
});

A thumbnail image is generated evenly to fit within the bounds of (maxWidth, maxHeight), which are provided through the ThumbnailSize constructor. Note that if the original image is smaller than the specified dimensions, the thumbnail isn't resized. getUrl() returns the location of the generated thumbnail file within Sendbird server.

This is one of Sendbird's premium features. Contact our sales team for further assistance.


Share an encrypted file with other participants

This file encryption feature prevents users without access from opening and reading encrypted files that have been shared within a group of users. When this feature is turned on, all types of sent files and thumbnail images will be first uploaded to Sendbird server, and then encrypted by AES256.

In an open channel, encrypted files and thumbnail images will be decrypted and accessed securely only by the participants. Anyone outside of the channel and application will not have access to those files and thumbnail images. The following explains how this data security works and what to do at the SDK level to apply it to your client apps.

The Sendbird system enables secure encryption and decryption of files by generating and distributing an opaque and unique encryption key for each user. An encryption key is managed internally by the system, and is valid for 3 days. It is generated every time the user logs in to Sendbird server through the Chat SDK, which then gets delivered to the Chat SDK from the server.

When the Chat SDK requests an encrypted file by its URL, the parameter auth should be added to the URL to access the file, which is specified with an encryption key of the user such as ?auth=RW5jb2RlIHaXMgdGV4eA==. With the specified key in the auth, Sendbird server first decrypts the file, then checks if the user is participating in the open channel, and finally, allows the user to access and open the file in the channel.

This can be easily done by using the fileMessage.getUrl() method, which automatically adds the parameter auth with an encryption key of the current user to the file URL, and returns the unique URL for the user.


Spam flood protection

This feature allows you to customize the number of messages a participant can send in an open channel per second. By doing so, all excess messages from a paricipant will be deleted and only the number of messages allowed to be sent per participant per second will be delivered. This feature protects your app from some participants spamming others in the channel with the same messages.

Note: Our default system setting is 5 messages per second. This limit can be manually adjusted only from our side. This is one of Sendbird's premium features. Contact our sales team for further assistance.


Smart throttling

You can use this feature to customize the number of messages displayed in an open channel per second. By doing so, you can adjust the pace of the conversation in a chat so that the participants can read the messages more clearly. In fact, each participant's channel will display the messages they have sent and those that other participants have sent up to this limit in chronological order.

Note: Our default system setting is 5 messages per second. This limit can be manually adjusted only from our side. This is one of Sendbird's premium features. Contact our sales team for further assistance.


Message auto-translation

It is possible for text messages to be sent in different languages through the Sendbird's auto-translation feature. When sending a text message, set a List of language codes to a UserMessageParams object and then pass the object as an argument to a parameter in the sendUserMessage() method to request translated messages in the corresponding languages.

Note: This message auto-translation feature is powered by Google Cloud Translation API recognition engine and Microsoft Translator engine. It is by default that Google's Cloud Translation API recognition engine is used for message auto-translation, whereas if your Sendbird application has been created before June 26, 2019, Microsoft Translator engine is used.

Light Color Skin
Copy
List<String> translationTargetLanguages = new ArrayList<>();
translationTargetLanguages.add("es");   // Spanish 
translationTargetLanguages.add("ko");   // Korean 

UserMessageParams params = new UserMessageParams()
        .setMessage(TEXT_MESSAGE)
        .setCustomType(CUSTOM_TYPE)
        .setData(DATA)
        ...
        .setTranslationTargetLanguages(translationTargetLanguages);

openChannel.sendUserMessage(params, new BaseChannel.SendUserMessageHandler() {
    @Override
    public void onSent(UserMessage userMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

You can retrieve translations of a text message using the userMessage.getTranslations() method which returns a Map object containing the language codes and translations.

Note: The two translation engines support a wide variety of languages, and you can see their language code tables in the Miscellaneous > Language support section.

Light Color Skin
Copy
SendBird.addChannelHandler(UNIQUE_HANDLER_ID, new SendBird.ChannelHandler() {
    @Override
    public void onMessageReceived(BaseChannel channel, BaseMessage message) {
        Map<String, String> map = ((UserMessage) message).getTranslations();
        String esTranslation = map.get("es");       // Spanish
        ...
        // TODO: Display translation in UI.
    }
}

This is one of Sendbird's premium features. Contact our sales team for further assistance.


Message on-demand translation

Using the openChannel.translateUserMessage() method, you can allow your users to translate text messages into other languages when needed.

Note: This message on-demand translation is powered by Google Cloud Translation API recognition engine, and you can see its language code table in the Miscellaneous > Language support section.

Light Color Skin
Copy
List<String> translationTargetLanguages = new ArrayList<>();
translationTargetLanguages.add("es");   // Spanish
translationTargetLanguages.add("de");   // German

// The USER_MESSAGE below indicates a UserMessage object which represents an already sent or received text message.
openChannel.translateUserMessage(USER_MESSAGE, translationTargetLanguages, new BaseChannel.TranslateUserMessageHandler() {
    @Override
    public void onTranslated(UserMessage userMessage, SendBirdException e) {
        Map<String, String> map = userMessage.getTranslations();
        String esTranslatedMessage = map.get("es");     // Spanish
        String deTranslatedMessage = map.get("de");     // German
        ...
        // TODO: Display translation in UI.
    }
}

Based on this method, you can implement features such as real-time or instant translation to your app. You can also implement to only translate a selected message into preferred languages.

This is one of Sendbird's premium features. Contact our sales team for further assistance.