|
| 1 | +Scheduled messages let a user write a message now and have it sent later. A server-side client can schedule, list, edit, cancel and send early the scheduled messages of any user. |
| 2 | + |
| 3 | +Scheduled messages must be enabled for your app. Until the scheduled message is sent it is visible only to the user who scheduled it (and to your backend); the channel's other members see nothing until the message is sent. |
| 4 | + |
| 5 | +## Scheduling a Message |
| 6 | + |
| 7 | +Pass `scheduledAt` to a regular send. The message is not sent: it is stored and sent at that time. The send time must be at least 1 minute and at most the app's maximum lead time (120 days by default) away. |
| 8 | + |
| 9 | +```java |
| 10 | +// Backend SDK |
| 11 | +Date in1Hour = new Date(System.currentTimeMillis() + 60 * 60 * 1000); |
| 12 | + |
| 13 | +MessageSendResponse response = |
| 14 | + Message.send("messaging", "general") |
| 15 | + .message(MessageRequestObject.builder().text("Good morning!").userId("john").build()) |
| 16 | + .scheduledAt(in1Hour) |
| 17 | + .request(); |
| 18 | + |
| 19 | +ScheduledMessage scheduled = response.getScheduledMessage(); |
| 20 | +scheduled.getId(); // ID of the scheduled message |
| 21 | +scheduled.getStatus(); // "scheduled" |
| 22 | +scheduled.getScheduledAt(); // when it will be sent |
| 23 | +``` |
| 24 | + |
| 25 | +`response.getMessage()` holds the message as it will be sent; it is not in the channel yet. Slash commands cannot be scheduled, and `scheduledAt` cannot be combined with `pending(true)` (`pending(false)` is accepted). |
| 26 | + |
| 27 | +## Listing Scheduled Messages |
| 28 | + |
| 29 | +Lists one user's scheduled messages across channels: pending ones first, then failed ones, each by `scheduled_at`. `userId` is required. Each item carries a summary of its channel. |
| 30 | + |
| 31 | +```java |
| 32 | +ScheduledMessageQueryResponse page = |
| 33 | + ScheduledMessage.query() |
| 34 | + .userId("john") |
| 35 | + .filter( |
| 36 | + ScheduledMessagesFilter.builder() |
| 37 | + .cid("messaging:general") // optional: one channel only |
| 38 | + .status("scheduled") // optional: scheduled, sending, failed |
| 39 | + .build()) |
| 40 | + .limit(100) // 1 to 100, defaults to 20 |
| 41 | + .request(); |
| 42 | + |
| 43 | +List<ScheduledMessage> items = page.getScheduledMessages(); |
| 44 | + |
| 45 | +// Next page |
| 46 | +if (page.getNext() != null && !page.getNext().isEmpty()) { |
| 47 | + ScheduledMessage.query().userId("john").next(page.getNext()).request(); |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | +Only sorting by `scheduled_at` ascending is supported. |
| 52 | + |
| 53 | +## Editing a Scheduled Message |
| 54 | + |
| 55 | +Replace the message, move the send time, or both. A new `message` replaces the stored one as a whole; the sender stays the user who scheduled it. |
| 56 | + |
| 57 | +```java |
| 58 | +ScheduledMessage.update(scheduled.getId()) |
| 59 | + .message(MessageRequestObject.builder().text("Good morning, everyone!").build()) |
| 60 | + .scheduledAt(new Date(System.currentTimeMillis() + 2 * 60 * 60 * 1000)) |
| 61 | + .request(); |
| 62 | +``` |
| 63 | + |
| 64 | +## Canceling a Scheduled Message |
| 65 | + |
| 66 | +Cancels a scheduled message so it is never sent, or removes one that failed. |
| 67 | + |
| 68 | +```java |
| 69 | +ScheduledMessage canceled = ScheduledMessage.delete(scheduled.getId()).request().getScheduledMessage(); |
| 70 | +canceled.getStatus(); // "canceled" |
| 71 | +``` |
| 72 | + |
| 73 | +## Sending a Scheduled Message Now |
| 74 | + |
| 75 | +Moves the send time to now and queues the send. |
| 76 | + |
| 77 | +```java |
| 78 | +ScheduledMessage.sendNow(scheduled.getId()).request(); |
| 79 | +``` |
| 80 | + |
| 81 | +Editing, canceling and sending now return a 409 error while the message is being sent. |
| 82 | + |
| 83 | +## Statuses and Failures |
| 84 | + |
| 85 | +| Status | Meaning | |
| 86 | +| ----------- | ------------------------------------------------------------------------------- | |
| 87 | +| `scheduled` | Waiting for its send time | |
| 88 | +| `sending` | Being sent | |
| 89 | +| `failed` | The send failed; `getFailureReason()` says why. It can only be deleted | |
| 90 | +| `canceled` | Canceled; returned by `delete` | |
| 91 | +| `sent` | Sent; reported only by the `scheduled_message.sent` event | |
| 92 | + |
| 93 | +Failure reasons: `banned`, `no_permission`, `channel_frozen`, `channel_deleted`, `user_deleted`, `moderation_blocked`, `hook_rejected`, `expired`, `internal_error`, `invalid_message`, `pending_not_supported`. |
| 94 | + |
| 95 | +## Events and Webhooks |
| 96 | + |
| 97 | +| Event | Webhook | When | |
| 98 | +| --------------------------- | ------- | -------------------------------------------------------------------- | |
| 99 | +| `scheduled_message.created` | No | A message was scheduled | |
| 100 | +| `scheduled_message.updated` | No | A scheduled message was edited or sent now | |
| 101 | +| `scheduled_message.deleted` | No | A scheduled message was canceled | |
| 102 | +| `scheduled_message.sent` | Yes | A scheduled message was sent; `getMessageId()` is the sent message ID | |
| 103 | +| `scheduled_message.failed` | Yes | A scheduled message failed to send | |
| 104 | + |
| 105 | +`Event.getScheduledMessage()` holds the scheduled message on all of them. The sent message itself also triggers the usual `message.new`. |
| 106 | + |
| 107 | +## Permissions |
| 108 | + |
| 109 | +Scheduling needs the `ScheduleMessage` permission (channel capability `schedule-message`) in addition to the permission to send the message. |
0 commit comments