If you just want to be able to post messages to public channels using a token that's only allowed to do that one thing, this tutorial is for you!
To get started, you'll need to create a Slack app. It's not a big deal, it's just a container for your credentials and where to put all the vital information about what your app is or does. You can't get a token without one.
We set up an app manifest with just the permissions you'll need to post messages to any public channel—without even having your app be a member. In this first step, you'll create an app following the prompts after the button below. When you're all done creating and installing your app, follow the banner back to this tutorial.
Features you’ll use
Tokens created by this manifest sure are potent! If you've been using Slack for a long time, this is more or less the equivalent of a classic legacy tester token, but operating as a bot instead of a user.
Quickly create an app with the correct configuration of scopes and features for this tutorial by clicking below.
Now that you have your token, let's start using it.
Now that you've created your app and have your token, we'll use it in the next steps with the command line tool curl.
If you're in a MacOS or modern UNIX environment, it's likely you already have curl available when you open up a terminal.
If you don't have curl or aren't already familiar with it, visit the venerable tool online at https://curl.se/.
Do you see your token below? If it's not a placeholder, that means you've arrived at this track after creating your app using the button above. Thank you!
xoxb-not-a-real-token-this-will-not-work
Anywhere you see xoxb-not-a-real-token-this-will-not-work
in this tutorial, that's where your real bot token should be.
First, let's make sure our token works. It's wise to do a sanity check when you first use a token in a new environment. Since you'll be copying and pasting your token around, it's possible for you to even lose it!
We're going to use our token to call the auth.test
Web API method. In the Slack Web API, the RPC (not REST) methods are served from slack.com
over HTTPS and all methods are part of the /api/
path.
Here's a verbose but best practice way to issue your first curl request.
curl -H "Authorization: Bearer xoxb-not-a-real-token-this-will-not-work" https://slack.com/api/auth.test
That looks so formal though! When you pass a token the preferred way, you must pass it as an Authorization
HTTP header with a special keyword that tells us exactly what kind of authorization you're presenting.
If you prefer to keep things tidier, you can do this too:
curl -d "token=xoxb-not-a-real-token-this-will-not-work" https://slack.com/api/auth.test
If the request works, you'll see curl print a JSON response in the command line indicating at the very least that "ok"
is true
. It'll also return some other info that's useful to identify just who or what the token you're using belongs to.
If you want to see even more about the request, try adding the --verbose
flag to the end of your curl request. It'll print out all the HTTP headers and you'll really see how the whole request sequence plays out.
If your token works—great! Let's proceed. And if it doesn't—make sure you've created an app, installed it, and copied your app's bot token before trying again.
With a working token, let's throw all caution to the wind and post a message to declare a bold "hello!" to the world. As is our custom.
You're going to need a public channel ID. Or your own user ID. The token we're using doesn't have permissions to list channels or users, so you're going to need to find one another way. This other tutorial introduces more privledged tokens that can retrieve data like this.
From here on out, I assume you have a public channel or user ID. For our example, we'll use C123456
a public channel I like to call #test
.
To start our message, we'll want to use some text. It'll become the text
parameter of our request to chat.postMessage
, the primary way to send messages into Slack.
We all say hello our own little way, today I'll use: "Hi I am a bot that can post messages to any public channel."
Preparing my request, I'll set that hello as my text
argument and C123456
as my channel
argument.
curl -d "text=Hi I am a bot that can post messages to any public channel." -d "channel=C123456" -H "Authorization: Bearer xoxb-not-a-real-token-this-will-not-work" -X POST https://slack.com/api/chat.postMessage
Executing this with your own token and channel ID, you should see a "ok": true
like before in the response (and more!) and also, your app's message posted to the target channel.
We did something a little different here. We used -d
to pass each argument separately. Curl will helpfully URL-encode strings you pass it, so we didn't have to manually modify each of our space characters to +
or %20
like curl ultimately will do for you. We added -X POST
to instruct curl to use the HTTP method POST. It might even have done it anyway, but with a write method I like to be explicit.
Block kit is the way to build UIs and vibrant messages on the Slack platform. If you want to go beyond a "hello world" you'll want to learn Block Kit next. With these app permissions, you can even extend your app to being fully interactive with Block Kit interactivity.
Block Kit Builder is a design tool that'll show you the possibilities and the JSON code to go with them.
When you have blocks you want to include with your message, it's best to change up how you send your arguments to curl to send application/json
instead, meaning the whole packet of info you send over to Slack will be in JSON.
First we'll make our hello world a little fancier and plan out its JSON.
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Hi I am a bot that can post *_fancy_* messages to any public channel."
}
}
]
}
Then we'll attach the other argument we need to send a message to the API—channel
. Since we'll send blocks
we won't need to send text
this time.
{
"channel": "C123456",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "Hi I am a bot that can post *_fancy_* messages to any public channel."
}
}
]
}
And now we'll package it up into a curl request. Here's one way to do that. We're going to remove newlines from our JSON and just stuff it into a single-quoted string. If your blocks
themselves had single-quoted strings, this wouldn't work out so well. Since this is a lot of stuff, we're breaking lines up by trailing each component with a \
character.
curl -H "Content-type: application/json" \
--data '{"channel":"C123456","blocks":[{"type":"section","text":{"type":"mrkdwn","text":"Hi I am a bot that can post *_fancy_* messages to any public channel."}}]}' \
-H "Authorization: Bearer xoxb-not-a-real-token-this-will-not-work" \
-X POST https://slack.com/api/chat.postMessage
If you can't get this one to work, try loading the blocks into Block Kit Builder and making sure everything transcribed right.
With a token with limited permissions like this—the ability to post to any public channel—you can go far. Sending notifications into Slack from the command line, scripts, or even complex applications or integrations is one of the primary use cases for our platform. I hope you can take what you've learned here today and apply it to your own workspace projects.