Skip to content

Slash Commands

Next to triggering Slack Machine by listening to messages that match a specific regular expression, you can also use Slash Commands in Slack Machine.

Creating a Slash Command

To configure a Slash Command for your Slack App, you can follow the instructions in the official Slack documentation. As you will have likely followed the guide to using Slack Machine, you propbably have already defined a Slack App. This is what you need to do next:

  1. Go to your app's management dashboard
  2. Click your Slack App
  3. Go to Slash Commands in the navigation menu
  4. Click the Create New Command button and follow the instructions

Using the App manifest

If you used the example App manifest when creating your Slack App, you can also adjust that to include the Slash Commands you want to define. You can add it under features as follows:

features:
  bot_user:
    display_name: My Bot
    always_online: false
  slash_commands:
    - command: /hello
      description: Say hello
      usage_hint: "[whatever else you want to say]"
      should_escape: false

Defining your Slash Command in code

The next step is to use the @command decorator on the function that should be triggered when the user uses the Slash Command you defined. The decorator takes only 1 parameter: the slash command that should trigger the decorated function. It should be the same as the Slash Command you just defined in the App dashboard.

This is what a decorated command handler typically looks like:

@command("/hello")
async def hello(self, command):
    print(f"I just received the following command: {command.command} with text {command.text}")
    await command.say("I like greetings!")

Parameters of your command handler

Your command handler will be called with a Command object that contains useful information about the slash command invocation. The most important property is probably text, which contains any additional text that was passed when the slash command was used.

You can optionally add the logger argument to your handler get a logger that was enriched by Slack Machine

Responding to a command

Responding to Slash Commands is a timely business. As explained in the official documentation, the receipt of the slash command payload has to be acknowledged. This has to happen within 3 seconds, or Slack will return an error to the user. To make your life easy, Slack Machine will handle all of this.

If you want to send a message to the user after a slash command was invoked, you can do so by calling the say() method on the command object your handler received from Slack Machine. This works just like any other way Slack provides for sending messages. You can include just text, but also rich content using Block Kit

Info

The response_url property is used by the say() method to send messages to a channel after receiving a command. It does so by invoking a Webhook using this response_url This is different from how message.say() works - which uses the Slack Web API.

The reason for this is to keep consistency with how Slack recommends interacting with a user. For commands, using the response_url is the recommended way

If you read the aforementioned documentation on responding to commands carefully, you'll notice that as part of acknowleding the receipt of a command payload, you can return a response to the user (which has to happen in 3 seconds). This is different from the command.say() method, which does not have any timing requirements. Slack Machine supports returning an immediate response by turning your command handler into a generator and returning an immediate response through yield:

@command("/hello-again")
async def hello_again(self, command):
    print(f"I just received the following command: {command.command} with text {command.text}")
    # this is sent as part of the initial payload acknowledgement
    yield "This will be returned immediately to the user"
    # this is less time-sensitive
    await command.say("This will be sent after the initial acknowledgement")

Opening modals

The Command object that your handler receives, contains an extra piece of information you can use to trigger more varied reponses: the trigger_id The trigger_id can used specifically to trigger modal responses. You don't have to worry about the trigger_id and instead can just call the open_modal method on the Command object to open a modal.