Message Reminders

Message reminders allow users to set reminders for messages. This feature is useful when users want to be notified about messages that they need to follow up on.

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.

// 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)")
    }
}

Updating a message reminder

You can update an existing reminder for a message to change the reminder time.

// 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)")
    }
}

Deleting a message reminder

You can delete a reminder for a message when it’s no longer needed.

// 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)")
    }
}

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.

// 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)")
    }
}

Filtering reminders

You can filter the reminders based on different criteria:

  • 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).

// 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()

Pagination

If you have many reminders, you can paginate the results.

// 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)")
    }
}

Events

The following WebSocket events are available for message reminders:

  • reminder.created, triggered when a reminder is created.
  • reminder.updated, triggered when a reminder is updated.
  • reminder.deleted, triggered when a reminder is deleted.
  • notification.reminder_due, triggered when a reminder’s due time is reached.

When a reminder’s due time is reached, the server will also send a push notification to the user. Make sure you have configured push notifications in your app to handle these reminders.

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 = even as? MessageReminderDueEvent {
        print("Reminder due for message: \(event.messageId)")
    }
}
© Getstream.io, Inc. All Rights Reserved.