Go to Slack

Easy-peasy slash commands: Getting started

By D.E. Goodman-Wilson

You: Have a great idea for a new command to the new operating system for your business, but you're feeling a little confused as to how to start.

Me: Short on ideas, but I have some experience in writing the code we need.

So! Let's make like the Wonder Twins and build a slash command! 👫

Still from the motion picture '5 Centimeters Per Second' Still from the motion picture 5 Centimeters Per Second

In this tutorial we'll walk through the steps to write a slash command app, getting it running on your laptop or desktop computer, and connecting it to Slack. In a future tutorial we'll cover deploying your app to a service like Heroku so others can use it too.

If you've read my Easy-Peasy Bot tutorial, some of what follows might look familiar — there is a fair amount of overlap in building a Slack App of any kind! Please bear with me if I repeat myself.

Bots and apps and slash commands, oh my!

What is the difference between a bot and a slash command? Let's take a brief moment to understand the fundamental differences, and help you decide which you ought to be writing.

A bot is a program that connects to Slack just like you do: Slack effectively sees bots as users (but not as paid users, fear not!): They have access to the stream of messages that pass through Slack's servers, and they interact with Slack much like you do by reading and posting messages. Bots are great if you need a high degree of interactivity, or you want to be able to process the message stream as a gestalt.

A slash command, on the other hand, is like a command line utility for slack. It has a fixed syntax, and the program on the other end only ever sees the command itself. Likewise, it can only respond to that command in a limited way. Slash commands are great when you have a fixed set of interactions, and need to kick off a process on behalf of the user, or report structured data back to the user.

Most kinds of Slack Apps are best suited as slash commands, and so if you aren't sure, consider slash commands the default.

In this tutorial, I'm going to take you through the process of writing a slash command. If you decide that a bot is right for your idea, have I got the answer for you.

Slash commands with Botkit

Don't let the name fool you: Botkit is great for building more than just bots. Howdy.ai has done a lot (a lot) of the hard work for us, so why not leverage that?

First, we need to install some things. Make sure you have node installed on your local machine. If not, you have several options for installing node.

Begin by forking and then cloning this GitHub repository: https://github.com/DEGoodmanWilson/easy-peasy-slash-command-app. This is just the simplest possible slash command project built around one of the Botkit example apps. It includes everything we need to not only write a slash command, but set it up for distribution via the "Add to Slack" Button or even the App Directory, easy-peasy.

This is a Node.js project, so of course once you have the repository on your local machine, you will need to run

npm install

to install the various dependencies.

Next, edit the package.json file to give your slash command a name, and to update the GitHub URLs to reflect the location of your fork.

Exposing your app to the outside world

Slash commands can't do anything without some way to invoke them. We need to be able to open a secure HTTP connection to a service running locally on your laptop. There are many tools that will let us open such a window, such as *ngrok and Pagekite. But I'm going to use localtunnel. Just use *npm to install:

npm install -g localtunnel

and run localtunnel as such:

lt --port 8765 --subdomain myslashcommand

Once your slash command is running on local port 8765, it will be accessible at https://myslashcommand.localtunnel.me, but your slash command will only be available for testing really once it is installed on Slack. (You might consider changing myslashcommand to something more...memorable. And unique.)

Pass the good word to Slack

Now we need to let Slack know that your slash command exists. Couldn't be easier. Go to https://api.slack.com/applications/new and fill out the form. Don't worry too much about the support URLs. But do be clear on the redirect URL. Look to the localtunnel output: The redirect URL will be

https://myslashcommand.localtunnel.me/oauth

On the next page, you will see a more detailed form for setting up your new app. Scroll down until you see the slash command section:

Setting up your command

Click on "Create new command". You'll now be asked to fill in the details for your command. So that the command will work with the demo code, fill it out as such:

Readying for demo

It's kind of hard to see: The Request URL should be set to

https://awesomeslashcommand.localtunnel.me/slack/receive

Indeed, this is the URL you will use for any Botkit-based slash command — Botkit is prewired to expect all slash commands to arrive at this endpoint.

(A common gotcha at this point is having a URL that is not secure: Either it doesn't use HTTPS, or the security of the HTTPS connection can't be verified. If you are using localtunnel as advised above, this shouldn't be an issue. But once you deploy your slash command, you should be certain that your hosting service provides a valid HTTPS connection — but we can worry about this in a later tutorial.)

Slack gives us a nice little preview of what our slash command's auto-complete message will look like:

Auto complete

Once we've hit "Save", Slack will issue us a Verification Token. This is super important, as it is a secret handshake that Slack shares with us so we know that a given slash command was actually issued by Slack, and not by some imposter. Keep it safe, keep it secret — and make sure your slash command knows about it and is checking it. Slack issues one token per app, so if you have multiple slash commands, they will all use the same verification token.

Verification tokens

Running your slash command

We've got Slack all set up — now to look at the code, and make a slash command worthy of the name. The template code is pretty contrived, but provides all the basic tools you'll need to make a slash command work.

Running it locally

Now, the time has come to run your bot. From the directory your bot is installed in, simply run

CLIENT_ID=xxx.yyy CLIENT_SECRET=abc VERIFICATION_TOKEN=123 PORT=8765 npm start

And then visit https://awesomeslashcommand.localtunnel.me/login to install your bot on a team.

Don't forget to restart the slash command when you make changes to the source code!

Making it fancy

Botkit provides two functions for responding to a slash command: replyPublic() and replyPrivate(). The difference is that replyPublic() will post the response into the Slack channel for everyone to see. replyPrivate() on the other hand will post an ephemeral message that only the user issuing the command can see. For example, if you've ever used /giphy, its responses are public. On the other hand, /remind's responses are private — what Slack calls "ephemeral". Think carefully about whether the response should be publicized for all to see!

The demonstration slash command has a basic structure that looks like this:

// if no text was supplied, treat it as a help command
if (message.text === "" || mesage.text === "help") {
    slashCommand.replyPrivate(message,
        "I echo back what you tell me. " + 
        "Try typing `/echo hello` to see.");
    return;
}

// If we made it here, just echo what the user typed back at them //TODO You do it!

This code does something very simple, depending on what the user types:

/echo or /echo help both summon a snippet of helpful text that describes how to use the command. Always provide a help sub-command for your users in this way.

In every other case, we want the command to simply echo back to the user what they typed. So, let's replace the comment

//*TODO You do it!*

with some actual code. Use slashCommand.replyPublic() to accomplish this:

slashCommand.replyPublic(message, "Echo: " + message.text);

Try playing around with the message response; also try out using replyPrivate and observe the difference.

Delayed and asynchronous replies

In general, your app has 3000 milliseconds to send a reply (public or private), and can send at most one reply. For most cases, this is fine. But what if you need to hit a third-party API, or perform some time-intensive computation before you can respond? Or what if you need to send multiple replies? Enter the delayed reply.

Delayed replies are simply a different way of replying to a slash command that can be invoked up to 5 times, and up to 30 minutes later, giving your app lots of time to formulate its response. (You can read more about delayed replies and other awesome slash command tips in the official slash command style guide.) Using a delayed reply is just like using a regular reply:

slashCommand.replyPublicDelayed(message, "delayed response");

Note that if you send more than one delayed reply, Botkit does not guarantee the order if you send them procedurally — you'll need to use usual Node-style callback mechanism to ensure that your delayed replies are sent in the right order:

slashCommand.replyPublicDelayed(message, "first response",
  function() {
        slashCommand.replyPublicDelayed(message, "second response");
});

Congratulations!

👏 You've built your first slash command in Slack! Granted it doesn't do much — yet. But you've got ideas, I can feel it.

At this point you will probably want to start doing more sophisticated things, like making requests to external services, so your slash command can respond with timely and useful information (depending on what your app does, of course).

First, the Slack Platform team has a slash command style guide that covers idiomata and best practices that you should read, right this moment.

Second, There's a lot more to Botkit than can be easily covered here. You can learn more about Botkit's awesome features by simply perusing the Botkit documentation.

Next time...

Of course, you don't want to host your slash command on your laptop forever. (Or maybe you do?) Over the next articles, I will show you how easy it is to deploy your slash command to hosting services like Heroku, and give your slash command a more permanent memory. But at this point you should be far enough along to get your core logic going, and maybe even demo it.

Related documentation