Starter Deal! First 3 month from only  $9.9 /month!
Starter Deal! First 3 month from only  $9.9 /month!
Grab It Now 
Chat
  • Web
    • TUIKit
      • Overview
      • Installaton
        • TUIKit
          • Vue
          • React
        • TUIChat Only
          • Vue
      • Features
        • Reactions
        • Read Receipt
        • Typing Status
        • User Online Status
      • Themes
        • Setting UI Styles
          • Web
          • Mobile
      • Customization
        • Customize Messages
      • Localization
    • SDK
      • Install Chat SDK
      • Initialize Chat SDK
      • Login and Logout
      • Client APIs
      • Message
        • Overview
        • Send a Message
        • Receive a Message
        • Historical Message
        • Forward Messages
        • Modify a Message
        • Delete Messages
        • Clear History Message
        • Recall a Message
        • Send an Online Message
        • Message Read Receipt
        • Query Messages
        • Targeted Group Message
        • Do not Notify
        • Key-Value Extensions
        • Translation
      • Conversation
        • Overview
        • Conversation List
        • Get Conversations
        • Unread Count
        • Pin Conversations
        • Delete Conversations
        • Mark
        • Conversation Group
      • Group
        • Overview
        • Group Management
        • Group Profile
        • Group Member Management
        • Group Member Profile
        • Custom Group Attribute
        • Group Counter
      • Community Topic
        • Community Management
      • User Profile and Relationship Chain
        • User Profile
        • User Status
        • Friend Management
        • Friend List
        • Block List
  • Android
    • Run Demo
    • UIKit
      • Overview
      • Getting Started
      • Installation
        • TUIKit
        • TUIChat Only
      • Features
        • Reactions
        • Read Receipt
        • User Online Status
        • Search Messages
      • Customization
        • Customize Messages
        • Customize Emojis and Stickers
      • Localization
    • SDK
      • Install Chat SDK
      • Initialize Chat SDK
      • Login and Logout
      • Message
        • Overview
        • Send a Message
        • Receive a Message
        • Retrieve Messages
        • Forward Messages
        • Modify a Message
        • Insert a Message
        • Delete Messages
        • Clear History Messages
        • Recall a Message
        • Send an Online Message
        • Message Read Receipt
        • Query Messages
        • Metions
        • Targeted Group Message
        • Do not Notify
        • Key-Value Extensions
        • Reactions
        • Translation
        • Pin Messages
      • Conversation
        • Overview
        • Conversation List
        • Get Conversations
        • Unread Count
        • Pin Conversations
        • Delete Conversations
        • Draft
        • Mark
        • Conversation Group
      • Group
        • Overview
        • Manage Group
        • Profile
        • Manage Members
        • Member Profile
        • Attribute
        • Counter
      • Community and Topic
        • Manage Community
        • Permission Group
      • User
        • User Profile
        • User Status
        • Manage Friends
        • Friend Group
        • Block Lists
      • Local Search
        • Search Messages
        • Search Friends
        • Search Groups
        • Search Group Members
      • Signaling
      • API Reference
        • Java
  • iOS and macOS
    • Run Demo
    • UIKit
      • Overview
      • Getting Started
      • Installation
        • TUIKit
        • TUIChat Only
      • Features
        • Reactions
        • Read Receipt
        • User Online Status
        • Search Messages
      • Customization
        • Customize Messages
        • Customize Emojis and Stickers
      • Localization
    • SDK
      • Installation
        • iOS
        • macOS
      • Initialize Chat SDK
      • Login and Logout
      • Message
        • Overview
        • Send a Message
        • Receive a Message
        • Retrieve Messages
        • Forward Messages
        • Modify a Message
        • Insert a Message
        • Delete Messages
        • Clear History Messages
        • Recall a Message
        • Send an Online Message
        • Message Read Receipt
        • Query Messages
        • Metions
        • Targeted Group Messages
        • Do not Notify
        • Key-Value Extensions
        • Reactions
        • Translation
        • Pin Messages
      • Conversation
        • Overview
        • Conversation List
        • Get Conversations
        • Unread Count
        • Pin Conversations
        • Delete Conversations
        • Draft
        • Mark
        • Conversation Group
      • Group
        • Overview
        • Manage Group
        • Profile
        • Manage Members
        • Member Profile
        • Attribute
        • Counter
      • Community and Topic
        • Manage Community
        • Permission Group
      • User
        • User Profile
        • User Status
        • Manage Friends
        • Friend Group
        • Block Lists
      • Local Search
        • Search Messages
        • Search Friends
        • Search Groups
        • Search Group Members
      • Signaling
      • API Reference
        • Swift
        • Objective-C
  • Windows
    • SDK
      • Install Chat SDK
      • Initialize Chat SDK
      • Login and Logout
      • Message
        • Overview
        • Send a Message
        • Receive a Message
        • Retrieve Messages
        • Forward Messages
        • Modify a Message
        • Insert a Message
        • Delete Messages
        • Clear History Messages
        • Recall a Message
        • Send an Online Message
        • Message Read Receipt
        • Query Messages
        • Metions
        • Targeted Group Messages
        • Do not Notify
        • Key-Value Extensions
        • Reactions
        • Translation
        • Pin Messages
      • Conversation
        • Overview
        • Conversation List
        • Get Conversations
        • Unread Count
        • Pin Conversations
        • Delete Conversations
        • Draft
        • Mark
        • Conversation Group
      • Group
        • Overview
        • Manage Group
        • Profile
        • Manage Members
        • Member Profile
        • Attribute
        • Counter
      • Community and Topic
        • Manage Community
        • Permission Group
      • User
        • User Profile
        • User Status
        • Manage Friends
        • Friend Group
        • Block Lists
      • Local Search
        • Search Messages
        • Search Friends
        • Search Groups
        • Search Group Members
      • Signaling
      • API Reference
        • C++
        • C
  • Flutter
    • Run Demo
    • UIKIT
      • Overview
      • Installation
        • integrated
      • Features
        • Local Search
        • Offline Push
        • Online Status
        • Typing Status
        • Message Read Receipt
        • Message Reactions
        • Internationalization
        • Adding Custom Messages
        • Emoji & Stickers
      • Customization
        • Modifying UI Themes
        • Setting UI Styles
    • SDK
      • Install Chat SDK
        • Install
      • Initialize Chat SDK
        • Initialize
      • Login And Logout
        • Login and Logout
      • Message
        • Message Overview
        • Sending Message
        • Receiving Message
        • Historical Message
        • Forwarding Message
        • Modifying Message
        • Message Inserting
        • Deleting Message
        • Clearing Messages
        • Recalling Message
        • Online Message
        • Read Receipt
        • Querying Message
        • Group @ Message
        • Targeted Group Message
        • Notification Muting
        • Message Extension
      • Conversation
        • Conversation Overview
        • Conversation List
        • Getting Conversation
        • Conversation Unread Count
        • Pinning Conversation to the Top
        • Deleting Conversation
        • Conversation Draft
        • Conversation Group
      • Group
        • Group Overview
        • Group Management
        • Group Profile
        • Group Member Management
        • Group Member Profile
        • Custom Group Attribute
      • User
        • User Profile
        • Friend Management
        • Friend List
        • Blocklist
      • Offline Push
        • Offline Push
      • Signaling
        • Signaling Management
      • Local Search
        • Searching for Message
        • Searching for Friend
        • Searching Group
        • Searching for Group Member
      • API Reference
        • Client APIs
  • React Native
    • Run Demo
    • SDK
      • SDK Integration
      • Initialization
      • Login and Logout
      • Message
        • Message Overview
        • Sending Message
        • Receiving Message
        • Historical Message
        • Forwarding Message
        • Modifying Message
        • Message Inserting
        • Deleting Message
        • Clearing Messages
        • Recalling Message
        • Online Message
        • Read Receipt
        • Querying Message
        • Group @ Message
        • Targeted Group Message
        • Notification Muting
        • Message Extension
      • Group
        • Overview
        • Group Management
        • Group Profile
        • Group Member Management
        • Group Member Profile
        • Custom Group Attribute
        • Community Management
      • User
        • User Profile
        • Friend Management
        • Friend List
        • Blocklist
      • Offline Push
        • Offline Push
      • Local Search
        • Searching for Message
        • Searching for Friend
        • Searching Group
        • Searching for Group Member
      • Signaling
        • Signaling Management
  • Unity(Game Solution)
    • Run Demo
    • SDK
      • SDK Integration
      • Initialization
      • Login and Logout
      • Message
        • Message Overview
        • Sending Message
        • Receiving Message
        • Historical Message
        • Forwarding Message
        • Modifying Message
        • Deleting Message
        • Clearing Messages
        • Recalling Message
        • Online Message
        • Read Receipt
        • Querying Message
        • Group @ Message
        • Targeted Group Message
        • Notification Muting
        • Message Extension
      • Conversation
        • Conversation Overview
        • Conversation List
        • Getting Conversation
        • Conversation Unread Count
        • Pinning Conversation to the Top
        • Deleting Conversation
        • Conversation Draft
        • Conversation Mark
        • Conversation Group
      • Group
        • Group Overview
        • Group Management
        • Group Profile
        • Group Member Management
        • Group Member Profile
        • Custom Group Attribute
        • Group Counter
      • User
        • User Profile
        • User Status
        • Friend Management
        • Friend List
        • Blocklist
  • Unreal Engine(Game Solution)
    • SDK
      • SDK Integration
  • Free Demos
  • Server APIs
    • Generating UserSig
    • RESTful APIs
      • RESTful API Overview
      • RESTful API List
      • Message Related
        • Send Message
          • Sending One-to-One Messages to One User
          • Sending One-to-One Messages to Multiple Users
          • Sending Ordinary Messages in a Group
          • Sending System Messages in a Group
          • Broadcast Message of Audio-Video Group
          • Importing One-to-One Messages
          • Importing Group Messages
        • Historical Message
          • Modifying Historical One-to-one Messages
          • Modifying Historical Group Messages
          • Pulling Historical One-to-one Messages
          • Pulling Historical Group Messages
        • Delete Message
          • Deleting Messages Sent by a Specified User
        • Withdraw Message
          • Recalling One-to-One Messages
          • Recalling Group Messages
        • Read Receipt
          • Marking One-to-One Messages as Read
          • Pulling Group Message Read Receipt Details
          • Pulling Read Receipts for Group Messages
        • Message Extension
          • Pulling the Message Extension of a One-to-One Message
          • Configuring Message Extension for a One-to-One Message
          • Pulling Message Extension of a Group Message
          • Configuring Message Extension for a Group Message
        • Pushing to All Users
          • API for Pushing to All Users
          • Pushing to All Users
          • Setting Application Attribute Names
          • Getting Application Attribute Names
          • Getting User Attributes
          • Setting User Attributes
          • Deleting User Attributes
          • Getting User Tags
          • Adding User Tags
          • Deleting User Tags
          • Deleting All Tags of a User
      • Session Related
        • Conversation List
          • Pulling a conversation list
        • Session Unread Count
          • Setting the Unread Message Count of a Member
          • Querying Unread One-to-One Message Count
        • Delete Session
          • Deleting a conversation
        • Session Grouping Tag
          • Creating Conversation Group Data
          • Updating Conversation Group Data
          • Deleting Conversation Group Data
          • Creating or Updating Conversation Mark Data
          • Searching for Conversation Group Marks
          • Pulling Conversation Group Mark Data
      • Group Related
        • Group Management
          • Getting All Groups in an App
          • Creating a Group
          • Disbanding a Group
          • Getting the Groups a User Has Joined
        • Group Information
          • Getting Group Profiles
          • Modifying the Profile of a Group
          • Importing a Group Profile
        • Group Member Management
          • Adding Group Members
          • Deleting Group Members
          • Banning Group Members
          • Unbanning Group Members
          • Bulk Muting and Unmuting
          • Getting the List of Muted Group Members
          • Changing Group Owner
          • Querying the Roles of Users in a Group
          • Importing Group Members
        • Group Member Information
          • Getting Group Member Profiles
          • Modifying the Profile of a Group Member
        • Group Custom Attributes
          • Getting Group Custom Attributes
          • Modifying Group Custom Attributes
          • Clearing Group Custom Attributes
          • Resetting Group Custom Attributes
          • Deleting Group Custom Attributes
        • Live Group Management
          • Getting the Number of Online Users in an Audio-Video Group
          • Getting the List of Online Members in Audio-Video Group
          • Setting Audio-Video Group Member Marks
          • Getting the List of Banned Group Members.
        • Community Management
          • Creating Topic
          • Deleting Topic
          • Getting Topic Profile
          • Modifying Topic Profile
          • Importing Topic Profiles
        • Group Counter
          • Getting Group Counters
          • Updating Group Counters
          • Deleting Group Counters
      • User Management
        • Account Management
          • Importing a Single Account
          • Importing Multiple Accounts
          • Deleting Accounts
          • Querying Accounts
        • User Information
          • Setting Profiles
          • Pulling Profiles
        • User Status
          • Invalidating Account Login States
          • Querying Account Online Status
        • Friend Management
          • Adding Friends
          • Importing Friends
          • Updating Friends
          • Deleting Friends
          • Deleting All Friends
          • Verifying Friends
          • Pulling Friends
          • Pulling Specified Friends
        • Friend Lists
          • Adding Lists
          • Deleting Lists
          • Pulling Lists
        • Blocklist
          • Blocklisting Users
          • Unblocklisting Users
          • Pulling a Blacklist
          • Verifying Users on a Blocklist
      • Global Mute Management
        • Setting Global Mute
        • Querying Global Mute
      • Operations Management
        • Pulling Operations Data
        • Downloading Recent Messages
        • Getting Server IP Addresses
      • Chatbots
        • Pulling Chatbot Accounts
        • Creating Chatbot Accounts
        • Deleting Chatbot Accounts
    • Webhooks
      • Webhook Overview
      • Webhook Command List
      • Operations Management Callbacks
        • API Overclocking Alarm Callbacks
      • Online Status Webhooks
        • Status Change Webhooks
      • Relationship Chain Webhooks
        • After a Profile Is Updated
        • Before a Friend Is Added
        • Before a Friend Request Is Responded
        • After a Friend Is Added
        • After a Friend Is Deleted
        • After a User Is Added to Blocklist
        • After a User Is Removed from Blocklist
      • One-to-One Message Webhooks
        • Before a One-to-One Message Is Sent
        • After a One-to-One Message Is Sent
        • After a One-to-One message Is Marked as Read
        • After A One-to-One Message Is Recalled
      • Group Webhooks
        • Before a Group Is Created
        • After a Group Is Created
        • Before Applying to Join a Group
        • Before Inviting a User to a Group
        • After a User Joins a Group
        • After a User Leaves a Group
        • Before Group Message Is Sent
        • After a Group Message Is Sent
        • After a Group Is Full
        • After a Group Is Disbanded
        • After Group Profile Is Modified
        • Callback After Recalling Group Messages
        • Webhook for Online and Offline Status of Audio-Video Group Members
        • Webhook for Exceptions When Group Messages Are Sent
        • Before a Topic Is Created
        • After a Topic Is Created
        • After a Topic Is Deleted
        • Topic Profile Change Webhook
        • Callback After Group Member Profile Changed
        • Callback After Group Attribute Changed
        • Callback After Read Receipt
        • Callback After the Group Owner Changed
      • Webhook Mutual Authentication Configuration Guide
        • Apache Mutual Authentication Configuration
        • Nginx Mutual Authentication Configuration
      • Chatbot webhooks
        • Chatbot Passthrough Message Callback
  • Console Guide
    • Creating and Upgrading an Application
    • Basic Configuration
    • Feature Configuration
    • Account Management
    • Group Management
    • Webhook Configuration
  • Product Introduction
    • Message Management
      • One-to-One Message
      • Message Storage
      • Offline Push
      • Group Message
      • Message Formats
    • Account System
      • Login Authentication
      • Online Status Management
    • Group Related
      • Group System
      • Group Management
    • User Profile and Relationship Chain
      • Profile Management
      • Relationship Chain Management
  • Purchase Guide
    • Billing Overview
    • Pricing
  • Error Codes
Chat

Retrieve Messages

Feature Description

The API for pulling historical messages is in the V2TIMManager and V2TIMManager+Message (for iOS and macOS) and V2TIMMessageManager (Android and Windows) classes.
In addition to the support for pulling historical one-to-one and group messages, an advanced API is provided to pull messages by sequence, start point, or time range.
Both local and cloud historical messages can be pulled.
Note
When historical messages are pulled from the cloud and a network exception is noticed, the SDK will return the locally stored historical messages.
Locally stored historical messages are not subject to time limits, but those stored in the cloud are subject to the following time limits:
Developer edition: The free storage period is 7 days and cannot be extended.
Standard edition: The free storage period is 7 days and can be extended.
Premium edition: The free storage period is 30 days and can be extended.
Note
It is a value-added service to extend the storage period of historical messages. If you need this feature, please contact us.
Rich media messages (such as images, files, and audios) have the same storage periods as historical messages.

Pulling Historical One-to-One Messages

Call the getC2CHistoryMessageList API (Android / iOS and macOS) to get historical one-to-one messages. When the network is normal, the latest cloud data will be pulled; when it is abnormal, the SDK will return the locally stored historical messages.
If you want to pull only local historical messages, see Advanced API. This API supports pulling by page. For more information, see Pulling by page.
Sample code:
Android
iOS and macOS
// Pull historical one-to-one messages
// Set `lastMsg` to `null` for the first pull
// `lastMsg` can be the last message in the returned message list for the second pull.
V2TIMManager.getMessageManager().getC2CHistoryMessageList(#your user id#, 20, null, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onError(int code, String desc) {
Log.i("imsdk", "fail, " + code + ", " + desc);
}

@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// Record the `lastMsg` for the next pull
V2TIMMessage lastMsg = v2TIMMessages.get(v2TIMMessages.size() - 1);
Log.i("imsdk", "success");
}
});
// Pull historical one-to-one messages
// Set `lastMsg` to `nil` for the first pull
// `lastMsg` can be the last message in the returned message list for the second pull.
[V2TIMManager.sharedInstance getC2CHistoryMessageList:#your user id# count:20 lastMsg:nil succ:^(NSArray<V2TIMMessage *> *msgs) {
// Record the `lastMsg` for the next pull
V2TIMMessage *lastMsg = msgs.lastObject;
NSLog(@"success, %@", msgs);
} fail:^(int code, NSString *desc) {
NSLog(@"fail, %d, %@", code, desc);
}];

Pulling Historical Group Messages

Call the getGroupHistoryMessageList API (Android / iOS and macOS) to get historical group messages. When the network is normal, the latest cloud data will be pulled; when it is abnormal, the SDK will return the locally stored historical messages.
If you want to pull only local historical messages, see Advanced API. This API supports pulling by page. For more information, see Pulling by page.
Caution
Only the historical messages of meeting groups (Meeting) can be pulled. For more information on group message limits, see Differences in message capabilities.
This API does not apply to audio-video groups (AVChatRoom), as their messages are not stored on the cloud roaming server or in the local database. If you use the Premium edition, you can configure Message History for New Members in the IM console to get historical messages in the onRecvNewMessage callback after successfully joining the audio-video group. New members of an audio-video group can view up to 20 messages in the past 24 hours before they join the group. For console configuration details, see Message history for new members of an audio-video group.
Sample code:
Android
iOS and macOS
// Pull historical group messages
// Set `lastMsg` to `null` for the first pull
// `lastMsg` can be the last message in the returned message list for the second pull.
V2TIMManager.getMessageManager().getGroupHistoryMessageList(#your group id#, 20, null, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onError(int code, String desc) {
Log.i("imsdk", "fail, " + code + ", " + desc);
}

@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// Record the `lastMsg` for the next pull
V2TIMMessage lastMsg = v2TIMMessages.get(v2TIMMessages.size() - 1);
Log.i("imsdk", "success");
}
});
// Pull historical group messages
// Set `lastMsg` to `null` for the first pull
// `lastMsg` can be the last message in the returned message list for the second pull.
[V2TIMManager.sharedInstance getGroupHistoryMessageList:#your group id# count:20 lastMsg:nil succ:^(NSArray<V2TIMMessage *> *msgs) {
// Record the `lastMsg` for the next pull
V2TIMMessage *lastMsg = msgs.lastObject;
NSLog(@"success, %@", msgs);
} fail:^(int code, NSString *desc) {
NSLog(@"fail, %d, %@", code, desc);
}];

Advanced Features

Advanced API

If the ordinary API above cannot meet your needs to pull historical messages, you can use the advanced API getHistoryMessageList (Android / iOS and macOS / Windows).
In addition to pulling historical one-to-one and group messages, this API supports the following advanced features:
Set the start point for message pull
Set the time range for message pull
Set the source for message pull: pull from the local database or the cloud
Specify the sequence for message pull: pull in reverse chronological order or in chronological order
Specify the message type for local pull: text, image, audio, video, file, emoji, group tip, merged, or custom message.
API prototype:
Android
iOS and macOS
Windows
public abstract void getHistoryMessageList(V2TIMMessageListGetOption option, V2TIMValueCallback<List<V2TIMMessage>> callback);
- (void)getHistoryMessageList:(V2TIMMessageListGetOption *)option
succ:(V2TIMMessageListSucc)succ
fail:(V2TIMFail)fail;
virtual void GetHistoryMessageList(const V2TIMMessageListGetOption& option,
V2TIMValueCallback<V2TIMMessageVector>* callback) = 0;
The parameters of the V2TIMMessageListGetOptionclass are as described below:
Parameter
Description
Valid for One-to-One Chat
Valid for Group Chat
Required
Remarks
getType
Source and sequence of the message pull, which can be set to local/cloud and reverse chronological order/chronological order respectively.
YES
YES
YES
When the pull source is set to the cloud, the local message list and cloud message list will be merged and returned. If there is no network connection, the local message list will be returned.
userID
The specified user ID with which to pull historical one-to-one messages
YES
NO
NO
To pull one-to-one messages with a certain user, you need to specify only the userID.
groupID
The specified group ID with which to pull historical group messages
NO
YES
NO
To pull group messages from a certain group, you need to specify only the groupID.
count
Number of messages per pull
YES
YES
YES
We recommend you set it to 20; otherwise, the pull speed may be affected.
messageTypeList
Pulled message type set
YES
YES
NO
1. It is supported only for local pull, that is, it is valid only when getType is V2TIM_GET_LOCAL_OLDER_MSG or V2TIM_GET_LOCAL_NEWER_MSG.
2. If this field is left empty, messages of all types will be pulled.
3. For more information on the supported message types, see V2TIMElemType (Android / iOS and macOS / Windows).
lastMsg
Last message
YES
YES
NO
This parameter applies to historical message pull.
1. It can be used for both one-to-one and group chats.
2. If it is set as the start point for the message pull, the message will not be included in the returned message list.
3. If it is left empty, the latest message in the conversation will be used as the start point for pull.
lastMsgSeq
seq of the last message
NO
YES
NO
This parameter applies to historical message pull or locating.
1. It can be used only for group chats.
2. If it is set as the start point for the message pull, the message will be included in the returned message list.
3. If both lastMsg and lastMsgSeq are specified, the SDK will use lastMsg.
4. If neither lastMsg nor lastMsgSeq is specified, the start point for pull will be determined based on whether the getTimeBegin is set. If yes, the set range will be used as the start point; if no, the latest message will be used as the start point.
getTimeBegin
Start time for the message pull. It is a UTC timestamp in seconds.
YES
YES
NO
It defaults to 0, indicating to pull messages from the current time.
getTimePeriod
Time range for the message pull in seconds.
YES
YES
NO
1. It defaults to 0, indicating that there is no time range limit.
2. It is a closed range including the start and end time:
If getType specifies the reverse chronological order, the time range is [getTimeBegin - getTimePeriod, getTimeBegin].
If getType specifies the chronological order, the time range is [getTimeBegin, getTimeBegin + getTimePeriod].

Pulling by page

Historical one-to-one message pull, historical group message pull, and pull via the advanced API can all be paged by using lastMsg and count:
1. For the first pull, leave lastMsg empty. In this case, the SDK will pull the latest message.
2. If it is not the first pull, use the last message in the message list from the last pull as the lastMsg. In this case, the lastMsg will not be included in the returned message list.
3. If the message list returned in the successful callback is empty, it means that pulling completed and there is no more data.
Note
1. In the pulled message list, newer messages are more forward.
2. We recommend you set count to 20 to enhance the loading efficiency and save network traffic.
If you use lastMsgSeq to pull historical messages, the message corresponding to lastMsgSeq will be included in the returned message list. Therefore, we recommend you not use lastMsgSeq if you are not pulling historical group messages for the first time (subsequent pull); otherwise, the same message may be pulled repeatedly. For example, there are eight historical messages: msg1, msg2, msg3, msg4, msg5, msg6, msg7, and msg8. If four messages are pulled each time, you will get msg1, msg2, msg3, and msg4 for the first pull. If you use the lastMsgSeq of msg4 to start another pull, msg4, msg5, msg6, and msg7 will be pulled. In this case, msg4 is pulled twice. If you need to use lastMsgSeq for subsequent pulls, we recommend you set the logic of message deduplication.

Pulling by time range

You can set getTimeBegin and getTimePeriod to specify the time range for the message pull. The start and end timestamps of the time range are related to getType, as shown below:



The following sample code demonstrates the process of pulling cloud group messages of the whole day from 2022-01-01 00:00:00 (the timestamp is 1640966400) in reverse chronological order.
Android
iOS and macOS
Windows
V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();
option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // Pull older cloud messages
option.setGetTimeBegin(1640966400); // Start from 2022-01-01 00:00:00
option.setGetTimePeriod(1 * 24 * 60 * 60); // Pull the messages of the whole day
option.setCount(Integer.MAX_VALUE); // Return all the messages within the time range
option.setGroupID(#you group id#); // Pull group messages
V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];
option.getType = V2TIM_GET_CLOUD_OLDER_MSG; // Pull cloud messages in reverse chronological order
option.getTimeBegin = 1640966400; // Start from 2022-01-01 00:00:00
option.getTimePeriod = 1 * 24 * 60 * 60; // Pull the messages of the whole day
option.count = INT_MAX; // Return all the messages within the time range
option.groupID = #your group id#; // Pull group messages
[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMMessageListGetOption option;
option.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // Pull older cloud messages
option.getTimeBegin = 1640966400; // Start from 2022-01-01 00:00:00
option.getTimePeriod = 1 * 24 * 60 * 60; // Pull the messages of the whole day
option.count = std::numeric_limits<uint64_t>::max(); // Return all the messages within the time range
option.groupID = "your group id"; // Pull group messages

auto callback = new ValueCallback<V2TIMMessageVector>{};
callback->SetCallback(
[=](const V2TIMMessageVector& messageList) {
std::cout << "success" << std::endl;
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);

Pulling by page within the time range

You can specify both the time range and lastMsg/lastMsgSeq for the message pull at the same time. And the SDK will respond as follows:
1. If both getTimeBegin/getTimePeriod and lastMsg/lastMsgSeq are set, the overlapping part of the messages pulled based on the start message and the messages pulled based on the time range will be returned.
2. If neither getTimeBegin/getTimePeriod nor lastMsg/lastMsgSeq is set, messages will be pulled from the latest message based on the sequence and method specified by getType.
The following sample code demonstrates the process of pulling cloud group messages by page (20 messages per page) from 2022-01-01 00:00:00 (the timestamp is 1640966400) in reverse chronological order.
Android
iOS and macOS
Windows
// Define a variable to record the cursor of each pull
private V2TIMMessage m_lastMsg = null; // It is `null` for the first pull.

// Logic of pulling by page
V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();
option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // Pull older cloud messages
option.setGetTimeBegin(1640966400); // Start from 2022-01-01 00:00:00
option.setGetTimePeriod(1 * 24 * 60 * 60); // Pull the messages of the whole day
option.setCount(20); // 20 messages per page
option.setLastMsg(m_lastMsg); // Position of the last pull (the last message in the returned message list each time)
option.setGroupID(#you group id#); // Pull group messages
V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
Log.i("imsdk", "success");
// Record the `lastMsg` for the next pull
m_lastMsg = v2TIMMessages.get(v2TIMMessages.size() - 1);
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
// Define a variable to record the cursor of each pull
@property (nonatomic, copy) V2TIMMessage *lastMsg;

// Logic of pulling by page
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];
option.getType = V2TIM_GET_CLOUD_OLDER_MSG; // Pull cloud messages in reverse chronological order
option.getTimeBegin = 1640966400; // Start from 2022-01-01 00:00:00
option.getTimePeriod = 1 * 24 * 60 * 60; // Pull the messages of the whole day
option.count = 20; // 20 messages per page
option.lastMsg = self.lastMsg; // Position of the last pull (the last message in the returned message list each time)
option.groupID = #your group id#; // Pull group messages
__weak typeof(self) weakSelf = self;
[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {
NSLog(@"success");
// Record the `lastMsg` for the next pull
weakSelf.lastMsg = msgs.lastObject;
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

// Define a variable to record the cursor of each pull
V2TIMMessage lastMsg;

// Logic of pulling by page
V2TIMMessageListGetOption option;
option.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // Pull older cloud messages
option.getTimeBegin = 1640966400; // Start from 2022-01-01 00:00:00
option.getTimePeriod = 1 * 24 * 60 * 60; // Pull the messages of the whole day
option.count = 20; // 20 messages per page
option.lastMsg = First pull? nullptr : &lastMsg; // Position of the last pull (the last message in the returned message list each time)
option.groupID = "your group id"; // Pull group messages

auto callback = new ValueCallback<V2TIMMessageVector>{};
callback->SetCallback(
[=](const V2TIMMessageVector& messageList) mutable {
std::cout << "success" << std::endl;
// Record the `lastMsg` for the next pull
lastMsg = messageList[messageList.Size() - 1];
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);

Pulling only local messages

Set getType to pull only local messages:
When getType is set to V2TIM_GET_LOCAL_OLDER_MSG, locally stored messages will be pulled in reverse chronological order.
When getType is set to V2TIM_GET_LOCAL_NEWER_MSG, locally stored messages will be pulled in chronological order.
The following sample code demonstrates the process of pulling 20 one-to-one messages from the local database in reverse chronological order, starting from the latest message:
Android
iOS and macOS
Windows
V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();
option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_LOCAL_OLDER_MSG); // Pull local messages in reverse chronological order
option.setLastMsg(null); // Set to pull from the latest message
option.setCount(20); // Pull 20 messages
option.setUserID(#you user id#); // Pull one-to-one messages
V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];
option.getType = V2TIM_GET_LOCAL_OLDER_MSG; // Pull local messages in reverse chronological order
option.lastMsg = nil; // Set to pull from the latest message
option.count = 20; // Pull 20 messages
option.userID = #your user id#; // Pull one-to-one messages
[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMMessageListGetOption option;
option.getType = V2TIMMessageGetType::V2TIM_GET_LOCAL_OLDER_MSG; // Pull older local messages
option.count = 20; // Pull 20 messages
option.userID = "you user id"; // Pull one-to-one messages

auto callback = new ValueCallback<V2TIMMessageVector>{};
callback->SetCallback(
[=](const V2TIMMessageVector& messageList) mutable {
std::cout << "success" << std::endl;
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);

Pulling messages of a specified type

The SDK defines common message types, such as text, image, and video messages. For more information, see V2TIMElemType (Android / iOS and macOS / Windows). The advanced API getHistoryMessageList allows setting messageTypeList to specify the message type for pull.
Caution
1. When messageTypeList is left empty, messages of all types will be pulled.
2. The message type can be specified only for the local pull but not for the cloud pull.
The following sample code demonstrates the process of pulling 20 text and image messages in reverse chronological order, starting from the current time:
Android
iOS and macOS
Windows
// Pull image and text messages
ArrayList<Integer> messageTypeList = new ArrayList<Integer>();
messageTypeList.add(V2TIM_ELEM_TYPE_IMAGE);
messageTypeList.add(V2TIM_ELEM_TYPE_TEXT);

V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();
option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // Pull older cloud messages
option.setCount(20);
option.setMessageTypeList(messageTypeList);
option.setGroupID("you group id");
V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];
option.getType = V2TIM_GET_CLOUD_OLDER_MSG;
// Pull image and text messages
option.messageTypeList = @[@(V2TIM_ELEM_TYPE_IMAGE), @(V2TIM_ELEM_TYPE_TEXT)];
option.count = 20;
option.groupID = @"your group id";
[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMMessageListGetOption option;
option.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // Pull older cloud messages
option.count = 20; // Pull 20 messages
option.messageTypeList.PushBack(V2TIMElemType::V2TIM_ELEM_TYPE_IMAGE); // Pull image messages
option.messageTypeList.PushBack(V2TIMElemType::V2TIM_ELEM_TYPE_TEXT); // Pull text messages
option.userID = "you group id"; // Pull group messages

auto callback = new ValueCallback<V2TIMMessageVector>{};
callback->SetCallback(
[=](const V2TIMMessageVector& messageList) mutable {
std::cout << "success" << std::endl;
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);

Pulling messages of a specified sequence

When polling historical messages in group chats, you can poll according to the specified message sequence.
Note:
It is only valid when pulling group history messages;
The message sequence can be obtained through the seq field of the V2TIMMessage object;
When getType is set to poll from the cloud, the local stored message list and the cloud stored message list will be merged and returned; if there is no network, the local message list will be returned directly;
When getType is set to poll from local, the local message list will be returned directly;
When getType is set to poll older messages, the message list is in reverse chronological order, i.e., messages are sorted from large to small by timestamp;
When getType is set to poll updated messages, the message list is in chronological order, i.e., messages are sorted from small to large by timestamp.
The sample code will demonstrate: In the group, poll messages with sequence 1, 3, 5, and 9 from the cloud, and return the messages in reverse chronological order.
Android
iOS & Mac
Windows
ArrayList<Long> sequenceList = new ArrayList<>();
sequenceList.add(1L);
sequenceList.add(3L);
sequenceList.add(5L);
sequenceList.add(9L);
V2TIMMessageListGetOption option = new V2TIMMessageListGetOption();
option.setGroupID("your groupID");
option.setMessageSeqList(sequenceList);
option.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG;);
V2TIMManager.getMessageManager().getHistoryMessageList(option, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {

}

@Override
public void onError(int code, String desc) {

}
});
V2TIMMessageListGetOption *option = [[V2TIMMessageListGetOption alloc] init];
option.getType = V2TIM_GET_CLOUD_OLDER_MSG;
option.groupID = @"your groupID";
option.messageSeqList = @[@(1), @(3), @(5), @(9)];
[V2TIMManager.sharedInstance getHistoryMessageList:option succ:^(NSArray<V2TIMMessage *> *msgs) {

} fail:^(int code, NSString *desc) {

}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

V2TIMUInt64Vector sequence_list;
sequence_list.PushBack(1);
sequence_list.PushBack(3);
sequence_list.PushBack(5);
sequence_list.PushBack(9);
V2TIMMessageListGetOption option;
option.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG;
option.messageSeqList = sequence_list;
option.groupID = "your group id";

auto callback = new ValueCallback<V2TIMMessageVector>{};
callback->SetCallback(
[=](const V2TIMMessageVector& messageList) {
std::cout << "success" << std::endl;
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(option, callback);

Quick redirection to a group @ message

After a user receives a group @ message in a group conversation, the user generally needs to click the @ bar to go to the message and pull the neighboring messages for display. As the group @ message also needs to be displayed, you can set its sequence as the lastMsgSeq and use the advanced API getHistoryMessageList to pull messages.
The following sample code demonstrates the process of clicking the @ bar, redirecting to the group @ message, and pulling the first 20 messages earlier and later than that message for display:
Android
iOS and macOS
Windows
// Get the `sequence` of the group @ message
long atSequence = 1081;

// Pull the group @ message and earlier messages
V2TIMMessageListGetOption beforeOption = new V2TIMMessageListGetOption();
beforeOption.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // Pull messages earlier than the group @ message
beforeOption.setCount(20); // Pull 20 messages
beforeOption.setLastMsgSeq(atSequence); // Start the pull from the group @ message, which is included in the pull list
beforeOption.setGroupID(#you group id#); // Pull group messages
V2TIMManager.getMessageManager().getHistoryMessageList(beforeOption, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// The group @ message is included in the returned message list.
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});

// Pull messages later than the group @ message
V2TIMMessageListGetOption afterOption = new V2TIMMessageListGetOption();
afterOption.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_NEWER_MSG); // Pull messages later than the group @ message
afterOption.setCount(20); // Pull 20 messages
afterOption.setLastMsgSeq(atSequence + 1); // Start the pull from the first message later than the group @ message, which is not included in the pull list
afterOption.setGroupID(#you group id#); // Pull group messages
V2TIMManager.getMessageManager().getHistoryMessageList(afterOption, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// The group @ message is not included in the returned message list.
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
// Get the `sequence` of the group @ message
NSInteger atSequence = 1081;

// Pull the group @ message and earlier messages
V2TIMMessageListGetOption *beforeOption = [[V2TIMMessageListGetOption alloc] init];
beforeOption.getType = V2TIM_GET_CLOUD_OLDER_MSG; // Pull messages earlier than the group @ message
beforeOption.count = 20; // Pull 20 messages
beforeOption.lastMsgSeq = atSequence; // Start the pull from the group @ message, which is included in the pull list
beforeOption.groupID = #your group id#; // Pull group messages
[V2TIMManager.sharedInstance getHistoryMessageList:beforeOption succ:^(NSArray<V2TIMMessage *> *msgs) {
// The group @ message is included in the returned message list.
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];

// Pull messages later than the group @ message
V2TIMMessageListGetOption *afterOption = [[V2TIMMessageListGetOption alloc] init];
afterOption.getType = V2TIM_GET_CLOUD_NEWER_MSG; // Pull messages later than the group @ message
afterOption.count = 20; // Pull 20 messages
afterOption.lastMsgSeq = atSequence + 1; // Start the pull from the first message later than the group @ message, which is not included in the pull list
afterOption.groupID = #your group id#; // Pull group messages
[V2TIMManager.sharedInstance getHistoryMessageList:afterOption succ:^(NSArray<V2TIMMessage *> *msgs) {
// The group @ message is not included in the returned message list.
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(error_code, error_message);
}
}

private:
SuccessCallback success_callback_;
ErrorCallback error_callback_;
};

// Get the `sequence` of the group @ message
uint64_t atSequence = 1081;

// Pull the group @ message and earlier messages
V2TIMMessageListGetOption beforeOption;
beforeOption.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_OLDER_MSG; // Pull messages earlier than the group @ message
beforeOption.count = 20; // Pull 20 messages
beforeOption.lastMsgSeq = atSequence; // Start the pull from the group @ message, which is included in the pull list
beforeOption.userID = "you group id"; // Pull group messages

auto beforeCallback = new ValueCallback<V2TIMMessageVector>{};
beforeCallback->SetCallback(
[=](const V2TIMMessageVector& messageList) mutable {
// The group @ message is included in the returned message list.
std::cout << "success" << std::endl;
delete beforeCallback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete beforeCallback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(beforeOption, beforeCallback);

// Pull the group @ message and earlier messages
V2TIMMessageListGetOption afterOption;
afterOption.getType = V2TIMMessageGetType::V2TIM_GET_CLOUD_NEWER_MSG; // Pull messages later than the group @ message
afterOption.count = 20; // Pull 20 messages
afterOption.lastMsgSeq = atSequence + 1; // Start the pull from the first message later than the group @ message, which is not included in the pull list
afterOption.userID = "you group id"; // Pull group messages

auto afterCallback = new ValueCallback<V2TIMMessageVector>{};
afterCallback->SetCallback(
[=](const V2TIMMessageVector& messageList) mutable {
// The group @ message is not included in the returned message list.
std::cout << "success" << std::endl;
delete afterCallback;
},
[=](int error_code, const V2TIMString& error_message) {
std::cout << "error" << std::endl;
delete afterCallback;
});

V2TIMManager::GetInstance()->GetMessageManager()->GetHistoryMessageList(afterOption, afterCallback);

Message locating for searches

When a user gets the V2TIMMessage object after the local search and clicks the message, you need to redirect the user to the position of the message and display neighboring messages. At this point, you can set lastMsg to the message object and use the advanced API getHistoryMessageList to pull neighboring messages.
The following sample code demonstrates the process of pulling the first 20 messages earlier and later than the located message for display.
Android
iOS and macOS
Windows
// Get the current message object
V2TIMMessage lastMsg = #The located message#;

// Pull messages earlier than the specified message
V2TIMMessageListGetOption beforeOption = new V2TIMMessageListGetOption();
beforeOption.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_OLDER_MSG); // Pull messages earlier than the specified message
beforeOption.setCount(20); // Pull 20 messages
beforeOption.setLastMsg(lastMsg); // Start the pull from the specified message, which is not included in the pull list
beforeOption.setGroupID(#you group id#); // Pull group messages
V2TIMManager.getMessageManager().getHistoryMessageList(beforeOption, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// `lastMsg` is not included in the returned message list.
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});

// Pull messages later than the specified message
V2TIMMessageListGetOption afterOption = new V2TIMMessageListGetOption();
afterOption.setGetType(V2TIMMessageListGetOption.V2TIM_GET_CLOUD_NEWER_MSG); // Pull messages later than the specified message
afterOption.setCount(20); // Pull 20 messages
afterOption.setLastMsg(lastMsg); // Start the pull from the specified message, which is not included in the pull list
afterOption.setGroupID(#you group id#); // Pull group messages
V2TIMManager.getMessageManager().getHistoryMessageList(afterOption, new V2TIMValueCallback<List<V2TIMMessage>>() {
@Override
public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
// `lastMsg` is not included in the returned message list.
Log.i("imsdk", "success");
}

@Override
public void onError(int code, String desc) {
Log.i("imsdk", "failure, code:" + code + ", desc:" + desc);
}
});
// Get the current message object
V2TIMMessage *lastMsg = #The located message#;

// Pull messages earlier than the specified message
V2TIMMessageListGetOption *beforeOption = [[V2TIMMessageListGetOption alloc] init];
beforeOption.getType = V2TIM_GET_CLOUD_OLDER_MSG; // Pull messages earlier than the specified message
beforeOption.count = 20; // Pull 20 messages
beforeOption.lastMsg = lastMsg; // Start the pull from the specified message, which is not included in the pull list
beforeOption.groupID = #your group id#; // Pull group messages
[V2TIMManager.sharedInstance getHistoryMessageList:beforeOption succ:^(NSArray<V2TIMMessage *> *msgs) {
// The specified message is not included in the returned message list.
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];

// Pull messages later than the specified message
V2TIMMessageListGetOption *afterOption = [[V2TIMMessageListGetOption alloc] init];
afterOption.getType = V2TIM_GET_CLOUD_NEWER_MSG; // Pull messages later than the specified message
afterOption.count = 20; // Pull 20 messages
afterOption.lastMsg = lastMsg; // Start the pull from the specified message, which is not included in the pull list
afterOption.groupID = #your group id#; // Pull group messages
[V2TIMManager.sharedInstance getHistoryMessageList:afterOption succ:^(NSArray<V2TIMMessage *> *msgs) {
// The specified message is not included in the returned message list.
NSLog(@"success");
} fail:^(int code, NSString *desc) {
NSLog(@"failure, code:%d, desc:%@", code, desc);
}];
template <class T>
class ValueCallback final : public V2TIMValueCallback<T> {
public:
using SuccessCallback = std::function<void(const T&)>;
using ErrorCallback = std::function<void(int, const V2TIMString&)>;

ValueCallback() = default;
~ValueCallback() override = default;

void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) {
success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
}

void OnSuccess(const T& value) override {
if (success_callback_) {
success_callback_(value);
}
}
void OnError(int error_code, const V2TIMString& error_message) override {
if (error_callback_) {
error_callback_(