// Enabling it for a channel
await channel.updatePartial({
config_overrides: {
user_message_reminders: true,
},
});
// Enabling it for a channel type
const update = await client.updateChannelType("messaging", {
user_message_reminders: true,
});Reminders & Bookmarks
Message reminders let users schedule notifications for specific messages, making it easier to follow up later. When a reminder includes a timestamp, it's like saying "remind me later about this message," and the user who set it will receive a notification at the designated time. If no timestamp is provided, the reminder functions more like a bookmark, allowing the user to save the message for later reference.
Reminders require Push V3 to be enabled - see details here
Enabling Reminders
The Message Reminders feature must be activated at the channel level before it can be used. You have two configuration options: activate it for a single channel using configuration overrides, or enable it globally for all channels of a particular type.
// Enabling it for a channel
$client->updateChannelPartial("messaging", "general", new Models\UpdateChannelPartialRequest(
set: (object)["config_overrides" => (object)["user_message_reminders" => true]],
));
// Enabling it for a channel type
$client->updateChannelType("messaging", new Models\UpdateChannelTypeRequest(
userMessageReminders: true,
));require 'getstream_ruby'
Models = GetStream::Generated::Models
# Enabling it for a channel
client.chat.update_channel_partial('messaging', channel_id, Models::UpdateChannelPartialRequest.new(
set: { 'config_overrides' => { 'user_message_reminders' => true } }
))
# Enabling it for a channel type
client.chat.update_channel_type('messaging', Models::UpdateChannelTypeRequest.new(
user_message_reminders: true,
automod: 'disabled',
automod_behavior: 'flag',
max_message_length: 5000
))// Enabling it for a channel
await chat.UpdateChannelPartialAsync("messaging", channelId,
new UpdateChannelPartialRequest
{
Set = new Dictionary<string, object>
{
["config_overrides"] = new Dictionary<string, object> { ["user_message_reminders"] = true }
}
});
// Enabling it for a channel type
await chat.UpdateChannelTypeAsync("messaging", new UpdateChannelTypeRequest
{
UserMessageReminders = true,
Automod = "disabled",
AutomodBehavior = "flag",
MaxMessageLength = 5000
});// Backend SDK
// Enabling it for a channel type
chat.updateChannelType("messaging", UpdateChannelTypeRequest.builder()
.userMessageReminders(true)
.automod("disabled")
.automodBehavior("flag")
.maxMessageLength(5000)
.build()).execute();# Enabling it for a channel
channel.update_channel_partial(
set={"config_overrides": {"user_message_reminders": True}}
)
# Enabling it for a channel type
client.chat.update_channel_type(
name="messaging",
automod="disabled",
automod_behavior="flag",
max_message_length=5000,
user_message_reminders=True,
)// Enabling it for a channel
channel.UpdateChannelPartial(ctx, &getstream.UpdateChannelPartialRequest{
Set: map[string]any{
"config_overrides": map[string]any{
"user_message_reminders": true,
},
},
})
// Enabling it for a channel type
client.Chat().UpdateChannelType(ctx, "messaging", &getstream.UpdateChannelTypeRequest{
UserMessageReminders: getstream.PtrTo(true),
Automod: "disabled",
AutomodBehavior: "flag",
MaxMessageLength: 5000,
})Message reminders allow users to:
- schedule a notification after given amount of time has elapsed
- bookmark a message without specifying a deadline
Limits
- A user cannot have more than 250 reminders scheduled
- A user can only have one reminder created per message
Creating a Message Reminder
You can create a reminder for any message. When creating a reminder, you can specify a reminder time or save it for later without a specific time.
// Backend SDK
// Create a reminder with a specific due date
const reminder = await client.createReminder(
"message-id",
"user-id",
new Date(Date.now() + 3600000),
);
// Create a "Save for later" reminder without a specific time
const reminder = await client.createReminder("message-id", "user-id");
// JavaScript SDK
// Create a reminder with a specific due date (direct API call)
await client.createReminder({
messageId: "message-id",
// Remind in offsetMs
remind_at: new Date(new Date().getTime() + offsetMs).toISOString(),
});
// Create a reminder with a specific due date (client state optimistic update (no server-side use))
await client.reminders.upsertReminder({
messageId: "message-id",
remind_at: new Date(new Date().getTime() + offsetMs).toISOString(),
});
// Create a "Save for later" reminder without a specific time (direct API call)
await client.createReminder({
messageId: "message-id",
});
// Create a "Save for later" reminder without a specific time (client state optimistic update (no server-side use))
await client.reminders.upsertReminder({
messageId: "message-id",
});// Create a reminder with a specific due date
$client->createReminder("message-id", new Models\CreateReminderRequest(
remindAt: new \DateTime("+1 hour"),
userID: "user-id",
));
// Create a "Save for later" reminder without a specific time
$client->createReminder("message-id", new Models\CreateReminderRequest(
userID: "user-id",
));require 'getstream_ruby'
Models = GetStream::Generated::Models
# Create a reminder with a specific due date
reminder = client.chat.create_reminder('message-id', Models::CreateReminderRequest.new(
user_id: 'user-id',
remind_at: (Time.now + 3600).utc.iso8601
))
# Create a "Save for later" reminder without a specific time
reminder = client.chat.create_reminder('message-id', Models::CreateReminderRequest.new(
user_id: 'user-id'
))// Create a reminder with a specific due date
await chat.CreateReminderAsync("message-id", new CreateReminderRequest
{
RemindAt = DateTime.UtcNow.AddHours(1),
UserID = "user-id"
});
// Create a "Save for later" reminder without a specific time
await chat.CreateReminderAsync("message-id", new CreateReminderRequest
{
UserID = "user-id"
});// Backend SDK
// Create a reminder with a specific due date
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR, 1);
Date remindAt = cal.getTime();
chat.createReminder("message-id", CreateReminderRequest.builder()
.remindAt(remindAt)
.userID("user-id")
.build()).execute();
// Create a "Save for later" reminder without a specific time
chat.createReminder("message-id", CreateReminderRequest.builder()
.userID("user-id")
.build()).execute();from datetime import datetime, timedelta
# Create a reminder with a specific due date
remind_at = datetime.now() + timedelta(hours=1)
reminder = client.chat.create_reminder(
message_id="message-id", user_id="user-id", remind_at=remind_at
)
# Create a "Save for later" reminder without a specific time
reminder = client.chat.create_reminder(message_id="message-id", user_id="user-id")import "time"
// Create a reminder with a specific due date
t := time.Now().Add(time.Hour)
remindAt := getstream.Timestamp{Time: &t}
resp, err := client.Chat().CreateReminder(ctx, "message-id", &getstream.CreateReminderRequest{
RemindAt: &remindAt,
UserID: getstream.PtrTo("user-id"),
})
// Create a "Save for later" reminder without a specific time
resp, err := client.Chat().CreateReminder(ctx, "message-id", &getstream.CreateReminderRequest{
UserID: getstream.PtrTo("user-id"),
})// Get a message controller for the message
let messageController = chatClient.messageController(
cid: ChannelId(type: .messaging, id: "general"),
messageId: "message-id"
)
// Create a reminder with a specific due date
messageController.createReminder(
remindAt: Date().addingTimeInterval(3600) // Reminder in 1 hour
) { result in
switch result {
case .success(let reminder):
print("Reminder created: \(reminder)")
case .failure(let error):
print("Failed to create reminder: \(error)")
}
}
// Create a "Save for later" reminder without a specific time
messageController.createReminder(
remindAt: nil // No specific reminder time
) { result in
switch result {
case .success(let reminder):
print("Message saved for later: \(reminder)")
case .failure(let error):
print("Failed to save message for later: \(error)")
}
}// Create a reminder with a specific due date
client.createReminder(
messageId = "message-id",
// Remind in 1 hour
remindAt = Date().apply { time += 1.hours.inWholeMilliseconds }
).enqueue { /* ... */ }
// Create a "Save for later" reminder without a specific time
client.createReminder(
messageId = "message-id",
remindAt = null, // No specific remind time
).enqueue { /* ... */ }// Create a reminder with a specific due date
await client.createReminder(
messageId,
// Remind in 1 hour
remindAt: DateTime.now().add(const Duration(hours: 1)),
);
// Create a "Save for later" reminder without a specific time
await client.createReminder(messageId);Updating a Message Reminder
You can update an existing reminder for a message to change the reminder time.
// Backend SDK
// Update a reminder with a new due date
const updatedReminder = await client.updateReminder(
"message-id",
"user-id",
new Date(Date.now() + 7200000),
);
// Convert a timed reminder to "Save for later"
const updatedReminder = await client.updateReminder(
"message-id",
"user-id",
null,
);
// JavaScript SDK
// Update a reminder with a new due date (direct API call)
await client.updateReminder({
messageId: "message-id",
// Remind in newOffsetMs
remind_at: new Date(new Date().getTime() + newOffsetMs).toISOString(),
// in case of server-side integration, include the id of a user on behalf of which the reminder is created
//user_id: 'some-user-id'
});
// Update a reminder with a new due date (client state optimistic update (no server-side use))
await client.reminders.upsertReminder({
messageId: "message-id",
// Remind in newOffsetMs
remind_at: new Date(new Date().getTime() + newOffsetMs).toISOString(),
// in case of server-side integration, include the id of a user on behalf of which the reminder is created
//user_id: 'some-user-id'
});
// Convert a timed reminder to "Save for later" (direct API call)
await client.updateReminder({
messageId: "message-id",
remind_at: null,
// in case of server-side integration, include the id of a user on behalf of which the reminder is created
//user_id: 'some-user-id'
});
// Convert a timed reminder to "Save for later" (client state optimistic update (no server-side use))
await client.reminders.upsertReminder({
messageId: "message-id",
remind_at: null,
});// Update a reminder with a new due date
$client->updateReminder("message-id", new Models\UpdateReminderRequest(
remindAt: new \DateTime("+2 hours"),
userID: "user-id",
));
// Convert a timed reminder to "Save for later"
$client->updateReminder("message-id", new Models\UpdateReminderRequest(
remindAt: null,
userID: "user-id",
));require 'getstream_ruby'
Models = GetStream::Generated::Models
# Update a reminder with a new due date
updated_reminder = client.chat.update_reminder('message-id', Models::UpdateReminderRequest.new(
user_id: 'user-id',
remind_at: (Time.now + 7200).utc.iso8601
))
# Convert a timed reminder to "Save for later"
updated_reminder = client.chat.update_reminder('message-id', Models::UpdateReminderRequest.new(
user_id: 'user-id',
remind_at: nil
))// Update a reminder with a new due date
await chat.UpdateReminderAsync("message-id", new UpdateReminderRequest
{
RemindAt = DateTime.UtcNow.AddHours(2),
UserID = "user-id"
});
// Convert a timed reminder to "Save for later"
await chat.UpdateReminderAsync("message-id", new UpdateReminderRequest
{
RemindAt = null,
UserID = "user-id"
});// Backend SDK
// Update a reminder with a new due date
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR, 2);
Date remindAt = cal.getTime();
chat.updateReminder("message-id", UpdateReminderRequest.builder()
.remindAt(remindAt)
.userID("user-id")
.build()).execute();
// Convert a timed reminder to "Save for later"
chat.updateReminder("message-id", UpdateReminderRequest.builder()
.remindAt(null)
.userID("user-id")
.build()).execute();from datetime import datetime, timedelta
# Update a reminder with a new due date
remind_at = datetime.now() + timedelta(hours=2)
updated_reminder = client.chat.update_reminder(
message_id="message-id", user_id="user-id", remind_at=remind_at
)
# Convert a timed reminder to "Save for later"
updated_reminder = client.chat.update_reminder(
message_id="message-id", user_id="user-id", remind_at=None
)import "time"
// Update a reminder with a new due date
t := time.Now().Add(2 * time.Hour)
remindAt := getstream.Timestamp{Time: &t}
resp, err := client.Chat().UpdateReminder(ctx, "message-id", &getstream.UpdateReminderRequest{
RemindAt: &remindAt,
UserID: getstream.PtrTo("user-id"),
})
// Convert a timed reminder to "Save for later"
resp, err := client.Chat().UpdateReminder(ctx, "message-id", &getstream.UpdateReminderRequest{
UserID: getstream.PtrTo("user-id"),
})// Get a message controller for the message
let messageController = chatClient.messageController(
cid: ChannelId(type: .messaging, id: "general"),
messageId: "message-id"
)
// Update a reminder with a new due date
messageController.updateReminder(
remindAt: Date().addingTimeInterval(7200) // New reminder time (2 hours)
) { result in
switch result {
case .success(let reminder):
print("Reminder updated: \(reminder)")
case .failure(let error):
print("Failed to update reminder: \(error)")
}
}
// Convert a timed reminder to "Save for later"
messageController.updateReminder(
remindAt: nil // Remove specific reminder time
) { result in
switch result {
case .success(let reminder):
print("Reminder updated to save for later: \(reminder)")
case .failure(let error):
print("Failed to update reminder: \(error)")
}
}// Update a reminder with a new due date
client.updateReminder(
messageId = "message-id",
// New reminder time in 2 hours
remindAt = Date().apply { time += 2.hours.inWholeMilliseconds }
).enqueue { /* ... */ }
// Convert a timed reminder to "Save for later"
client.updateReminder(
messageId = "message-id",
remindAt = null, // Remove specific reminder time
).enqueue { /* ... */ }// Update a reminder with a new due date
await client.updateReminder(
messageId,
// New reminder time in 2 hours
remindAt: DateTime.now().add(const Duration(hours: 2)),
);
// Convert a timed reminder to "Save for later"
await client.updateReminder(
messageId,
remindAt: null, // Remove specific reminder time
);Deleting a Message Reminder
You can delete a reminder for a message when it's no longer needed.
// Backend SDK
// Delete the reminder for the message
await client.deleteReminder("message-id", "user-id");
// JavaScript SDK
// Delete a reminder for a message with id 'message-id' (direct API call)
await client.deleteReminder("message-id");
// Delete a reminder for a message with id 'message-id' (client state optimistic update (no server-side use))
await client.reminders.deleteReminder("message-id");// Delete the reminder for the message
$client->deleteReminder("message-id", "user-id");require 'getstream_ruby'
Models = GetStream::Generated::Models
# Delete the reminder for the message
client.chat.delete_reminder('message-id', 'user-id')// Delete the reminder for the message
await chat.DeleteReminderAsync("message-id", new { user_id = "user-id" });// Backend SDK
// Delete the reminder for the message
chat.deleteReminder("message-id", DeleteReminderRequest.builder()
.UserID("user-id")
.build()).execute();# Delete the reminder for the message
client.chat.delete_reminder(message_id="message-id", user_id="user-id")// Delete the reminder for the message
_, err := client.Chat().DeleteReminder(ctx, "message-id", &getstream.DeleteReminderRequest{
UserID: getstream.PtrTo("user-id"),
})// Get a message controller for the message
let messageController = chatClient.messageController(
cid: ChannelId(type: .messaging, id: "general"),
messageId: "message-id"
)
// Delete the reminder for the message
messageController.deleteReminder { result in
switch result {
case .success:
print("Reminder deleted successfully")
case .failure(let error):
print("Failed to delete reminder: \(error)")
}
}// Delete the reminder for the message
client.deleteReminder("message-id").enqueue { /* ... */ }// Delete the reminder for the message
await client.deleteReminder(messageId);Querying Message Reminders
The SDK allows you to fetch all reminders of the current user. You can filter, sort, and paginate through all the user's reminders.
// Query reminders for a user (server-side)
const reminders = await client.queryReminders({ user_id: "user-id" });
// Query reminders with filters (server-side)
const reminders = await client.queryReminders({
user_id: "user-id",
filter: { channel_cid: "messaging:general" },
});
// JavaScript SDK
// Retrieve the first page of reminders for the current user (direct API call).
await client.queryReminders();
// For the client-side pagination there are two methods representing two directions of pagination
// Query the first page (client state optimistic update (no server-side use))
await client.reminders.queryNextReminders();// Query reminders for a user
$response = $client->queryReminders(new Models\QueryRemindersRequest(
userID: "user-id",
));
// Query reminders with filters
$response = $client->queryReminders(new Models\QueryRemindersRequest(
filter: (object)["channel_cid" => "messaging:general"],
userID: "user-id",
));require 'getstream_ruby'
Models = GetStream::Generated::Models
# Query reminders for a user
reminders = client.chat.query_reminders(Models::QueryRemindersRequest.new(
user_id: 'user-id'
))
# Query reminders with filters
reminders = client.chat.query_reminders(Models::QueryRemindersRequest.new(
user_id: 'user-id',
filter: { 'channel_cid' => 'messaging:general' }
))// Query reminders for a user
var resp = await chat.QueryRemindersAsync(new QueryRemindersRequest
{
UserID = "user-id"
});
// Query reminders with filters
var filteredResp = await chat.QueryRemindersAsync(new QueryRemindersRequest
{
UserID = "user-id",
Filter = new Dictionary<string, object> { ["channel_cid"] = "messaging:general" }
});// Backend SDK
// Query reminders for a user
var reminders = chat.queryReminders(QueryRemindersRequest.builder()
.userID("user-id")
.build()).execute().getData();
// Query reminders with filters
Map<String, Object> filter = Map.of("channel_cid", "messaging:general");
var filteredReminders = chat.queryReminders(QueryRemindersRequest.builder()
.userID("user-id")
.filter(filter)
.build()).execute().getData();# Query reminders for a user
reminders = client.chat.query_reminders(user_id="user-id")
# Query reminders with filters
reminders = client.chat.query_reminders(
user_id="user-id",
filter={"channel_cid": "messaging:general"},
)// Query reminders for a user
resp, err := client.Chat().QueryReminders(ctx, &getstream.QueryRemindersRequest{
UserID: getstream.PtrTo("user-id"),
})
// Query reminders with filters
resp, err := client.Chat().QueryReminders(ctx, &getstream.QueryRemindersRequest{
UserID: getstream.PtrTo("user-id"),
Filter: map[string]any{
"channel_cid": "messaging:general",
},
})// Create a reminder list controller
let reminderListController = chatClient.messageReminderListController()
// Sync reminders
reminderListController.synchronize { error in
if let error = error {
print("Failed to synchronize reminders: \(error)")
}
}
reminderListController.delegate = self
// Get notified about reminders changes
class MyReminderListView: MessageReminderListControllerDelegate {
let controller: MessageReminderListController
init(controller: MessageReminderListController) {
self.controller = controller
controller.delegate = self
}
func controller(
_ controller: MessageReminderListController,
didChangeReminders changes: [ListChange<MessageReminder>]
) {
// Handle changes to reminders
print("New reminders: \(controller.reminders)")
}
}// Retrieve the first 25 reminders for the current user.
client.queryReminders(filter = Filters.neutral(), limit = 25).enqueue { /* ... */ }// Retrieve all reminders for the current user.
await client.queryReminders();Filtering Reminders
You can filter the reminders based on different criteria:
message_id- Filter by the message that the reminder is created on.remind_at- Filter by the reminder time.created_at- Filter by the creation date.channel_cid- Filter by the channel ID.
The most common use case would be to filter by the reminder time. Like filtering overdue reminders, upcoming reminders, or reminders with no due date (saved for later).
// Server-side SDK
// Filter overdue reminders
const overdueFilter = { remind_at: { $lt: new Date() } };
const overdueReminders = await client.queryReminders({
user_id: "user-id",
filter: overdueFilter,
});
// Filter upcoming reminders
const upcomingFilter = { remind_at: { $gt: new Date() } };
const upcomingReminders = await client.queryReminders({
user_id: "user-id",
filter: upcomingFilter,
});
// Filter reminders with no due date (saved for later)
const savedFilter = { remind_at: null };
const savedReminders = await client.queryReminders({
user_id: "user-id",
filter: savedFilter,
});
// JavaScript SDK
// Direct API call
// Create filter for overdue reminders
await client.queryReminders({
filter: {
remind_at: { $lte: new Date().toISOString() },
},
sort: {
remind_at: -1, // sort from the most recently expired
},
});
// Create filter for upcoming reminders
await client.queryReminders({
filter: {
remind_at: { $gt: new Date().toISOString() },
},
sort: {
remind_at: 1, // sort from the nearest to expire
},
});
// Create filter for reminders with no due date (saved for later)
await client.queryReminders({
filter: {
remind_at: null,
},
sort: {
created_at: -1, // sort from the most recently created
},
});
// Client-side calls with local state updates before starting the pagination.
// Setting sort or filters resets the pagination state
// Create filter for overdue reminders
client.reminders.paginator.filters = {
remind_at: { $lte: new Date().toISOString() },
};
client.reminders.paginator.sort = {
remind_at: -1, // sort from the most recently expired
};
// Create filter for upcoming reminders
client.reminders.paginator.filters = {
remind_at: { $gt: new Date().toISOString() },
};
client.reminders.paginator.sort = {
remind_at: 1, // sort from the nearest to expire
};
// Create filter for reminders with no due date (saved for later)
client.reminders.paginator.filters = {
remind_at: null,
};
client.reminders.paginator.sort = {
created_at: -1, // sort from the most recently created
};
// adjust the page size
client.reminders.paginator.pageSize = 15;// Filter overdue reminders
$response = $client->queryReminders(new Models\QueryRemindersRequest(
filter: (object)["remind_at" => (object)['$lt' => (new \DateTime())->format(\DateTime::ATOM)]],
userID: "user-id",
));
// Filter upcoming reminders
$response = $client->queryReminders(new Models\QueryRemindersRequest(
filter: (object)["remind_at" => (object)['$gt' => (new \DateTime())->format(\DateTime::ATOM)]],
userID: "user-id",
));
// Filter reminders with no due date (saved for later)
$response = $client->queryReminders(new Models\QueryRemindersRequest(
filter: (object)["remind_at" => null],
userID: "user-id",
));require 'getstream_ruby'
Models = GetStream::Generated::Models
# Filter overdue reminders
overdue_reminders = client.chat.query_reminders(Models::QueryRemindersRequest.new(
user_id: 'user-id',
filter: { 'remind_at' => { '$lt' => Time.now.utc.iso8601 } }
))
# Filter upcoming reminders
upcoming_reminders = client.chat.query_reminders(Models::QueryRemindersRequest.new(
user_id: 'user-id',
filter: { 'remind_at' => { '$gt' => Time.now.utc.iso8601 } }
))
# Filter reminders with no due date (saved for later)
saved_reminders = client.chat.query_reminders(Models::QueryRemindersRequest.new(
user_id: 'user-id',
filter: { 'remind_at' => nil }
))// Filter overdue reminders
var overdueResp = await chat.QueryRemindersAsync(new QueryRemindersRequest
{
UserID = "user-id",
Filter = new Dictionary<string, object>
{
["remind_at"] = new Dictionary<string, object> { ["$lt"] = DateTime.UtcNow }
}
});
// Filter upcoming reminders
var upcomingResp = await chat.QueryRemindersAsync(new QueryRemindersRequest
{
UserID = "user-id",
Filter = new Dictionary<string, object>
{
["remind_at"] = new Dictionary<string, object> { ["$gt"] = DateTime.UtcNow }
}
});
// Filter reminders with no due date (saved for later)
var savedResp = await chat.QueryRemindersAsync(new QueryRemindersRequest
{
UserID = "user-id",
Filter = new Dictionary<string, object> { ["remind_at"] = null }
});// Backend SDK
import java.util.Date;
// Filter overdue reminders
Map<String, Object> overdueFilter = Map.of("remind_at", Map.of("$lt", new Date()));
var overdueReminders = chat.queryReminders(QueryRemindersRequest.builder()
.userID("user-id")
.filter(overdueFilter)
.build()).execute().getData();
// Filter upcoming reminders
Map<String, Object> upcomingFilter = Map.of("remind_at", Map.of("$gt", new Date()));
var upcomingReminders = chat.queryReminders(QueryRemindersRequest.builder()
.userID("user-id")
.filter(upcomingFilter)
.build()).execute().getData();
// Filter reminders with no due date (saved for later)
Map<String, Object> savedFilter = new HashMap<>();
savedFilter.put("remind_at", null);
var savedReminders = chat.queryReminders(QueryRemindersRequest.builder()
.userID("user-id")
.filter(savedFilter)
.build()).execute().getData();from datetime import datetime
# Filter overdue reminders
overdue_reminders = client.chat.query_reminders(
user_id="user-id",
filter={"remind_at": {"$lt": datetime.now().isoformat()}},
)
# Filter upcoming reminders
upcoming_reminders = client.chat.query_reminders(
user_id="user-id",
filter={"remind_at": {"$gt": datetime.now().isoformat()}},
)
# Filter reminders with no due date (saved for later)
saved_reminders = client.chat.query_reminders(
user_id="user-id",
filter={"remind_at": None},
)import "time"
// Filter overdue reminders
overdueResp, err := client.Chat().QueryReminders(ctx, &getstream.QueryRemindersRequest{
UserID: getstream.PtrTo("user-id"),
Filter: map[string]any{
"remind_at": map[string]any{"$lt": time.Now()},
},
})
// Filter upcoming reminders
upcomingResp, err := client.Chat().QueryReminders(ctx, &getstream.QueryRemindersRequest{
UserID: getstream.PtrTo("user-id"),
Filter: map[string]any{
"remind_at": map[string]any{"$gt": time.Now()},
},
})
// Filter reminders with no due date (saved for later)
savedResp, err := client.Chat().QueryReminders(ctx, &getstream.QueryRemindersRequest{
UserID: getstream.PtrTo("user-id"),
Filter: map[string]any{
"remind_at": nil,
},
})// Create filter for overdue reminders
let query = MessageReminderListQuery(
filter: .overdue, // Same as .less(.remindAt, than: Date())
sort: [.init(key: .remindAt, isAscending: false)]
)
// Create filter for upcoming reminders
let query = MessageReminderListQuery(
filter: .upcoming, // Same as .greater(.remindAt, than: Date())
sort: [.init(key: .remindAt, isAscending: true)]
)
// Create filter for reminders with no due date (saved for later)
let query = MessageReminderListQuery(
filter: .isNil(.remindAt),
sort: [.init(key: .createdAt, isAscending: false)]
)
// Apply the filter to the controller
let reminderListController = chatClient.messageReminderListController(query: query)
reminderListController.delegate = self
reminderListController.synchronize()// Retrieve the first 25 overdue reminders for the current user sorted by remindAt.
val now = Date()
client.queryReminders(
filter = Filters.lessThanEquals("remind_at", now),
limit = 25,
sort = QuerySortByField.descByName("remind_at"),
).enqueue { /* ... */ }
// Retrieve the first 25 upcoming reminders for the current user sorted by remindAt.
val now = Date()
client.queryReminders(
filter = Filters.greaterThanEquals("remind_at", now),
limit = 25,
sort = QuerySortByField.ascByName("remind_at"),
).enqueue { /* ... */ }
// Retrieve the first 25 reminders saved for later (no remind_at).
client.queryReminders(
filter = Filters.notExists("remind_at"),
limit = 25,
sort = QuerySortByField.descByName("created_at"),
).enqueue { /* ... */ }Pagination
If you have many reminders, you can paginate the results.
// Server-side SDK
// Load reminders with pagination
const reminders = await client.queryReminders({
user_id: "user-id",
limit: 10,
offset: 0,
});
// Load next page
const nextReminders = await client.queryReminders({
user_id: "user-id",
limit: 10,
offset: 10,
});
// JavaScript SDK
// Load the next page (direct API call).
await client.queryReminders({ filter, sort, limit, next }); // limit is the page size
// Load the previous page (direct API call).
await client.queryReminders({ filter, sort, limit, prev }); // limit is the page size
// For the client-side pagination there are two methods representing two directions of pagination
// Set the filter and (or) sort params - this resets the pagination
client.reminders.paginator.filters = filters;
client.reminders.paginator.sort = sort;
// Query the next page of reminders starting from 0 (client state optimistic update
await client.reminders.queryNextReminders();
// Query the previous page of reminders if already some reminders were queried previously
await client.reminders.queryPreviousReminders();// Load reminders with pagination
$response = $client->queryReminders(new Models\QueryRemindersRequest(
userID: "user-id",
limit: 10,
));
// Load next page using cursor
if ($response->getData()->next) {
$nextResponse = $client->queryReminders(new Models\QueryRemindersRequest(
userID: "user-id",
limit: 10,
next: $response->getData()->next,
));
}require 'getstream_ruby'
Models = GetStream::Generated::Models
# Load reminders with pagination
reminders = client.chat.query_reminders(Models::QueryRemindersRequest.new(
user_id: 'user-id',
limit: 10
))
# Load next page using cursor
if reminders.next
next_reminders = client.chat.query_reminders(Models::QueryRemindersRequest.new(
user_id: 'user-id',
limit: 10,
next: reminders.next
))
end// Load reminders with pagination
var resp = await chat.QueryRemindersAsync(new QueryRemindersRequest
{
UserID = "user-id",
Limit = 10
});
// Load next page using cursor
if (resp.Data.Next != null)
{
var nextResp = await chat.QueryRemindersAsync(new QueryRemindersRequest
{
UserID = "user-id",
Limit = 10,
Next = resp.Data.Next
});
}// Backend SDK
// Load reminders with pagination
var reminders = chat.queryReminders(QueryRemindersRequest.builder()
.userID("user-id")
.limit(10)
.build()).execute().getData();
// Load next page
var nextReminders = chat.queryReminders(QueryRemindersRequest.builder()
.userID("user-id")
.limit(10)
.next(reminders.getNext())
.build()).execute().getData();# Load reminders with pagination
reminders = client.chat.query_reminders(user_id="user-id", limit=10)
# Load next page using cursor
if reminders.data.next:
next_reminders = client.chat.query_reminders(
user_id="user-id", limit=10, next=reminders.data.next
)// Load reminders with pagination
resp, err := client.Chat().QueryReminders(ctx, &getstream.QueryRemindersRequest{
UserID: getstream.PtrTo("user-id"),
Limit: getstream.PtrTo(10),
})
// Load next page using cursor
nextResp, err := client.Chat().QueryReminders(ctx, &getstream.QueryRemindersRequest{
UserID: getstream.PtrTo("user-id"),
Limit: getstream.PtrTo(10),
Next: resp.Data.Next,
})// Load more reminders
reminderListController.loadMoreReminders { error in
switch result {
case .success(let newReminders):
print("Loaded \(newReminders.count) more reminders")
case .failure(let error):
print("Failed to load more reminders: \(error)")
}
}// Load first page of reminders
val result = client.queryReminders(
filter = filter,
limit = limit,
).await().getOrThrow()
// Load next page of reminders
val nextPageKey = result.next
client.queryReminders(
filter = filter,
limit = limit,
next = nextPageKey, // Pass the next page key for pagination
).enqueue { /* ... */ }// Load more reminders
final response = await client.queryReminders(
sort: sort,
filter: filter,
// Pass the limit and next page key for pagination
pagination: PaginationParams(limit: limit, next: nextPageKey),
);Events
The following WebSocket events are available for message reminders:
reminder.created- Triggered when a reminder is createdreminder.updated- Triggered when a reminder is updatedreminder.deleted- Triggered when a reminder is deletednotification.reminder_due- Triggered when a reminder's due time is reached
When a reminder's due time is reached, the server also sends a push notification to the user. Ensure push notifications are configured in your app.
client.on("reminder.created", (event) => {
console.log("Reminder created for message:", event.message_id);
});
client.on("reminder.updated", (event) => {
console.log("Reminder updated for message:", event.message_id);
});
client.on("reminder.deleted", (event) => {
console.log("Reminder deleted for message:", event.message_id);
});
client.on("notification.reminder_due", (event) => {
console.log("Reminder due for message:", event.message_id);
});
// Unsubscribe when done
const { unsubscribe } = client.on("reminder.created", handler);
unsubscribe();let chatClient = ChatClient.shared
let eventsController = chatClient.eventsController()
eventsController.delegate = self
public func eventsController(_ controller: EventsController, didReceiveEvent event: any Event) {
if let event = event as? MessageReminderCreatedEvent {
print("Reminder created for message: \(event.messageId)")
} else if let event = event as? MessageReminderUpdatedEvent {
print("Reminder updated for message: \(event.messageId)")
} else if let event = event as? MessageReminderDeletedEvent {
print("Reminder deleted for message: \(event.messageId)")
} else if let event = event as? MessageReminderDueEvent {
print("Reminder due for message: \(event.messageId)")
}
}client.subscribeFor(
ReminderCreatedEvent::class.java,
ReminderUpdatedEvent::class.java,
ReminderDeletedEvent::class.java,
NotificationReminderDueEvent::class.java,
) { event ->
when (event) {
is ReminderCreatedEvent -> {
println("Reminder created for message: ${event.messageId}")
}
is ReminderUpdatedEvent -> {
println("Reminder updated for message: ${event.messageId}")
}
is ReminderDeletedEvent -> {
println("Reminder deleted for message: ${event.messageId}")
}
is NotificationReminderDueEvent -> {
println("Reminder due for message: ${event.messageId}")
}
else -> {}
}
}client.on(EventType.reminderCreated).listen((event) {
print('Reminder created for message: ${event.messageId}');
});
client.on(EventType.reminderUpdated).listen((event) {
print('Reminder updated for message: ${event.messageId}');
});
client.on(EventType.reminderDeleted).listen((event) {
print('Reminder deleted for message: ${event.messageId}');
});
client.on(EventType.notificationReminderDue).listen((event) {
print('Reminder due for message: ${event.messageId}');
});Webhooks
The same events are available as webhooks to notify your backend systems:
reminder.createdreminder.updatedreminder.deletednotification.reminder_due
These webhook events contain the same payload structure as their WebSocket counterparts. For more information on configuring webhooks, see the Webhooks documentation.