A Slackbot is configured on the UI (there might be a way to do so programmatically, though not sure if there’s a need for it).

From there, one will obtain API keys for it (SLACK_API_TOKEN).

There are three ways to set up a Slack bot in Python. Slack has three Python SDKs, each in increasing levels of declarativeness:

  • SlackClient that provides more low-level control, and has access to some deprecated APIs/protocols
  • WebClient is more high-level
  • Bolt, a framework built on top of WebClient that makes big use of dependency injection to simplify things

Code Snippets (WebClient)

pip install slack-sdk
import os
 
from slack_sdk import WebClient
 
slack_client = WebClient(token=os.getenv("SLACK_API_TOKEN"))
 
# To post a message
slack_client.chat_postMessage(
    chanmel="...",  # Even for DMs
    text="...",  # Can also use `blocks` and `attachments` for richer outputs
    thread_ts="...",  # Optional timestamp ID of the parent thread, for threaded conversations
)

Listen for a Slack command

  1. Create a local webserver using something like Flask with a POST endpoint.
  2. Enable ngrok to expose the local webserver to the public
    • Ensure that the ngrok instance is validated with a personal token
    • Spin up the server with ngrok http <your-localhost-port-#>
  3. Run the local web application: python app.py

Code Snippets (Bolt)

pip install slack_bolt
app = App(
    token=get_secret("SLACK_BOT_TOKEN"),
    signing_secret=get_secret("SLACK_SIGNING_SECRET"),
    token_verification_enabled=os.getenv("SLACK_TOKEN_VERIFICATION_ENABLED", "true") == "true",
)
 
 
@app.event("app_mention")
def handler_fn(event, ack, say):
    # Send an acknowledgement
    ack()
 
	# Get context about the triggering event
    # and post a message back
    say("Hi there", thread_ts=event['thread_ts'])
 
 
@click.command(help="starts razorbot")
@click.option(
    "--socket-mode/--no-socket-mode", default=True, help="connection to Slack"
)
def main(socket_mode):
    if socket_mode:
        app_token = get_secret("SLACK_APP_TOKEN")
        handler = SocketModeHandler(slackbot, app_token)
        handler.start()
    else:
        slackbot.start(port=int(os.getenv("PORT", 8080)), path="/slack/events")
 
 
if __name__ == "__main__":
    main()

In the code above, we use socket_mode. This allows the application to communicate with the Slack instance without going through the HTTP protocol. This is helpful for an internal application or for applications/instances that sit behind a firewall.

Note

I’m not quite sure if socket_mode will still be used in production or not.

Another thing worth noting is that there are a few kinds of tokens available when building a slack bot:

TokenDescription
User token
Bot tokenUsed when creating the Bolt app or the WebClient.
Application tokenUsed when creating the SocketModeHandler

Permissionning

You need to enable some settings on the Slack application (api.slack.com) page otherwise events won’t be forwarded to your Bolt application.

  1. Go to “Event Subscription” on the left pane
  2. Enable “Enable Events”
  3. Scroll to “Subscribe to bot events”
  4. Add the required event listeners. The appropriate OAuth scopes will be granted.
    • For example, app_mention if you need to listen for an app, or message.channel to listen to messages in a channel

How to change the Slack bot’s display name?

  1. On Slack, click on the info of a Slack application (like on the name from the group chat).
  2. Once a modal pops up, click on “Configuration”. This redirects you to the application’s Slack webpage on your browser
  3. On the Slack application’s webpage, scroll to the bottom and you can then edit the name