- Notifications
You must be signed in to change notification settings - Fork277
A framework to build Slack apps using Python
License
slackapi/bolt-python
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A Python framework to build Slack apps in a flash with the latest platform features. Read thegetting started guide and look at ourcode examples to learn how to build apps using Bolt. The Python module documents are availablehere.
# Python 3.7+ requiredpython -m venv .venvsource .venv/bin/activatepip install -U pippip install slack_bolt
Create a Bolt for Python app by calling a constructor, which is a top-level export. If you'd prefer, you can create anasync app.
importlogginglogging.basicConfig(level=logging.DEBUG)fromslack_boltimportApp# export SLACK_SIGNING_SECRET=***# export SLACK_BOT_TOKEN=xoxb-***app=App()# Add functionality hereif__name__=="__main__":app.start(3000)# POST http://localhost:3000/slack/events
export SLACK_SIGNING_SECRET=***export SLACK_BOT_TOKEN=xoxb-***python app.py# in another terminalngrok http 3000
If you useSocket Mode for running your app,SocketModeHandler is available for it.
importosfromslack_boltimportAppfromslack_bolt.adapter.socket_modeimportSocketModeHandler# Install the Slack app and get xoxb- token in advanceapp=App(token=os.environ["SLACK_BOT_TOKEN"])# Add functionality hereif__name__=="__main__":# Create an app-level token with connections:write scopehandler=SocketModeHandler(app,os.environ["SLACK_APP_TOKEN"])handler.start()
Run the app this way:
export SLACK_APP_TOKEN=xapp-***export SLACK_BOT_TOKEN=xoxb-***python app.py# SLACK_SIGNING_SECRET is not required# Running ngrok is not required
Apps typically react to a collection of incoming events, which can correspond toEvents API events,actions,shortcuts,slash commands oroptions requests. For each type ofrequest, there's a method to build a listener function.
# Listen for an action from a Block Kit element (buttons, select menus, date pickers, etc)app.action(action_id)(fn)# Listen for dialog submissionsapp.action({"callback_id":callbackId})(fn)# Listen for slash commandsapp.command(command_name)(fn)# Listen for an event from the Events APIapp.event(event_type)(fn)# Listen for a custom step execution from a workflowapp.function(callback_id)(fn)# Convenience method to listen to only `message` events using a string or re.Patternapp.message([pattern ,])(fn)# Listen for options requests (from select menus with an external data source)app.options(action_id)(fn)# Listen for a global or message shortcutsapp.shortcut(callback_id)(fn)# Listen for view_submission modal eventsapp.view(callback_id)(fn)
The recommended way to use these methods are decorators:
@app.event(event_type)defhandle_event(event):pass
Most of the app's functionality will be inside listener functions (thefn parameters above). These functions are called with a set of arguments, each of which can be used in any order. If you'd like to access arguments off of a single object, you can useargs, anslack_bolt.kwargs_injection.Args instance that contains all available arguments for that event.
| Argument | Description |
|---|---|
body | Dictionary that contains the entire body of the request (superset ofpayload). Some accessory data is only available outside of the payload (such astrigger_id andauthorizations). |
payload | Contents of the incoming event. The payload structure depends on the listener. For example, for an Events API event,payload will be theevent type structure. For a block action, it will be the action from within theactions list. Thepayload dictionary is also accessible via the alias corresponding to the listener (message,event,action,shortcut,view,command, oroptions). For example, if you were building amessage() listener, you could use thepayload andmessage arguments interchangably.An easy way to understand what's in a payload is to log it. |
context | Event context. This dictionary contains data about the event and app, such as thebotId. Middleware can add additional context before the event is passed to listeners. |
ack | Function thatmust be called to acknowledge that your app received the incoming event.ack exists for all actions, shortcuts, view submissions, slash command and options requests.ack returns a promise that resolves when complete. Read more inAcknowledging events. |
respond | Utility function that responds to incoming eventsif it contains aresponse_url (shortcuts, actions, and slash commands). |
say | Utility function to send a message to the channel associated with the incoming event. This argument is only available when the listener is triggered for events that contain achannel_id (the most common beingmessage events).say accepts simple strings (for plain-text messages) and dictionaries (for messages containing blocks). |
client | Web API client that uses the token associated with the event. For single-workspace installations, the token is provided to the constructor. For multi-workspace installations, the token is returned by usingthe OAuth library, or manually using theauthorize function. |
logger | The built-inlogging.Logger instance you can use in middleware/listeners. |
complete | Utility function used to signal the successful completion of a custom step execution. This tells Slack to proceed with the next steps in the workflow. This argument is only available with the.function and.action listener when handling custom workflow step executions. |
fail | Utility function used to signal that a custom step failed to complete. This tells Slack to stop the workflow execution. This argument is only available with the.function and.action listener when handling custom workflow step executions. |
If you'd prefer to build your app withasyncio, you can import theAIOHTTP library and call theAsyncApp constructor. Within async apps, you can use the async/await pattern.
# Python 3.7+ requiredpython -m venv .venvsource .venv/bin/activatepip install -U pip# aiohttp is requiredpip install slack_bolt aiohttp
In async apps, all middleware/listeners must be async functions. When calling utility methods (likeack andsay) within these functions, it's required to use theawait keyword.
# Import the async app instead of the regular onefromslack_bolt.async_appimportAsyncAppapp=AsyncApp()@app.event("app_mention")asyncdefevent_test(body,say,logger):logger.info(body)awaitsay("What's up?")@app.command("/hello-bolt-python")asyncdefcommand(ack,body,respond):awaitack()awaitrespond(f"Hi <@{body['user_id']}>!")if__name__=="__main__":app.start(3000)
If you want to use another async Web framework (e.g., Sanic, FastAPI, Starlette), take a look at the built-in adapters and their examples.
- The Bolt app examples
- The built-in adaptersApps can be run the same way as the syncronous example above. If you'd prefer another async Web framework (e.g., Sanic, FastAPI, Starlette), take a look atthe built-in adapters and their correspondingexamples.
The documentation has more information on basic and advanced concepts for Bolt for Python. Also, all the Python module documents of this library are availablehere.
If you otherwise get stuck, we're here to help. The following are the best ways to get assistance working through your issue:
- Issue Tracker for questions, bug reports, feature requests, and general discussion related to Bolt for Python. Try searching for an existing issue before creating a new one.
- Email our developer support team:
support@slack.com
About
A framework to build Slack apps using Python
Topics
Resources
License
Code of conduct
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.