-
Notifications
You must be signed in to change notification settings - Fork 842
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Socket Mode implementation (aiohttp, websockets, websocket-client)
- Loading branch information
Showing
30 changed files
with
1,926 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# ------------------ | ||
# Only for running this script here | ||
import sys | ||
from os.path import dirname | ||
|
||
sys.path.insert(1, f"{dirname(__file__)}/../../..") | ||
# ------------------ | ||
|
||
import logging | ||
|
||
logging.basicConfig(level=logging.DEBUG) | ||
|
||
import asyncio | ||
import os | ||
from slack_sdk.web.async_client import AsyncWebClient | ||
from slack_sdk.socket_mode.response import SocketModeResponse | ||
from slack_sdk.socket_mode.request import SocketModeRequest | ||
from slack_sdk.socket_mode.aiohttp import SocketModeClient | ||
|
||
|
||
async def main(): | ||
|
||
client = SocketModeClient( | ||
app_token=os.environ.get("SLACK_SDK_TEST_SOCKET_MODE_APP_TOKEN"), | ||
web_client=AsyncWebClient( | ||
token=os.environ.get("SLACK_SDK_TEST_SOCKET_MODE_BOT_TOKEN") | ||
), | ||
) | ||
|
||
async def process(client: SocketModeClient, req: SocketModeRequest): | ||
if req.type == "events_api": | ||
response = SocketModeResponse(envelope_id=req.envelope_id) | ||
await client.send_socket_mode_response(response) | ||
|
||
await client.web_client.reactions_add( | ||
name="eyes", | ||
channel=req.payload["event"]["channel"], | ||
timestamp=req.payload["event"]["ts"], | ||
) | ||
|
||
client.socket_mode_request_listeners.append(process) | ||
await client.connect() | ||
await asyncio.sleep(float("inf")) | ||
|
||
|
||
asyncio.run(main()) |
82 changes: 82 additions & 0 deletions
82
integration_tests/samples/socket_mode/bolt_adapter/aiohttp.py
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,82 @@ | ||
# ------------------ | ||
# Only for running this script here | ||
import sys | ||
from os.path import dirname | ||
|
||
sys.path.insert(1, f"{dirname(__file__)}/../../../..") | ||
# ------------------ | ||
|
||
import logging | ||
import os | ||
import asyncio | ||
from typing import Optional | ||
from time import time | ||
from slack_sdk.socket_mode.response import SocketModeResponse | ||
from slack_sdk.socket_mode.request import SocketModeRequest | ||
from slack_sdk.socket_mode.aiohttp import SocketModeClient | ||
|
||
from slack_bolt import App | ||
from slack_bolt.request import BoltRequest | ||
from slack_bolt.response import BoltResponse | ||
|
||
|
||
class SocketModeAdapter: | ||
app: App | ||
|
||
def __init__(self, app: App): | ||
self.app = app | ||
|
||
async def listener(self, client: SocketModeClient, req: SocketModeRequest): | ||
start = time() | ||
bolt_req: BoltRequest = BoltRequest(mode="socket_mode", body=req.payload) | ||
bolt_resp: BoltResponse = self.app.dispatch(bolt_req) | ||
if bolt_resp.status == 200: | ||
if bolt_resp.body is None or len(bolt_resp.body) == 0: | ||
await client.send_socket_mode_response( | ||
SocketModeResponse(envelope_id=req.envelope_id) | ||
) | ||
elif bolt_resp.body.startswith("{"): | ||
await client.send_socket_mode_response( | ||
SocketModeResponse( | ||
envelope_id=req.envelope_id, payload=bolt_resp.body, | ||
) | ||
) | ||
if client.logger.level <= logging.DEBUG: | ||
spent_time = int((time() - start) * 1000) | ||
client.logger.debug(f"Response time: {spent_time} milliseconds") | ||
else: | ||
client.logger.info( | ||
f"Unsuccessful Bolt execution result (status: {bolt_resp.status}, body: {bolt_resp.body})" | ||
) | ||
|
||
|
||
class SocketModeApp: | ||
app: App | ||
app_token: str | ||
client: SocketModeClient | ||
|
||
def __init__( | ||
self, app: App, app_token: Optional[str] = None, | ||
): | ||
self.app = app | ||
self.app_token = app_token or os.environ["SLACK_APP_TOKEN"] | ||
self.client = SocketModeClient(app_token=self.app_token) | ||
listener = SocketModeAdapter(self.app).listener | ||
self.client.socket_mode_request_listeners.append(listener) | ||
|
||
async def connect_async(self): | ||
await self.client.connect() | ||
|
||
async def disconnect_async(self): | ||
await self.client.disconnect() | ||
|
||
async def close_async(self): | ||
await self.client.close() | ||
|
||
async def start_async(self): | ||
await self.connect_async() | ||
if self.app.logger.level > logging.INFO: | ||
print("⚡️ Bolt app is running!") | ||
else: | ||
self.app.logger.info("⚡️ Bolt app is running!") | ||
await asyncio.sleep(float("inf")) |
82 changes: 82 additions & 0 deletions
82
integration_tests/samples/socket_mode/bolt_adapter/aiohttp_async.py
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,82 @@ | ||
# ------------------ | ||
# Only for running this script here | ||
import sys | ||
from os.path import dirname | ||
|
||
sys.path.insert(1, f"{dirname(__file__)}/../../../..") | ||
# ------------------ | ||
|
||
import asyncio | ||
import logging | ||
import os | ||
from typing import Optional | ||
from time import time | ||
from slack_sdk.socket_mode.response import SocketModeResponse | ||
from slack_sdk.socket_mode.request import SocketModeRequest | ||
from slack_sdk.socket_mode.aiohttp import SocketModeClient | ||
|
||
from slack_bolt.app.async_app import AsyncApp | ||
from slack_bolt.request.async_request import AsyncBoltRequest | ||
from slack_bolt.response import BoltResponse | ||
|
||
|
||
class AsyncSocketModeAdapter: | ||
app: AsyncApp | ||
|
||
def __init__(self, app: AsyncApp): | ||
self.app = app | ||
|
||
async def listener(self, client: SocketModeClient, req: SocketModeRequest): | ||
start = time() | ||
bolt_req: AsyncBoltRequest = AsyncBoltRequest(mode="socket_mode", body=req.payload) | ||
bolt_resp: BoltResponse = await self.app.async_dispatch(bolt_req) | ||
if bolt_resp.status == 200: | ||
if bolt_resp.body is None or len(bolt_resp.body) == 0: | ||
await client.send_socket_mode_response( | ||
SocketModeResponse(envelope_id=req.envelope_id) | ||
) | ||
elif bolt_resp.body.startswith("{"): | ||
await client.send_socket_mode_response( | ||
SocketModeResponse( | ||
envelope_id=req.envelope_id, payload=bolt_resp.body, | ||
) | ||
) | ||
if client.logger.level <= logging.DEBUG: | ||
spent_time = int((time() - start) * 1000) | ||
client.logger.debug(f"Response time: {spent_time} milliseconds") | ||
else: | ||
client.logger.info( | ||
f"Unsuccessful Bolt execution result (status: {bolt_resp.status}, body: {bolt_resp.body})" | ||
) | ||
|
||
|
||
class AsyncSocketModeApp: | ||
app: AsyncApp | ||
app_token: str | ||
client: SocketModeClient | ||
|
||
def __init__( | ||
self, app: AsyncApp, app_token: Optional[str] = None, | ||
): | ||
self.app = app | ||
self.app_token = app_token or os.environ["SLACK_APP_TOKEN"] | ||
self.client = SocketModeClient(app_token=self.app_token) | ||
listener = AsyncSocketModeAdapter(self.app).listener | ||
self.client.socket_mode_request_listeners.append(listener) | ||
|
||
async def connect_async(self): | ||
await self.client.connect() | ||
|
||
async def disconnect_async(self): | ||
await self.client.disconnect() | ||
|
||
async def close_async(self): | ||
await self.client.close() | ||
|
||
async def start_async(self): | ||
await self.connect_async() | ||
if self.app.logger.level > logging.INFO: | ||
print("⚡️ Bolt app is running!") | ||
else: | ||
self.app.logger.info("⚡️ Bolt app is running!") | ||
await asyncio.sleep(float("inf")) |
82 changes: 82 additions & 0 deletions
82
integration_tests/samples/socket_mode/bolt_adapter/websocket_client.py
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,82 @@ | ||
# ------------------ | ||
# Only for running this script here | ||
import sys | ||
from os.path import dirname | ||
|
||
sys.path.insert(1, f"{dirname(__file__)}/../../../..") | ||
# ------------------ | ||
|
||
import logging | ||
import os | ||
from threading import Event | ||
from typing import Optional | ||
from time import time | ||
from slack_sdk.socket_mode.response import SocketModeResponse | ||
from slack_sdk.socket_mode.request import SocketModeRequest | ||
from slack_sdk.socket_mode.websocket_client import SocketModeClient | ||
|
||
from slack_bolt.app import App | ||
from slack_bolt.request import BoltRequest | ||
from slack_bolt.response import BoltResponse | ||
|
||
|
||
class SocketModeAdapter: | ||
app: App | ||
|
||
def __init__(self, app: App): | ||
self.app = app | ||
|
||
def listener(self, client: SocketModeClient, req: SocketModeRequest): | ||
start = time() | ||
bolt_req: BoltRequest = BoltRequest(mode="socket_mode", body=req.payload) | ||
bolt_resp: BoltResponse = self.app.dispatch(bolt_req) | ||
if bolt_resp.status == 200: | ||
if bolt_resp.body is None or len(bolt_resp.body) == 0: | ||
client.send_socket_mode_response( | ||
SocketModeResponse(envelope_id=req.envelope_id) | ||
) | ||
elif bolt_resp.body.startswith("{"): | ||
client.send_socket_mode_response( | ||
SocketModeResponse( | ||
envelope_id=req.envelope_id, payload=bolt_resp.body, | ||
) | ||
) | ||
if client.logger.level <= logging.DEBUG: | ||
spent_time = int((time() - start) * 1000) | ||
client.logger.debug(f"Response time: {spent_time} milliseconds") | ||
else: | ||
client.logger.info( | ||
f"Unsuccessful Bolt execution result (status: {bolt_resp.status}, body: {bolt_resp.body})" | ||
) | ||
|
||
|
||
class SocketModeApp: | ||
app: App | ||
app_token: str | ||
client: SocketModeClient | ||
|
||
def __init__( | ||
self, app: App, app_token: Optional[str] = None, | ||
): | ||
self.app = app | ||
self.app_token = app_token or os.environ["SLACK_APP_TOKEN"] | ||
self.client = SocketModeClient(app_token=self.app_token) | ||
listener = SocketModeAdapter(self.app).listener | ||
self.client.socket_mode_request_listeners.append(listener) | ||
|
||
def connect(self): | ||
self.client.connect() | ||
|
||
def disconnect(self): | ||
self.client.disconnect() | ||
|
||
def close(self): | ||
self.client.close() | ||
|
||
def start(self): | ||
self.connect() | ||
if self.app.logger.level > logging.INFO: | ||
print("⚡️ Bolt app is running!") | ||
else: | ||
self.app.logger.info("⚡️ Bolt app is running!") | ||
Event().wait() |
82 changes: 82 additions & 0 deletions
82
integration_tests/samples/socket_mode/bolt_adapter/websockets.py
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,82 @@ | ||
# ------------------ | ||
# Only for running this script here | ||
import sys | ||
from os.path import dirname | ||
|
||
sys.path.insert(1, f"{dirname(__file__)}/../../../..") | ||
# ------------------ | ||
|
||
import logging | ||
import os | ||
import asyncio | ||
from typing import Optional | ||
from time import time | ||
from slack_sdk.socket_mode.response import SocketModeResponse | ||
from slack_sdk.socket_mode.request import SocketModeRequest | ||
from slack_sdk.socket_mode.websockets import SocketModeClient | ||
|
||
from slack_bolt import App | ||
from slack_bolt.request import BoltRequest | ||
from slack_bolt.response import BoltResponse | ||
|
||
|
||
class SocketModeAdapter: | ||
app: App | ||
|
||
def __init__(self, app: App): | ||
self.app = app | ||
|
||
async def listener(self, client: SocketModeClient, req: SocketModeRequest): | ||
start = time() | ||
bolt_req: BoltRequest = BoltRequest(mode="socket_mode", body=req.payload) | ||
bolt_resp: BoltResponse = self.app.dispatch(bolt_req) | ||
if bolt_resp.status == 200: | ||
if bolt_resp.body is None or len(bolt_resp.body) == 0: | ||
await client.send_socket_mode_response( | ||
SocketModeResponse(envelope_id=req.envelope_id) | ||
) | ||
elif bolt_resp.body.startswith("{"): | ||
await client.send_socket_mode_response( | ||
SocketModeResponse( | ||
envelope_id=req.envelope_id, payload=bolt_resp.body, | ||
) | ||
) | ||
if client.logger.level <= logging.DEBUG: | ||
spent_time = int((time() - start) * 1000) | ||
client.logger.debug(f"Response time: {spent_time} milliseconds") | ||
else: | ||
client.logger.info( | ||
f"Unsuccessful Bolt execution result (status: {bolt_resp.status}, body: {bolt_resp.body})" | ||
) | ||
|
||
|
||
class SocketModeApp: | ||
app: App | ||
app_token: str | ||
client: SocketModeClient | ||
|
||
def __init__( | ||
self, app: App, app_token: Optional[str] = None, | ||
): | ||
self.app = app | ||
self.app_token = app_token or os.environ["SLACK_APP_TOKEN"] | ||
self.client = SocketModeClient(app_token=self.app_token) | ||
listener = SocketModeAdapter(self.app).listener | ||
self.client.socket_mode_request_listeners.append(listener) | ||
|
||
async def connect_async(self): | ||
await self.client.connect() | ||
|
||
async def disconnect_async(self): | ||
await self.client.disconnect() | ||
|
||
async def close_async(self): | ||
await self.client.close() | ||
|
||
async def start_async(self): | ||
await self.connect_async() | ||
if self.app.logger.level > logging.INFO: | ||
print("⚡️ Bolt app is running!") | ||
else: | ||
self.app.logger.info("⚡️ Bolt app is running!") | ||
await asyncio.sleep(float("inf")) |
Oops, something went wrong.