Messaging
This document explains how to use the IMLib SDK to send and receive ultra group messages. For ultra group messaging, you need to use methods from RongCoreClient.
Prerequisites
We recommend reading Ultra Group Overview and Ultra Group Private Channel Overview first to understand how to use channels and ultra group channel features in your app.
- Create an ultra group via server API [Create Ultra Group]
- Create a channel via server API [Create Channel], or use the default channel ID
RCDefault - Add the sender to the ultra group via server API [Join Ultra Group]
- If unsure whether the sender is in the ultra group, query via server API [Check Group Membership]
- When sending messages to private channels in ultra groups, ensure members are added via server API [Add Private Channel Members]
When users send/receive messages in the current channel chat UI, you must verify both the ultra group targetId and channelId. The message should only be displayed in the current channel UI if both the ultra group targetId and channelId match the current channel. Otherwise, it should be ignored. If messages appear in wrong chat UIs, this typically indicates incorrect ultra group ID or channel ID.
Receiving Messages
The message receiving interface for ultra group conversations is identical to one-to-one and group chats. For implementation details, refer to [Receiving Messages].
Ultra group conversations don't support offline messages. To retrieve messages received while offline, you need to fetch historical messages based on the last message in the ultra group conversation.
Constructing Message Objects
Before sending messages, you need to construct a [Message] object. The message's conversationType field must be set to ConversationType.ULTRA_GROUP for ultra group conversations. The targetId field represents the ultra group ID, while channelId represents the ultra group channel ID.
The [Message] class defined in IMLib SDK contains two main types of message content: regular message content and media message content.
Regular message content inherits from MessageContent, such as text messages ([TextMessage]).
String targetId = "Ultra Group ID";
ConversationType conversationType = Conversation.ConversationType.ULTRA_GROUP;
String channelId = "Ultra Group Channel ID";
TextMessage messageContent = TextMessage.obtain("Test Ultra Group");
Message message = Message.obtain(targetId, conversationType, channelId, messageContent);
Media message content inherits from MediaMessageContent, such as image messages ([ImageMessage]), GIF messages ([GIFMessage]), etc.
String targetId = "Ultra Group ID";
ConversationType conversationType = Conversation.ConversationType.ULTRA_GROUP;
String channelId = "Ultra Group Channel ID";
Uri localUri = Uri.parse("file://image_path");//Local image path, recipients can get auto-generated thumbnail Uri via getThumUri
boolean mIsFull = true; //Whether to send original image
ImageMessage mediaMessageContent = ImageMessage.obtain(localUri, mIsFull);
Message message = Message.obtain(targetId, conversationType, channelId, mediaMessageContent);
- Use
sendMessagefor regular messages andsendMediaMessagefor media messages. - The client SDK enforces a message rate limit of 5 messages per second.
- For apps/environments where ultra group service was activated on or after 2022.10.13, ultra groups include a default channel with ID
RCDefault. Messages without specified channelId will be sent to this default channel. - For apps/environments where ultra group service was activated before 2022.10.13, messages without specified channelId won't belong to any channel. RC supports migrating to the new behavior, which affects multiple features including message sending/receiving, conversation retrieval, history clearing, and muting. Submit a ticket for migration details if needed.
Sending Regular Messages
Regular messages include text messages, quoted messages, and other non-media messages. Their content inherits from MessageContent, such as text messages ([TextMessage]) or custom regular message types.
String targetId = "Target ID";
ConversationType conversationType = ConversationType.ULTRA_GROUP;//Ultra group conversation type
String channelId = "Target Channel ID";
TextMessage content = TextMessage.obtain("This is a text message");
Message message = Message.obtain(targetId, conversationType, channelId, content);
To send ultra group regular messages, use the sendMessage method from RongCoreClient.
Interface
RongCoreClient.getInstance().sendMessage(message, pushContent, pushData, callback);
Parameters
| Parameter | Type | Description |
|---|---|---|
| message | [Message] | The message object to send. Must specify conversationType, targetId, and messageContent. See [Message Introduction]. |
| pushContent | String | Customizes push notification content displayed in the notification bar. Can also be configured in the message's push attributes (MessagePushConfig), which will override this setting. See Custom Push Notifications.
|
| pushData | String | Additional push notification data. Recipients can retrieve this via:
MessagePushConfig), which will override this setting. See [Custom Push Notifications]. |
| callback | [ISendMessageCallback] | Callback for sending media messages |
Example Code
RongCoreClient.getInstance().sendMessage(message, null, null, new IRongCoreCallback.ISendMessageCallback() {
@Override
public void onAttached(Message message) {
}
@Override
public void onSuccess(Message message) {
}
@Override
public void onError(Message message, IRongCoreEnum.CoreErrorCode errorCode) {
}
});
:::tip
- For how to customize offline push notifications received by recipients, see [Remote Notifications](#remote-notifications) below.
- Custom message types do not support offline message-to-push conversion by default. If support is needed, see [How to Enable Remote Push for Custom Messages](#how-to-enable-remote-push-for-custom-messages) below.
:::
## Sending Media Messages
The `content` field of the media message `Message` object must contain a subclass object of [MediaMessageContent], representing the media message content. For example, image message content ([ImageMessage]), GIF message content ([GIFMessage]), or custom media message content that inherits from [MediaMessageContent].
Image messages ([ImageMessage]) support sending the original image.
```java
String targetId = "Target ID";
ConversationType conversationType = ConversationType.ULTRA_GROUP; // Ultra group conversation type
String channelId = "Target channel ID";
Uri localUri = Uri.parse("file://path_to_image"); // Local path of the image. The recipient can obtain the automatically generated thumbnail Uri via getThumUri
boolean mIsFull = true; // Whether to send the original image
ImageMessage mediaMessageContent = ImageMessage.obtain(localUri, mIsFull);
Message message = Message.obtain(targetId, conversationType, channelId, mediaMessageContent);
To send media messages in an ultra group, use the `sendMediaMessage` method in [RongCoreClient](https://doc.rongcloud.cn/apidoc/imlibcore-android/latest/zh_CN/html/-android--i-m-lib-core--s-d-k/io.rong.imlib/-rong-core-client/index.html). The SDK will generate thumbnails for images, short videos, etc., compress them according to the [default compression settings](https://help.rongcloud.cn/t/topic/1041), upload the media files to RC's default file server ([file storage duration](https://help.rongcloud.cn/t/topic/1049)), and send the message after successful upload. If an image message is set to send the original image, it will not be compressed.
##### Interface
```java
RongCoreClient.getInstance().sendMediaMessage(message, pushContent, pushData, callback);
#### Parameter Description
| Parameter | Type | Description |
|:------------|:----------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| message | [Message] | The message entity to be sent. The message entity must specify the conversation type (`conversationType`), target ID (`targetId`), and message content (`messageContent`). For details, see [Message Introduction]. |
| pushContent | String | Modify or specify the content displayed in the remote push notification bar. You can also configure this in the push attributes (`MessagePushConfig`) of `Message`, which will override the configuration here. For details, see [Custom Message Push Notification](../message/send.md#remote-notifications).<ul><li>If you want to use RC's default push notification content, you can enter `nil`. Note that custom message types have no default value.</li><li>If you want to specify personalized offline push notifications for this message, you must provide the `pushContent` field content to RC in either of the above places.</li><li>If your custom message type requires offline push services, you must provide the `pushContent` field content to RC in either of the above places; otherwise, users will not receive offline push notifications.</li></ul> |
| pushData | String | Additional information for remote push. When the recipient receives the remote push message, they can obtain this field content via the following method:<p>`io.rong.push.notification.PushNotificationMessage#getPushData()`</p>. You can also configure this in the push attributes (`MessagePushConfig`) of `Message`, which will override the configuration here. For details, see [Custom Message Push Notification]. |
| callback | [ISendMediaMessageCallback] | Callback for sending media messages |
#### Example Code
```java
RongCoreClient.getInstance().sendMediaMessage(message, null, null, new IRongCoreCallback.ISendMediaMessageCallback() {
@Override
public void onProgress(Message message, int i) {
}
@Override
public void onCanceled(Message message) {
}
@Override
public void onAttached(Message message) {
}
@Override
public void onSuccess(Message message) {
}
@Override
public void onError(final Message message, final IRongCoreEnum.CoreErrorCode errorCode) {
}
});
### Sending Media Messages and Uploading to Your Own Server
}
@Override
public void onSuccess(Message message) {
}
@Override
public void onError(final Message message, final IRongCoreEnum.CoreErrorCode errorCode) {
}
});
### Sending Media Messages and Uploading to Your Own Server
You can directly send files hosted on your own server. Pass the URL (indicating its location) of the media file as a parameter when constructing the media message content. In this case, your file will not be hosted on RC servers. When sending file messages with remote URLs, there are no file size restrictions, and you can directly use the `sendMessage` method to send the message.
If you want the SDK to send the message after successful upload, you can use the `sendMediaMessage` method. Implement the media file upload yourself in the `onAttached` callback method of the [ISendMediaMessageCallbackWithUploader] interface, and notify the SDK upon successful upload by providing the remote address of the media file. The SDK will send the message after receiving the upload success notification.
```java
String path = "file://path_to_image";
Uri localUri = Uri.parse(path);
ConversationType conversationType = ConversationType.ULTRA_GROUP;//Ultra group conversation type
String targetId = "Target ID";
ImageMessage imageMessage = ImageMessage.obtain(localUri, localUri);
Message message = Message.obtain(targetId, conversationType, imageMessage);
IRongCoreCallback.ISendMediaMessageCallbackWithUploader sendMediaMessageCallbackWithUploader =
new IRongCoreCallback.ISendMediaMessageCallbackWithUploader() {
@Override
public void onAttached(
Message message, IRongCoreCallback.MediaMessageUploader uploader) {
/*Upload image to your own server*/
uploadImg(imgMsg.getPicFilePath(), new UploadListener() {
@Override
public void onSuccess(String url) {
// Upload successful, call SDK's success method and pass the remote image address
uploader.success(Uri.parse(url));
}
@Override
public void onProgress(float progress) {
//Update upload progress
uploader.update((int) progress);
}
@Override
public void onFail() {
// Image upload failed, call error method.
uploader.error();
}
});
}
@Override
public void onError(
final Message message, final IRongCoreEnum.CoreErrorCode coreErrorCode) {
//Sending failed
}
@Override
public void onProgress(Message message, int progress) {
//Sending progress
}
@Override
public void onSuccess(Message message) {
//Sending successful
}
@Override
public void onCanceled(Message message) {
//Sending canceled
}
};
RongCoreClient.getInstance().sendMediaMessage(
message, pushContent, pushData, sendMediaMessageCallbackWithUploader);
Both `sendMessage` and `sendMediaMessage` directly provide parameters for controlling push notification content (`pushContent`) and push additional information (`pushData`). However, if you need more granular control over offline push notifications, such as titles, content, icons, or other third-party vendor-specific configurations, use message push attributes for configuration. See [Custom Message Push Notifications] for details.
- If the sent message belongs to SDK's built-in message types, such as [ImageMessage], these parameters can be set to `null`. When the message triggers an offline push notification, RC servers will use the default `pushContent` values for each built-in message type. For default push notification content of various message types, see [User Content Message Formats].
- If the message type is a custom message type and needs to support offline push notifications, you must provide the `pushContent` field to RC, otherwise users will not receive offline push notifications.
- If the message type is a custom message type but does not need to support remote push notifications (such as app business layer operation instructions implemented through custom message types), you can leave the `pushContent` field empty.
- The `pushContent` and `pushData` configurations in `MessagePushConfig` of `Message` will override the configurations here and provide more configuration capabilities, such as custom push notification titles. See [Custom Message Push Notifications] for details.
## How to Send @ Messages \{#mentionedinfo}
@ messages are not a predefined message type in RC IM services (see server documentation [Message Type Overview]). You can implement the function of mentioning (@) others by setting `mentionedInfo` data in the message.
You can set information about mentioned (@) persons in the [MentionedInfo] field of the message's `MessageContent`. Both SDK built-in message types and your custom message types directly or indirectly inherit from the [MessageContent] class, so they all support setting mentioned (@) person information.
`MentionedInfo` parameters:
| Parameter | Type | Description |
|:-----------------|:---------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| type | MentionedType | (Required) Specifies the type of `MentionedInfo`. `MentionedType.ALL` means everyone needs to be mentioned (@). `MentionedType.PART` means only some people need to be @, and the mentioned persons must be specified in `userIdList`. |
| userIdList | List\<String\> | Collection of user IDs to be mentioned (@). Required when `type` is `MentionedType.PART`. |
| mentionedContent | String | Content displayed in the notification bar when triggering offline message push. If `NULL`, the default prompt ("Someone @ you") will be displayed. The `mentionedContent` carried by @ messages has the highest priority and will override all default or custom `pushContent` data. |
The following example shows sending a text message mentioning some users to an ultra group conversation.
```java
List<String> userIdList = new ArrayList<>();
userIdList.add("userId1");
userIdList.add("userId2");
MentionedInfo mentionedInfo = new MentionedInfo(MentionedInfo.MentionedType.PART, userIdList, null);
TextMessage messageContent = TextMessage.obtain("Text message");
messageContent.setMentionedInfo(mentionedInfo);
Message message = Message.obtain(targetId, conversationType, channelId, messageContent);
RongCoreClient.getInstance().sendMessage(message, null, null, new IRongCoreCallback.ISendMessageCallback() {
@Override
public void onAttached(Message message) {
}
@Override
public void onSuccess(Message message) {
}
@Override
public void onError(Message message, IRongCoreEnum.CoreErrorCode errorCode) {
}
});
After receiving the message, the IMLib SDK needs to process the @ message data. You can obtain the `MentionedInfo` object carried by the message object through the following methods after getting the `Message` (message object).
```java
MentionedInfo mentionedInfo = message.getContent().getMentionedInfo();
## Remote Push Notifications
If your application has configured third-party push notifications with RC, when the message recipient is offline, the RC server will determine whether to trigger remote push notifications based on message type, recipient's supported push channels, and recipient's Do Not Disturb settings.
Remote push notifications are typically displayed in the system notification bar. RC's built-in message types will by default show notification titles and content in the notification bar. For default push notification content formats of each message type, refer to [User Content Message Formats].
### Configuring Push Notification Attributes
If you need customized offline push notifications, you can modify or specify the notification title, content, and other attributes through the following methods:
- Control push notification content by setting the `pushContent` parameter in the input parameters of [sendMessage] and [sendMediaMessage] methods.
- If you need to control more attributes of offline push notifications, such as title, content, icon, or customized configurations based on third-party vendor channels, use the push attributes ([MessagePushConfig]) of the [Message] object for configuration.
:::tip
Compared to the `pushContent` and `pushData` parameters when sending messages, the configurations in `MessagePushConfig` have higher priority. When sending messages, if you have configured the `messagePushConfig` attribute of `Message`, the configurations in `messagePushConfig` will be used first.
:::
You can provide `MessagePushConfig` configurations when sending messages to customize push behavior for individual messages. For example:
- Customize push title and notification content
- Customize notification bar icons
- Add additional information to remote push notifications
- Bypass client-side configurations and force display of notification content in push notifications
- Other customized configurations supported by APNs or Android push channels
For configuration methods of `MessagePushConfig`, refer to [Custom Message Push Notifications].
### How Custom Messages Support Remote Push Notifications
The IMLib SDK implements remote notification titles and content for built-in message types (refer to [User Content Message Formats]). If you are sending custom message types, you need to provide the `pushContent` field yourself; otherwise, recipients will not receive offline push notifications. Specifically:
- If the message type is custom and needs to support offline push notifications, you must provide the `pushContent` field to the IMLib SDK through the input parameters or push attributes of the message; otherwise, users will not receive offline push notifications.
- If the message type is custom but does not need to support remote push notifications (e.g., app business layer operation commands implemented through custom message types), you can leave the `pushContent` field empty.
## Disabling Push Notifications for Messages
When recipients are offline, the RC server will by default trigger push services to deliver messages through push channels (whether the server triggers push notifications is also affected by application-level and user-level Do Not Disturb settings).
Your app users may wish to specify that certain messages should not trigger push notifications when sending them. This requirement can be achieved by configuring the `MessageConfig` of the `Message` object.
In the following example, we set the `disableNotification` of `messageConfig` to `true` to disable push notifications for this message. The recipient will need to actively pull the message when they come back online.
```java
String targetId = "Target ID";
String channelId = "Target Channel ID";
ConversationType conversationType = ConversationType.ULTRA_GROUP;
TextMessage messageContent = TextMessage.obtain("Message content");
Message message = Message.obtain(targetId, conversationType, channelId, messageContent);
message.setMessageConfig(new MessageConfig.Builder().setDisableNotification(true).build());
## How to Transmit Custom Data
If you need to transmit custom data to the other end, you can achieve this through the following methods:
- The extra field in the message content [MessageContent], **this field will be sent to the other end along with the instant message**. After receiving the message online, the recipient can obtain this field from the message content. Note that this is different from the extra field of `Message`; the extra field of `Message` is a local operation field and will not be sent to the server.
- Additional information for remote push notifications `pushData`. You can directly set `pushData` in the input parameters of [sendMessage] and [sendMediaMessage], or use the field with the same name in the message push attributes; the `pushData` in the latter will override the former.
:::tip
**`pushData` will only be delivered to the other end's device when the message triggers offline remote push notifications**. When the other end receives the remote push notification, they can obtain the transmitted data content through the `appData` field in the push data. For details, refer to **Obtaining Push Data** in [Integrating Remote Push Notifications](/android-imlib/push/overview).
:::
## Handling Message Sending Failures
For message types that are stored locally on the client (refer to [Message Type Overview]), if the (`onAttached`) callback is triggered, it means the message has been stored in the local database and entered the local message list.
- If storage fails, you can check whether the parameters are valid and whether the device storage can be written normally.
- If storage is successful but message sending fails (`onError`), the app can temporarily display this failed message in the UI and cache the `Message` instance thrown by `onError`, then call `sendMessage` / `sendMediaMessage` again at an appropriate time to resend. Note that if you do not reuse this message instance but resend a new message with the same content, the local message list will store two duplicate messages.
For messages that are not stored locally on the client, if sending fails (`onError`), the app can cache the message instance and retry sending, or directly create a new message instance for sending.