Go to Slack

Scheduling messages

The rundown
Read this if:You're still experimenting, prototyping, and exploring.
Read first:Sending messages
Read next:An overview of message interactivity

Getting started with scheduled messages

One thing you'll need before starting is a Slack app. If you don't have one yet, here's a very quick guide to help you create one. Make sure you create the app in a workspace that won't mind you posting lots of test messages!

Since scheduling a message is just a bit of fancy footwork on top of sending a message directly, take a gander at our guide to sending messages. After you've done that, come back here and keep reading.

Permissions

Now for some particularly pleasant permissions news: your app's permissions are actually the ones you've already acquired to post messages!

A quick recap: you can use either an app with a bot or user token. If you choose to use a bot, the bot scope is all you need. As a friendly reminder, the legacy bot token isn't supported.

With a user token, the first scope your app requires is channels:read. That scope lets your app retrieve a list of all the public channels in a workspace so that you can pick one to publish a message to. If you already know the ID of the channel you wish to send messages to, you can skip out on requesting channels:read.

The next scope you'll need is chat:write:bot or chat:write:user. That scope grants permission for your app to send messages.

Schedule a message

Our guide to directly sending messages talked you through a simple call to chat.postMessage. Let's reinvent our app to send a reminder instead: say, about a weekly team breakfast.

{
  "channel": "YOUR_CHANNEL_ID",
  "text": "Hey, team. Don't forget about breakfast catered by John Hughes Bistro today."
}

If you want to do things the hard way, your app could implement state storage and job scheduling to send this message at the right time each week, using a database and batch task runner.

If you prefer an easier approach, use a scheduled message instead. Add a post_at parameter to your JSON request, and pass your JSON to chat.scheduleMessage instead of chat.postMessage:

{
  "channel": "YOUR_CHANNEL_ID",
  "text": "Hey, team. Don't forget about breakfast catered by John Hughes Bistro today.",
  "post_at": 1551891428,
}

Then sit back and relax. Like magic, the message appears at the moment specified in the post_at UNIX timestamp.

Message in Slack conversation that shows a breakfast reminder from the Breakfast Club app

Helpful hint: messages can only be scheduled up to 120 days in advance, and can't be scheduled for the past.

The HTTP response from chat.scheduleMessage includes a scheduled_message_id, which can be used to delete the scheduled message before it is sent. Read on to find out how.

List the messages you've scheduled

"Fire and forget" reminders are all well and good, but the best-laid breakfast plans sometimes fall through. Let's say a holiday closes the office during one of your team's scheduled breakfast clubs. Better cancel that reminder message!

Your app can list all the messages that it currently has scheduled with the chat.scheduledMessages.list endpoint.

Call chat.scheduledMessages.list with optional channel, latest, and oldest parameters to specify which channel and time range you're interested in:

{
    "channel": "YOUR_CHANNEL_ID",
    "latest": 1551991429,
    "oldest": 1551991427,
}

oldest signifies the UNIX timestamp of the earliest range you're interested in. latest signifies, well, the latest. So oldest must be less than latest if both are specified.

The endpoint yields scheduled messages sent by your app, plus pagination information.

{
    "ok": true,
    "scheduled_messages": [
        {
            "id": "YOUR_SCHEDULED_MESSAGE_ID",
            "channel_id": "YOUR_CHANNEL_ID",
            "post_at": 1551991428,
            "date_created": 1551891734
        }
    ],
    "response_metadata": {
        "next_cursor": ""
    }
}

Now that you've got the id of the breakfast club reminder you want to delete, one more method call awaits, so read on.

Delete a message you've scheduled

With the scheduled_message_id that you need in hand, it's time to banish that breakfast reminder. Use the chat.deleteScheduledMessage endpoint:

{
    "channel": "YOUR_CHANNEL_ID",
    "scheduled_message_id": "YOUR_SCHEDULED_MESSAGE_ID"
}

You'll receive the typical success response once your scheduled message has been deleted.

Updating

To update a pending scheduled message, delete the old message and then schedule a new one.

Reminders, notifications, even calendars—all now fall within easy grasp of your app. You don't have to store any state at all if you don't wish to. Instead, list and delete your scheduled messages on the fly. Combine scheduled messages with user interactivity to create a chat bot that's a capable, clever assistant. Enjoy the newfound simplicity of scheduled messages!

Warnings and known issues

  • If your app tries to schedule a message in the past or more than 120 days in the future, we'll return an invalid_time error.
  • To update a pending scheduled message, you'll need to delete your old message and then schedule a new one.