Post messages on a schedule

This tutorial will walk you through the creation of a Slack app that can regularly post messages to a particular Slack channel.

Features you’ll use

Scopes you'll request

Create a pre-configured app

Quickly create an app with the correct configuration of scopes and features for this tutorial by clicking below.

1Before you begin

Every Slack app journey begins with a few common steps. You'll need to create an app, give it some permission scopes, and then install it to a suitable development workspace.

  • Setting up a Slack app
    Watch our video showing how to create and setup a new Slack app.

    We'll show you how to use the app config pages and give you a brief tour of all the features you can setup for your app.

  • Create an app

    You won't get far without a Slack app to accompany you on this journey. Start here by creating an app.

  • Requesting scopes for your app

    Scopes give your app permission to do things (for example, post messages) in Slack. They're an essential component of any functional Slack app.

    Each scope that you add to your app will be presented in a permission request dialog during app installation. When you're building an app in a development workspace that you control, you'll be able to experience both sides of this system.

    Each app can use lots of different scopes, with the exact list depending on the type of access token the app will use. We favour using bot tokens for most apps, so we'll explain how to request scopes for that token type.

    To choose the scopes to add to your app:

    1. Head over to app config page for your app.
    2. Navigate to the OAuth & Permissions page.
    3. Scroll down to the Bot Token Scopes section.
    4. Click Add an OAuth Scope.
    5. Add the scopes listed above.

    Once added, the scope list will be saved automatically. Your app will now request these scopes during installation.

    If you add scopes to your app config after installation, simply reinstall your app to request and grant permission for the added scopes.

    To read more about scopes and permissions, check out our app authentication docs.

  • Install your app

    Your app can request any scope you want—but final say always resides with the user installing your app. A user can choose to refuse any and all installs that seem to request permissions beyond what they're comfortable granting.

    When you're installing your app to your own development workspace, you can experience this process for yourself.

    To install your app to your development workspace:

    1. Head over to app config page for your app.
    2. Navigate to the Install App page.
    3. Click Install to Workspace.

    You'll be redirected to the OAuth permission request dialog:

    Oauth UI for users

    As a user, you're choosing to trust the app. Is it trustworthy? Well, you're building it—hopefully, it's not too bad. After installation, you'll be redirected back to your app config. You'll see the newly generated access token on the Install App page you're redirected to.

    Access tokens are imbued with power. Your app is able to use this new access token to do practically everything that a Slack app can do.

    Remember to keep your access token secret and safe, to avoid violating the security of your app, and to maintain the trust of your app's users.

    At a minimum, avoid checking your access token into public version control. Access it via an environment variable. We've also got plenty more best practices for app security.

  • Use Bolt to build your app

    Bolt is a framework that lets you build Slack apps in a flash—available in JavaScript, Python, and Java.

    Bolt handles much of the foundational setup so you can focus on your app's functionality. Out of the box, Bolt includes:

    • A basic web server to run your app on
    • Authentication and installation handling for all the ins and outs of OAuth
    • Simplified interfaces for all Slack APIs and app features
    • Automatic token validation, retry, and rate-limiting logic

    Bolt also has built-in type support, so you can get more work done right from your code editor.

    Follow our guides on getting started with Bolt for JavaScript, Bolt for Python, or Bolt for Java. Or dig deeper by exploring our resources and sample code.

2Compose your message

Your Slack app can publish simple text messages to public channels or private conversations just as users can.

Apps, however, can also include special visual components in their messages. These messages are designed using a framework we call Block Kit.

Composing a message involves choosing blocks from Block Kit, and laying them out to present important data. In doing so, you’ll create an array of Block Kit objects that will be used when publishing a message.

When you're done

After you've finished with this step, you will be able to generate your own message payload.

  • Create a basic message payload

    All of the Slack APIs that publish messages use a common structure, called a message payload.

    This payload is a JSON object that is used to define the content of the message and metadata about the message. The metadata can include required information such as the conversation the message should be published to, and optional parameters which determine the visual composition of the message.

    Here's a very basic app-published message payload:

      "channel": "CONVERSATION_ID",
      "text": "Hello, world.",

    You can go further to customize published messages by using special text formatting, or by composing a blocks parameter to define a rich, and potentially interactive, message layout.

    View our message payload reference for a list of potential payload parameters.

  • Find a place to publish your message

    When an app publishes a message, the app needs to know which Slack conversation the message should be added to.

    In order to find a valid Slack conversation ID, we'll use the conversations.list API method. This API will return a list of all public channels in the workspace your app is installed to. You'll need the channels:read permission granted to your app.

    Within that list, we'll be able to find a specific id of the conversation that we want to access. Here's an example API call:

    Finding a conversation in HTTP

    Authorization: Bearer xoxb-your-token

    Explore our developer tools to simplify your app development.

    You'll get back a JSON object, with a channels array containing all the public channels that your app can see. You can find your channel by looking for the name in each object.

    When you've found the matching channel, make note of the id value, as you'll need it for certain API calls.

    If your app implements shortcuts, slash commands, or uses the Events API, your app will see conversation ids in request payloads sent by those features.

    In those cases, your app can dynamically respond using the payload data to identify the relevant conversation, rather than needing to use the conversations.list method described above.

  • OptionalFormat text in your message

    Text within message payloads can be formatted using a special markup syntax called mrkdwn. Consult this reference guide to learn everything you can do with mrkdwn.

  • OptionalCreate a rich message layout

    Slack provides a range of visual components, called Block Kit, that can be used in messages. These components can lay out complex information in a way that's easy to digest.

  • OptionalPrototype and preview message layouts

    Use Block Kit Builder to visually prototype app-publishable messages.

3Learn how to use the Web API

The Web API is the core of every Slack app's functionality. Here, we'll use it to access the API for scheduling messages.

Before we do that, familiarize yourself with the process for actually using the API. We recommend using Bolt to save yourself a lot of time and effort.

When you're done

After finishing this step, you should be familiar with the basics of using the Web API in an app.

  • Using the Slack Web API with Bolt

    If you're using our Bolt framework, which we recommend, making Web API calls is simple. All flavours of Bolt use a similar client interface, with API parameters passed as arguments.

    Here's a basic Bolt example that calls chat.postMessage:

    Calling chat.postMessage in JavaScript

    Show code to initialize app
    // ID of the channel you want to send the message to const channelId = "C12345"; try { // Call the chat.postMessage method using the WebClient const result = await{ channel: channelId, text: "Hello world" }); console.log(result); } catch (error) { console.error(error); }

    New to building Slack apps with JavaScript? Read Getting Started with Bolt for Javascript.

    If you're curious, you can read more about how Bolt can be used to call the Web API—just consult the relevant Bolt for JavaScript, Bolt for Python, or Bolt for Java docs.

  • AlternativeUse the Web API manually

    Not using Bolt? Read how to manually build an app that can interact with the Web API.

4Schedule a message to publish

Putting everything you've learned above together, you're ready to make the API calls that will schedule a message for publishing.

You could choose to handle the scheduling of publishing entirely within your own app, but it's likely simpler to use our APIs to handle that for you.

  • Schedule a message with Bolt

    If you're using Bolt, calling chat.scheduleMessage is really simple. Just follow the Bolt example below:

    Scheduling a message in JavaScript

    Show code to initialize app
    // Unix timestamp for tomorrow morning at 9AM const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); tomorrow.setHours(9, 0, 0); // Channel you want to post the message to const channelId = "C12345"; try { // Call the chat.scheduleMessage method using the WebClient const result = await{ channel: channelId, text: "Looking towards the future", // Time to post message, in Unix Epoch timestamp format post_at: tomorrow.getTime() / 1000 }); console.log(result); } catch (error) { console.error(error); }

    New to building Slack apps with JavaScript? Read Getting Started with Bolt for Javascript.

  • AlternativeSchedule a message manually

    If you're not using Bolt, you'll need to manually create an API call to chat.scheduleMessage. Here's a simple example:

    Scheduling a message in HTTP

    Content-type: application/json
    Authorization: Bearer xoxb-your-token
      "channel": "YOUR_CHANNEL_ID",
      "text": "Hey, team. Don't forget about breakfast catered by John Hughes Bistro today.",
      "post_at": 1551891428,

    Explore our developer tools to simplify your app development.

    Read our guide to the chat.scheduledMessage API if you want to learn more about the feature.

Was this page helpful?