This guide explains how to craft a new Slack app from the ground up.
To get started, create a new Slack app with this friendly UI:
This guide is for developers who've never followed a Slack app recipe before, but want to cook with the latest ingredients from the Slack platform.
If you're an experienced chef, already familiar with seasons of Slack apps past, check out this quickstart guide that explains exactly what new ingredients have arrived to apps.
Otherwise, read on!
This guide walks you through making a new Slack app using the Slack App Management UI.
New Slack apps are safer for users to install, less prone to unexpected uninstalls, and even have new features not available to classic apps. So let's get cooking, starting with the first ingredient: creating an app.
If you haven't already, create a new Slack app with our easygoing UI:
Fill out your App Name and select the Development Workspace where you'll play around and build your app. Don't fuss too much over either field—no matter what workspace you select, you'll still be able to distribute your app to other workspaces if you choose.
Preheat the oven and ready your app for action by requesting scopes. Scopes give your app permission to do things (for example, post messages) in your development workspace.
You can select the scopes to add to your app by heading over to the OAuth & Permissions sidebar.
Scroll down to the Scopes section and click to Add an OAuth Scope.
For example, try adding the
chat:write scope to your Bot Token. It'll allow your app to post messages! While you're at it, add the
channels:read scope so your app can gain knowledge about public Slack channels.
If you're confused about the difference between adding a Bot Token Scope or a User Token Scope, worry not:
Add scopes to your Bot Token, not your User Token.
It's really that simple. There's actually only two exceptions:
Otherwise, it's bot tokens all the way down.
Sure, you can request any scope you want—but final say always resides with the user installing your app. Like a picky eater, a user can choose to refuse any and all installs that seem to request permissions beyond what an app truly needs.
Try it out! Install your own app by selecting the Install App button on the sidebar.
After clicking through one more green Install App To Workspace button, you'll be sent through the Slack OAuth UI.
Here's a potentially confusing bit: when you follow this flow with Slack, you're playing the part of the installing user, the picky eater—not the app! If you were adding your app to a different workspace besides your development workspace, this flow would be completed by a user from that workspace, not you.
As a user, you're choosing to trust the app. Is it trustworthy? Well, you just built it—hopefully, it's not too bad.
After installation, you'll find an access token inside your app management page. Look for it under the OAuth & Permissions sidebar.
Access tokens are imbued with power. They represent the permissions delegated to your app by the installing user. Remember to keep your access token secret and safe, to avoid violating the trust of the installing user.
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.
Your access token allows you to call the methods described by the scopes you requested during installation.
For example, your
chat:write scope now allows your app to post messages. Your app probably isn't a member of any channels yet, so pick a channel you don't mind adding some test messages to and
/invite your app.
You can find the corresponding
id for the channel that your app just joined by looking through the results of the
curl https://slack.com/api/conversations.list -H "Authorization: Bearer xoxb-1234..."
You'll receive a list of
Now, post a message to the same channel your app just joined with the
curl -X POST -F channel=C1234 -F text="Reminder: we've got a softball game tonight!" https://slack.com/api/chat.postMessage -H "Authorization: Bearer xoxb-333649436676-799261852869-clFJVVIaoJahpORboa3Ba2al"
Voila! We're already well on our way to putting a full-fledged Slack app on the table.
Want more tips on cooking up the perfect API call? Check out the Web API guide for some technical tricks.
Just want to see all the different methods you can call? Check out the methods list, our cookbook detailing all the API calls you can make with Slack. If you select any method, you'll see the nutrition facts that explain exactly what parameters the method takes, plus additional bits of knowledge.
New Slack apps do not begin life with the ability to post to any public channel without joining. Nor do they start with the ability to adjust username or icon when posting messages—that is, message authorship.
Good news: with two special scopes, you can gain those abilities by asking for them explicitly.
chat:write.public scope to gain the ability to post in all public channels, without joining. Otherwise, you'll need to use
conversations.join, or have your app invited by a user into a channel, before you can post.
Also, you can adjust your app's message authorship with the help of the
chat:write.customize scope. Once you've requested the scope, you can make use of the
icon_emoji parameters in
chat.postMessage. Read up on the documentation here.
One fundamental pattern of Slack apps is listening and responding.
We've already touched on one way an app can respond: by calling
chat.postMessage to post a message.
But our app isn't a very good listener yet. An app that speaks without being prompted can be distracting at best and outright disruptive at worst.
Apps always respond to something. It might be a mention in channel, a button pushed to trigger an action, even a user entering into a DM with the app. But apps never act for no reason.
Apps listen with the Events API. Events are just what you'd expect: notifications, sent to your app, about happenings in Slack. Each type of event lets your app know about a certain type of happening.
Let's subscribe to the
app_mention event. Select the Event Subscriptions sidebar and search for
app_mention, then click to Add Bot User Event. As with scopes, always subscribe to events with a bot user, unless only a user token will do.
Set the Request URL to a URL where your app's server listens to incoming HTTP requests. Slack will send an HTTP request there when your app is mentioned, allowing your app to figure out how it wants to respond.
If setting a server up makes you nervous, there's plenty of help in our tools and SDKs for programming languages, which implement a server listening for events automatically.
You'll notice that the
app_mention event requires the
app_mention:read scope. Events are like API methods: they allow your app access to info in Slack, so you need permission for them. Reinstall your app with the new scope.
Now you'll be notified when your app is mentioned, and you can respond however you like:
commands scope to build a Slash command. Request the
incoming-webhook scope to use Incoming Webhooks. Both features act exactly the way they did for classic Slack apps, with one big exception:
Slash commands and Incoming Webhooks are now tied to your bot user and bot token, not a user. That means you're safe from unexpected installs if the user who builds a command or webhook leaves the workspace!
New Slack apps will not support Slash commands or Incoming Webhooks on a user token. They can only be obtained by the app's bot user.
A link shared in a channel will only be unfurled if the token with
links:write has access to the message that contains the link. For example, if you have a new Slack app and an installing user shares a link to a private channel, but the new Slack app is not in that private channel, that link will not unfurl.
Cooking is a life-long pursuit, and Slack apps have the same complexity. From here, you can go on to build mouth-watering interactive workflows; spice up your sentences with Block Kit; even pursue building for larger Enterprise Grid organizations, which contain multiple workspaces.
rtm.connectmethod, or for any other reason, click here: