Package: slash-slack
slash-slackA python framework for building slack slash bots. Get input parsing and validation, command routing, async responses, auto-generated help dialog, response visibility, and response message formatting all for free.slash-slackis a web server with a single endpoint (by default/slash_slack). In order to connect the Slack Slash command with theslash-slackserver, theslash-slackserver must be publicly accessible and the slash command must be configured with Slack. ViewSlack slash command documentationhere.# EX: /slash-slack math 10 * 10# Response: 100.0importosfromslash_slackimportFlag,Float,SlashSlack,Stringslash=SlashSlack(signing_secret=os.environ['SLACK_SIGNING_SECRET'])app=slash.get_fast_api()@slash.command("math")defmath_fn(x:float=Float(),symbol:str=Enum(values={"*","+","-","/"}),y:float=Float(),):ifsymbol=="*":returnx*yifsymbol=="+":returnx+yifsymbol=="-":returnx-yifsymbol=="/":returnx/yView a tutorial of creating a Slack slash command bot withslash-slackhere.Why useslash-slack?Building a slack slash bot can seem very straightforward at first, however there are some complexities that make it difficult.slash-slackhandles all of the complexities for you letting you focus on the bot response handlers.Webhook signature verificationslash-slackwill verify that incoming requests were made by slack by validating the request signature. To disable signature verification use thedev=Trueoption when creating theSlashSlackobject.Command Response Timeout/Async responsesSlack requires that the slash bot webhook be responded to within 3 seconds.Often times the action being taken by the bot will depend on external services which might not respond within 3 seconds.slash-slacksends an immediate200response to the webhook request, and runs the command function in the background. When the command function finishes, the response is sent back to slack using theresponse_urlfrom the request.You can optionally add content to the immediate response to let your user know that something is being
done in the background. A global/default response can be set with theacknowledge_responseparameter on
theSlashSlackclass, or at the command level with theacknowledge_responseparameter on thecommanddecorator.
The value passed toacknowledge_responsewill be passed toblocks._make_block_messageand can be astr,block,list[str], orlist[block]where ablockis ablock kit block.
See theexamplefor example usage.Input Arg/Flag parsingslash-slacktakes care of parsing command input into pre-defined args and flags which let you focus on writing the command function, and not wrangling the content into the format that you need.Auto-generated helpslash-slackprovides help dialog auto-generated from your commands, args, and flags. Additional details can be embedded directly into the command decorator and arg/flag initializers.To request global help:/slash-slack helpTo request command specific help:/slash-slack command --helpResponse visibilitySlack slash command responses can be made visible only to the requestor, or to the entire channel.slash-slackadds the ability for any command to be made visible with the--visibleflag.Response formattingSlack expects responses to be in the Slack Block Kit format.slash-slackwill automatically convert your string responses into slackmrkdownblocks.Deploymentslash-slackis a WSGI app based on the FastAPI framework. Deploy usinguvicorn.
You must expose the underlying app from theSlashSlackbot.# main.pyfromslash_slackimportSlashSlackslash=SlashSlack()app=slash.get_fast_api()uvicorn main:app --port 9002 --reloadDevelopment/Webhook mocking.A mock slack webhook clientmock-slackis bundled withslash-slack. This client can be used to mock webhooks sent by slack.To enter the mock slack client simply runmock-slack.SlashSlackmust bedev=Trueto disable signature verification.mock-slackwill prompt you for input. Responses from theslash-slackserver will be served in your browser in the Slack Block Kit Builder.$ mock-slack
MSG: echo testCommand InputsThe inputs and parsing for each command is determined by the parameters to the function.SlashSlackparses the function parameters and generates an input schema.When a request is made to a given command,SlashSlackattempts to parse the input text into the command input schema.FlagsFlags are boolean options that can be added to commands anywhere within the request. During the input parsing, flags are parsed and removed, and then args are parsed.There is no difference in doing/slash-slack command arg --flagand/slash-slack command --flag arg.Global FlagsThere are 2 global flags:--visibleand--help.The--visibleflag will make the response visible in the channel that the request was made. By default, responses are only visible to the user which made the request.The--helpflag will indicate that theSlashSlackapp should return the relevant help message. Whether that is app level/slash-slack --help, or command level/slash-slack command --help.ArgsAll non-flag arguments to the command function make up the input schema for the command function. This means that the # of words in the command request must match up with the # of non-flag arguments. (With two exceptions: String, UnknownLengthList).StringWhen the only non-flag parameter for the function is aString()then the entire argument body (with flags removed) will be passed into that parameter.# EX: /slash-slack echo hello --upper world# Response: HELLO WORLD@slash.command("echo")defecho(s:str,upper:bool=Flag()):returnsUnknown Length ListTo collect an arbitrary # of args from the user use theUnknownLengthListarg type. This arg type will be passed a list of all of the values passed to it parsed into the given type.Because this consumes args till the end of the arg list, this must be the last non-flag param for the command function.# EX: /slash-slack avg 10, 20, 30# Response: 20.0@slash.command("avg")defavg(numbers=UnknownLengthList(arg_type=Float())):returnsum(numbers)/len(numbers)SlashSlackRequestIf you want to have access to the complete request as sent from the slack servers. Add a param with the type annotation ofSlashSlackRequestto the command function.# EX: /slash-slack echo hello world# Response: hello world This request was made by John Doe@slash.command("echo")defecho(content:str,slash_slack_request:SlashSlackRequest):returnf"{content}This request was made by{slash_slack_request.user_name}"Example Application with UsagefromtypingimportListfromslash_slackimportEnum,Flag,Float,SlashSlack,String,UnknownLengthListslash=SlashSlack(signing_secret=os.environ["SLACK_SIGNING_SECRET"],description="A python framework for slack slash bots.",)app=slash.get_fast_api()@slash.command("echo",summary="Echo",help="Returns the provided text (made upper or lower case)",)deftest_fn(content:str=String(help="The content which will be echoed"),upper:bool=Flag(help="Converts the input text to all UPPERCASE"),lower:bool=Flag(help="Converts the input text to all lowercase"),):ifupper:returncontent.upper()iflower:returncontent.lower()returncontent@slash.command("math",summary="Performs basic arithmetic between two numbers",)defmath_fn(x:float=Float(help="A number."),symbol:str=Enum(values={"*","+","-","/"},help="The arithmetic operation to use."),y:float=Float(help="A number."),):ifsymbol=="*":returnx*yifsymbol=="+":returnx+yifsymbol=="-":returnx-yifsymbol=="/":returnx/y@slash.command("avg",summary="Return the average of the given numbers",help="EX: `avg 90 100 110.9`",)defunknown(nums:List[float]=UnknownLengthList(arg_type=Float(),help="The numbers to average."),):returnf"The avg of the given numbers is{sum(nums)/len(nums)}"Global Help/slash-slack helpCommand Help/slash-slack math --helpCommand invocation/slash-slack math 10 * 20Command parsing error/slash-slack math a * 100