Skip to main content

Click support for Slack-Bolt apps

Project description

Click support for Slack Apps

As a Python Slack-Bolt application developer I want to create slash-command that are composed with the Python Click package. I use the FastAPI web framework in asyncio mode.

I need support for --help --version and any usage error to be properly sent as Slack messages.

Quick Start

Check out the example application.

Async Usage

The following example illustrates how to device a Click group object and bind it to the Slack-Bolt command listener. In this example the code is all asyncio. Click was not written to support async io natively, so the @click_async decorator is required.

By default the Developer should pass the Slack-Bolt request instance as the Click obj value when executing the Click group/command. There is a mechanism to change this behavior, shown in a later example.

import click
from slack_bolt.request.async_request import AsyncBoltRequest as Request
from slack_click.async_click import click_async, version_option, AsyncSlackClickGroup

# -----------------------------------------------------------------------------
# Define a Click group handler for the Slack Slash-Command
#
# Notes:
#   @click_async decorator must be used for asyncio mode
#   @click.pass_obj inserts the click.Context obj into the callback parameters
#       By default the obj is the Slack-Bolt request instance; see the
#       @app.command code further down.
# -----------------------------------------------------------------------------

@click.group(name="/clicker", cls=AsyncSlackClickGroup)
@version_option(version="0.1.0")
@click.pass_obj
@click_async
async def cli_click_group(request: Request):
    """
    This is the Clicker /click command group
    """
    say = request.context["say"]
    await say("`/click` command invoked without any commands or options.")


# -----------------------------------------------------------------------------
# Register the command with Slack-Bolt
# -----------------------------------------------------------------------------

@app.command(cli_click_group.name)
async def on_clicker(request: Request, ack, say):
    await ack()
    await say("Got it.")

    return await cli_click_group(prog_name=cli_click_group.name, obj=request)

# -----------------------------------------------------------------------------
# Add a command the Click group
# -----------------------------------------------------------------------------

@cli_click_group.command("hello")
@click.pass_obj
async def click_hello_command(request: Request):
    await request.context.say(f"Hi there <@{request.context.user_id}> :eyes:")

Identifying the Slack-Bolt Request

As a Developer you may need to pass the Click obj as something other than the bolt request direct, as shown in the example above. You can identify where the Slack-Bolt request object can be found in the obj by passing a callback function to the click.command() or click.group() function called slack_request. This parameter expects a function that takes the click obj and returns the slack request.

The example below uses an inline lambda to get the request from the obj as a dictionary, using a the key "here".

from random import randrange

import click
from slack_bolt.request.async_request import AsyncBoltRequest as Request
from slack_click.async_click import click_async, AsyncSlackClickCommand

# -----------------------------------------------------------------------------
# /fuzzy command to manifest an anminal
# -----------------------------------------------------------------------------


animals = [":smile_cat:", ":hear_no_evil:", ":unicorn_face:"]


@click.command(
    name="/fuzzy", cls=AsyncSlackClickCommand, slack_request=lambda obj: obj["here"]
)
@click_async
@click.pass_obj
async def cli_fuzzy_command(obj: dict):
    request = obj["here"]
    say = request.context["say"]
    this_animal = animals[randrange(len(animals))]

    await say(f"Poof :magic_wand: {this_animal}")


@app.command(cli_fuzzy_command.name)
async def on_fuzzy(request: Request, ack):
    await ack()
    return await cli_fuzzy_command(
        prog_name=cli_fuzzy_command.name, obj={"here": request}
    )

Customizing Help

If you want to change the Slack message format for help or usage methods you can subclass AsyncSlackCLickCommand or AsyncSlackClickGroup and overload the methods:

  • slack_format_help - returns the Slack message payload (dict) for --help
  • slack_format_usage_help - returns the Slack message payload (dict) when click exception UsageError is raised.

References

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

slack_click-2.0.1.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

slack_click-2.0.1-py3-none-any.whl (11.1 kB view details)

Uploaded Python 3

File details

Details for the file slack_click-2.0.1.tar.gz.

File metadata

  • Download URL: slack_click-2.0.1.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.6 CPython/3.8.8 Darwin/19.6.0

File hashes

Hashes for slack_click-2.0.1.tar.gz
Algorithm Hash digest
SHA256 f315279cba35f00e381dd8561fd4ca993da89fa09abdc1cbf56e36e6f683494e
MD5 d70449422c67cafc92c7437a1aa0adbf
BLAKE2b-256 236dc9c707f9a3958a3deb3545033fbdd6bc1c420ca8d529e22f4d388773ff94

See more details on using hashes here.

File details

Details for the file slack_click-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: slack_click-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 11.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.6 CPython/3.8.8 Darwin/19.6.0

File hashes

Hashes for slack_click-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 19d41e614887f355a2f1704d2dd7e15dac2984c432e7e7ef5608b9e9c94a0733
MD5 7f676fbce20d9261c46e6486d6d95d09
BLAKE2b-256 8b6ffe6188a4271c903c1864bf46313543dc2ad64b5051ceafb1edc2eae5654d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page