-
Notifications
You must be signed in to change notification settings - Fork 235
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into issue-199-detecting-invalid-event-type
- Loading branch information
Showing
43 changed files
with
1,793 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ coverage: | |
status: | ||
project: | ||
default: | ||
threshold: 0.3% | ||
threshold: 2.0% | ||
patch: | ||
default: | ||
target: 50% |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
--- | ||
title: Using Socket Mode | ||
lang: en | ||
slug: socket-mode | ||
order: 16 | ||
--- | ||
|
||
<div class="section-content"> | ||
With the introduction of [Socket Mode](https://api.slack.com/apis/connections/socket), Bolt for Python introduced support in version `1.2.0`. With Socket Mode, instead of creating a server with endpoints that Slack sends payloads too, the app will instead connect to Slack via a WebSocket connection and receive data from Slack over the socket connection. Make sure to enable Socket Mode in your app configuration settings. | ||
|
||
To use the Socket Mode, add `SLACK_APP_TOKEN` as an environment variable. You can get your App Token in your app configuration settings under the **Basic Information** section. | ||
|
||
While we recommend using [the built-in Socket Mode adapter](https://github.com/slackapi/bolt-python/tree/main/slack_bolt/adapter/socket_mode/builtin), there are a few other 3rd party library based implementations. Here is the list of available adapters. | ||
|
||
|PyPI Project|Bolt Adapter| | ||
|-|-| | ||
|[slack_sdk](https://pypi.org/project/slack-sdk/)|[slack_bolt.adapter.socket_mode](https://github.com/slackapi/bolt-python/tree/main/slack_bolt/adapter/socket_mode/builtin)| | ||
|[websocket_client](https://pypi.org/project/websocket_client/)|[slack_bolt.adapter.socket_mode.websocket_client](https://github.com/slackapi/bolt-python/tree/main/slack_bolt/adapter/socket_mode/websocket_client)| | ||
|[aiohttp](https://pypi.org/project/aiohttp/) (asyncio-based)|[slack_bolt.adapter.socket_mode.aiohttp](https://github.com/slackapi/bolt-python/tree/main/slack_bolt/adapter/socket_mode/aiohttp)| | ||
|[websockets](https://pypi.org/project/websockets/) (asyncio-based)|[slack_bolt.adapter.socket_mode.websockets](https://github.com/slackapi/bolt-python/tree/main/slack_bolt/adapter/socket_mode/websockets)| | ||
|
||
</div> | ||
|
||
```python | ||
import os | ||
from slack_bolt import App | ||
from slack_bolt.adapter.socket_mode import SocketModeHandler | ||
|
||
# Install the Slack app and get xoxb- token in advance | ||
app = App(token=os.environ["SLACK_BOT_TOKEN"]) | ||
|
||
# Add middleware / listeners here | ||
|
||
if __name__ == "__main__": | ||
# export SLACK_APP_TOKEN=xapp-*** | ||
# export SLACK_BOT_TOKEN=xoxb-*** | ||
handler = SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]) | ||
handler.start() | ||
``` | ||
|
||
<details class="secondary-wrapper"> | ||
<summary markdown="0"> | ||
<h4 class="secondary-header">Using Async</h4> | ||
</summary> | ||
|
||
<div class="secondary-content" markdown="0"> | ||
To use the asyncio-based adapters such as aiohttp, your app needs to be compatible with asyncio's async/await programming model. `AsyncSocketModeHandler` is available for running `AsyncApp` and its async middleware and listeners. | ||
|
||
To learn how to use `AsyncApp`, checkout the [Using Async](https://slack.dev/bolt-python/concepts#async) document and relevant [examples](https://github.com/slackapi/bolt-python/tree/main/examples). | ||
</div> | ||
|
||
```python | ||
from slack_bolt.app.async_app import AsyncApp | ||
# The default is the aiohttp based implementation | ||
from slack_bolt.adapter.socket_mode.async_handler import AsyncSocketModeHandler | ||
|
||
app = AsyncApp(token=os.environ["SLACK_BOT_TOKEN"]) | ||
|
||
# Add middleware / listeners here | ||
|
||
async def main(): | ||
handler = AsyncSocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]) | ||
await handler.start_async() | ||
|
||
if __name__ == "__main__": | ||
import asyncio | ||
asyncio.run(main()) | ||
``` | ||
|
||
</details> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
# ------------------------------------------------ | ||
# instead of slack_bolt in requirements.txt | ||
import sys | ||
|
||
sys.path.insert(1, "..") | ||
# ------------------------------------------------ | ||
|
||
import logging | ||
|
||
logging.basicConfig(level=logging.DEBUG) | ||
|
||
import os | ||
|
||
from slack_bolt import App | ||
from slack_bolt.adapter.socket_mode import SocketModeHandler | ||
|
||
# Install the Slack app and get xoxb- token in advance | ||
app = App(token=os.environ["SLACK_BOT_TOKEN"]) | ||
|
||
|
||
@app.command("/hello-socket-mode") | ||
def hello_command(ack, body): | ||
user_id = body["user_id"] | ||
ack(f"Hi <@{user_id}>!") | ||
|
||
|
||
@app.event("app_mention") | ||
def event_test(event, say): | ||
say(f"Hi there, <@{event['user']}>!") | ||
|
||
|
||
def ack_shortcut(ack): | ||
ack() | ||
|
||
|
||
def open_modal(body, client): | ||
client.views_open( | ||
trigger_id=body["trigger_id"], | ||
view={ | ||
"type": "modal", | ||
"callback_id": "socket_modal_submission", | ||
"submit": {"type": "plain_text", "text": "Submit",}, | ||
"close": {"type": "plain_text", "text": "Cancel",}, | ||
"title": {"type": "plain_text", "text": "Socket Modal",}, | ||
"blocks": [ | ||
{ | ||
"type": "input", | ||
"block_id": "q1", | ||
"label": {"type": "plain_text", "text": "Write anything here!",}, | ||
"element": {"action_id": "feedback", "type": "plain_text_input",}, | ||
}, | ||
{ | ||
"type": "input", | ||
"block_id": "q2", | ||
"label": { | ||
"type": "plain_text", | ||
"text": "Can you tell us your favorites?", | ||
}, | ||
"element": { | ||
"type": "external_select", | ||
"action_id": "favorite-animal", | ||
"min_query_length": 0, | ||
"placeholder": { | ||
"type": "plain_text", | ||
"text": "Select your favorites", | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
) | ||
|
||
|
||
app.shortcut("socket-mode")(ack=ack_shortcut, lazy=[open_modal]) | ||
|
||
|
||
all_options = [ | ||
{"text": {"type": "plain_text", "text": ":cat: Cat"}, "value": "cat",}, | ||
{"text": {"type": "plain_text", "text": ":dog: Dog"}, "value": "dog",}, | ||
{"text": {"type": "plain_text", "text": ":bear: Bear"}, "value": "bear",}, | ||
] | ||
|
||
|
||
@app.options("favorite-animal") | ||
def external_data_source_handler(ack, body): | ||
keyword = body.get("value") | ||
if keyword is not None and len(keyword) > 0: | ||
options = [o for o in all_options if keyword in o["text"]["text"]] | ||
ack(options=options) | ||
else: | ||
ack(options=all_options) | ||
|
||
|
||
@app.view("socket_modal_submission") | ||
def submission(ack): | ||
ack() | ||
|
||
|
||
if __name__ == "__main__": | ||
# export SLACK_APP_TOKEN=xapp-*** | ||
# export SLACK_BOT_TOKEN=xoxb-*** | ||
SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]).start() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# ------------------------------------------------ | ||
# instead of slack_bolt in requirements.txt | ||
import sys | ||
|
||
|
||
sys.path.insert(1, "..") | ||
# ------------------------------------------------ | ||
|
||
import logging | ||
|
||
logging.basicConfig(level=logging.DEBUG) | ||
|
||
import os | ||
|
||
from slack_bolt.app.async_app import AsyncApp | ||
from slack_bolt.adapter.socket_mode.async_handler import AsyncSocketModeHandler | ||
|
||
# Install the Slack app and get xoxb- token in advance | ||
app = AsyncApp(token=os.environ["SLACK_BOT_TOKEN"]) | ||
|
||
|
||
@app.command("/hello-socket-mode") | ||
async def hello_command(ack, body): | ||
user_id = body["user_id"] | ||
await ack(f"Hi <@{user_id}>!") | ||
|
||
|
||
@app.event("app_mention") | ||
async def event_test(event, say): | ||
await say(f"Hi there, <@{event['user']}>!") | ||
|
||
|
||
async def ack_shortcut(ack): | ||
await ack() | ||
|
||
|
||
async def open_modal(body, client): | ||
await client.views_open( | ||
trigger_id=body["trigger_id"], | ||
view={ | ||
"type": "modal", | ||
"callback_id": "socket_modal_submission", | ||
"submit": {"type": "plain_text", "text": "Submit",}, | ||
"close": {"type": "plain_text", "text": "Cancel",}, | ||
"title": {"type": "plain_text", "text": "Socket Modal",}, | ||
"blocks": [ | ||
{ | ||
"type": "input", | ||
"block_id": "q1", | ||
"label": {"type": "plain_text", "text": "Write anything here!",}, | ||
"element": {"action_id": "feedback", "type": "plain_text_input",}, | ||
}, | ||
{ | ||
"type": "input", | ||
"block_id": "q2", | ||
"label": { | ||
"type": "plain_text", | ||
"text": "Can you tell us your favorites?", | ||
}, | ||
"element": { | ||
"type": "external_select", | ||
"action_id": "favorite-animal", | ||
"min_query_length": 0, | ||
"placeholder": { | ||
"type": "plain_text", | ||
"text": "Select your favorites", | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
) | ||
|
||
|
||
app.shortcut("socket-mode")(ack=ack_shortcut, lazy=[open_modal]) | ||
|
||
|
||
all_options = [ | ||
{"text": {"type": "plain_text", "text": ":cat: Cat"}, "value": "cat",}, | ||
{"text": {"type": "plain_text", "text": ":dog: Dog"}, "value": "dog",}, | ||
{"text": {"type": "plain_text", "text": ":bear: Bear"}, "value": "bear",}, | ||
] | ||
|
||
|
||
@app.options("favorite-animal") | ||
async def external_data_source_handler(ack, body): | ||
keyword = body.get("value") | ||
if keyword is not None and len(keyword) > 0: | ||
options = [o for o in all_options if keyword in o["text"]["text"]] | ||
await ack(options=options) | ||
else: | ||
await ack(options=all_options) | ||
|
||
|
||
@app.view("socket_modal_submission") | ||
async def submission(ack): | ||
await ack() | ||
|
||
|
||
# export SLACK_APP_TOKEN=xapp-*** | ||
# export SLACK_BOT_TOKEN=xoxb-*** | ||
|
||
|
||
async def main(): | ||
handler = AsyncSocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]) | ||
await handler.start_async() | ||
|
||
|
||
if __name__ == "__main__": | ||
import asyncio | ||
|
||
asyncio.run(main()) |
Oops, something went wrong.