The ZIM SDK supports the functionality of replying to messages within a session, which means quoting a received message to provide a targeted response and forming a tree-like structure of message replies starting from that message. With this feature, users can ask questions, provide feedback, or provide additional background information in response to a specific message.
This feature involves the following concepts:
Using messages A, B, and C in group chat as examples:
Before implementing the "Reply to a message" feature, make sure:
After logging in to ZIM, users can listen to the receivePeerMessage and onReceiveGroupMessage callback to receive new messages from one-on-one and group conversations, or call the queryHistoryMessage interface to fetch historical messages.
At this point, users can choose a message to reply to by using that message as the toOriginMessage
parameter and constructing a new message as the message
parameter. Then, call the replyMessage interface.
Only the following types are supported for the toOriginMessage
and message
parameters:
In addition to the required parameters mentioned above, you can also construct a notification
object based on your business needs and listen to the following callbacks:
The result of the transmission will be returned through ZIMMessageSentResult.
// The source message object, obtained through queryHistoryMessage or receivePeerMessage and receiveGroupMessage.
var toOriginMessage = {};
var config = {
priority: 1, // Set message priority, values are low: 1 (default), medium: 2, high: 3
};
var messageTextObj = { type: 1, message: 'Reply message content' };
var notification = {
onMessageAttached: function(message) {
// todo: Loading
},
onMediaUploadingProgress: (message, currentFileSize, totalFileSize) => {
// If the reply is a media message, you can use this to display the file upload progress.
},
}
zim.replyMessage(messageTextObj, toOriginMessage, config, notification)
.then(function ({ message }) {
// Sent successfully
})
.catch(function (err) {
// Failed to send
});
When receiving new messages in one-on-one and group conversations through the receivePeerMessage and receiveGroupMessage callbacks, you need to determine if the message has repliedInfo (basic information of the source message):
When you have the repliedInfo, you can use it to display the sender, sending time, and message content of the source message.
// Receive a message in a one-to-one conversation
zim.on('receivePeerMessage', function (zim, { messageList, fromConversationID }) {
messageList.forEach((msg) => {
if (msg.repliedInfo) {
// Basic information of the source message referenced by this reply, used to display the sender, sending time, and message content of the source message.
}
});
});
// Receive a message in a group conversation
zim.on('receiveGroupMessage', function (zim, { messageList, fromConversationID }) {
messageList.forEach((msg) => {
if (msg.repliedInfo) {
// Basic information of the source message referenced by this reply, used to display the sender, sending time, and message content of the source message.
}
});
});
ZIM supports actively or passively obtaining the number of replies to a root message.
To actively retrieve the number of replies to a root message, you can directly use ZIMMessage > rootRepliedCount to get it.
To get real-time updates on how many replies a root message has received, you can listen for the messageRepliedCountChanged event.
// Listen for changes in the number of replies to a root message
// Event trigger: When a new message replied to another message successfully, the number of replies to the root message of its reply tree will increase by 1
zim.on('messageRepliedCountChanged', function (zim, { infos }) {
infos.forEach(({ count, messageID, conversationID, conversationType }) => {
// Update the rootRepliedCount of the corresponding messageID in the conversation
});
});
Listen for the messageRepliedInfoChanged callback to get the list of child messages of a message when it is deleted or recalled. You can display relevant prompts on the UI of the corresponding child messages.
Even if the source message is deleted by the user on a device, causing the repliedInfo.state (the state of the source message) of its child message to be ZIMMessageRepliedInfoState.Deleted, you can still get the brief content of the source message in the repliedInfo.messageInfo of the child message. Therefore, you can choose whether to display the content of the source message on that device as needed.
// Listen for changes in the source message of a reply message
// Event trigger: When the source message is "deleted" or "recalled", the repliedInfo property of the reply referencing it will change
zim.on('messageRepliedInfoChanged', function (zim, { messageList }) {
messageList.forEach((msg) => {
if (msg.repliedInfo) {
if (msg.repliedInfo.state != 0) {
// The source message referenced by this reply message has been deleted, you can display "Message deleted" at this time
} else if (msg.repliedInfo.messageInfo.type == 31) {
// The source message referenced by this reply message has been recalled, you can display "Message recalled" at this time
}
}
});
});
Call queryMessageRepliedList and pass in the root message or any reply to view the complete list of replies and get the complete message list related to the replies.
The results returned by this interface will distinguish between the root message (rootRepliedInfo
) and the reply list (messageList
), and the reply list will be sorted in chronological order based on the sending time of the replies.
var replyMessage = {}; // replyMessage can be a root message or any reply, generally obtained through the queryHistoryMessage interface or receivePeerMessage and receiveGroupMessage
var config = {
count: 10, // The number of queries, please do not exceed 100
nextFlag: 0, // Pagination flag, fill in 0 for the first query, and subsequent queries will be based on the nextFlag returned by the query result
};
zim.queryMessageRepliedList(replyMessage, config)
.then(({ nextFlag, rootRepliedInfo, messageList }) => {
// Query successful
// If nextFlag is not 0, it means there is more data to be queried
// rootRepliedInfo is the information of the root message
// messageList represents the reply list to the root message
})
.catch((err) => {
// Query failed
});
Since the repliedInfo of a child message (i.e., a reply message) only contains basic source message data that can be used for UI display, users may need to go to the original location of the source message to read other messages near the source message.
Therefore, to implement this scenario, you need to use the repliedInfo.messageSeq property of the child message (which is the sequence number of the source message in the conversation).
The repliedInfo.messageSeq property of a child message (which is the sequence number of the source message in the conversation) corresponds to the messageSeq of the source message.
Depending on whether the source message and its surrounding messages are cached in the application's memory, ZIM provides two options.
When a source message and its surrounding messages are saved in your application's memory (for example, by calling queryHistoryMessage to retrieve and cache the conversation's message history), you can search the messageSeq of the source message in the memory and implement the business logic to go to the original location of the source message to view the context.
When the source message or its surrounding messages are not cached in the application's memory, if another user replies to the source message in the conversation, you can:
From the repliedInfo.messageSeq of the reply, get the messageSeq of the source message. Pass it as a parameter to call the queryMessages interface to get the complete ZIMMessage object of the source message.
var messageSeqs = []; // messageSeq is the sequence number of the source message in the conversation
var conversationID = '';
var conversationType = 0; // Conversation Type: ono-to-onr: 0; group: 2
zim.queryMessages(messageSeqs, conversationID, conversationType)
.then(({ messageList }) => {
// Query successful
})
.catch((err) => {
// Query failed
});
Pass the source message object as the nextMessage parameter to queryHistoryMessage, so that you can use the source message as an anchor point to retrieve messages from the messages forward or backward.
// This example demonstrates querying forward from the source message
var originalMessage = {};
var config = {
// originalMessage is the source message obtained through queryMessages
nextMessage: originalMessage,
count: 20,
reverse: false,
};
var conversationID = '';
var conversationType = 0;
zim.queryHistoryMessage(conversationID, conversationType, config)
.then((res) => {
// Query successful
})
.catch((err) => {
// Query failed
});