home
Boltworks¶
A collection of various extensions for Slack's bolt library to help you more easily make better slackbots.
The main features are: * Easy CLI parsing using the ArgParse library (or an automagic function parser that determines what params you need) * Easy callbacks on buttons and other GUI elements * A fast and flexible way of posting lots of information in a dynamically expandable GUI format
Getting Started¶
1 |
|
Follow the instructions at https://github.com/slackapi/bolt-python to begin setting up a Slackbot. Note that BoltWorks is not presently designed for async use, but any of the non-async handlers should work. For testing purposes, socket mode tends to be the easiest. All the rest of the demos will assume you've already instantiated a slack app
.
Easy CLIs with the @argparse_command decorator¶
This allows you to use Python's argparse library to process complex command line flags and options in Slack Commands. As usual, a --help flag will be generated for you. And if your method is type hinted, you can use Automagic mode to create a parser automagically.
All Slack parameters will be passed through to your method; you can use the 'args' catchall, and/or individual arguments like 'respond' or 'context' etc All other parameters will be parsed from the command string when the command is run.
The explicit way¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
@app.command(re.compile("/exponent")) @argparse_command(automagic=True) def power_calculator(respond, x: int, y:int, mode:Optional[Literal["q","v"]]=None): answer = x**y if mode=="q": respond(text=answer) elif mode=="v": respond(text=f"{x} to the power {y} equals {answer}") else: respond(text=f"{x}^{y} == {answer}")
1 2 3 4 5 6 |
|
disk_cache=DiskCacheKVStore(Cache(directory=DISK_CACHE_DIR)) callbacks=ActionCallbacks(app,disk_cache.using_serializer(dill))
def get_elapsed_time(args:Args, start:datetime): diff = datetime.now() - start formatted_diff = f"{diff.seconds//3600:02d}:{(diff.seconds%3600)//60:02d}:{diff.seconds%60:02d}" args.respond(f"time elapsed: {formatted_diff}")
def start_timer(args:Args): now=datetime.now() get_elapsed_button=callbacks.get_button_register_callback("get elapsed time",partial(get_elapsed_time,start=now)) timer_started_message="Timer started at "+now.strftime("%A, %B %d, %Y %I:%M:%S %p") block=slack_sdk.models.blocks.SectionBlock(text=timer_started_message,accessory=get_elapsed_button) args.say(blocks=[block])
start_timer_button=callbacks.get_button_register_callback("start a timer",start_timer) timer_start_block=slack_sdk.models.blocks.SectionBlock(text="click here to start a timer",accessory=start_timer_button) app.client.chat_postMessage(blocks=[timer_start_block],channel=CHANNEL_ID) ```
ThreadCallbacks¶
Similiar to ActionCallbacks, this class allows you to register a message's ts
(timestamp used by slack as a message id), so that your callback will be called any time a message is posted to that Thread.
NodeTreeUI - dynamic nested information formatter¶
Main article: docs/treenode.md
(also see the TreeNodeUI class in docs)
This module allows you to display complex nested information neatly, in a user-clickable, expanding and contracting view. The TreeNodeUI class handles all the logic of formatting these trees and responding to clicks.