diff --git a/slack_bolt/adapter/socket_mode/async_internals.py b/slack_bolt/adapter/socket_mode/async_internals.py index 00c33bf58..428ab437c 100644 --- a/slack_bolt/adapter/socket_mode/async_internals.py +++ b/slack_bolt/adapter/socket_mode/async_internals.py @@ -8,14 +8,14 @@ from slack_sdk.socket_mode.request import SocketModeRequest from slack_sdk.socket_mode.response import SocketModeResponse -from slack_bolt.adapter.socket_mode.internals import build_retry_headers +from slack_bolt.adapter.socket_mode.internals import build_headers from slack_bolt.app.async_app import AsyncApp from slack_bolt.request.async_request import AsyncBoltRequest from slack_bolt.response import BoltResponse async def run_async_bolt_app(app: AsyncApp, req: SocketModeRequest): - bolt_req: AsyncBoltRequest = AsyncBoltRequest(mode="socket_mode", body=req.payload, headers=build_retry_headers(req)) + bolt_req: AsyncBoltRequest = AsyncBoltRequest(mode="socket_mode", body=req.payload, headers=build_headers(req)) bolt_resp: BoltResponse = await app.async_dispatch(bolt_req) return bolt_resp diff --git a/slack_bolt/adapter/socket_mode/internals.py b/slack_bolt/adapter/socket_mode/internals.py index 9d6c3f898..6289f28f5 100644 --- a/slack_bolt/adapter/socket_mode/internals.py +++ b/slack_bolt/adapter/socket_mode/internals.py @@ -14,7 +14,7 @@ from slack_bolt.response import BoltResponse -def build_retry_headers(req: SocketModeRequest) -> Optional[Dict[str, Union[str, Sequence[str]]]]: +def build_headers(req: SocketModeRequest) -> Optional[Dict[str, Union[str, Sequence[str]]]]: # Mirror the HTTP mode retry headers so middleware/listeners can detect Events API retries headers: Dict[str, Union[str, Sequence[str]]] = {} if req.retry_attempt is not None: @@ -25,7 +25,7 @@ def build_retry_headers(req: SocketModeRequest) -> Optional[Dict[str, Union[str, def run_bolt_app(app: App, req: SocketModeRequest): - bolt_req: BoltRequest = BoltRequest(mode="socket_mode", body=req.payload, headers=build_retry_headers(req)) + bolt_req: BoltRequest = BoltRequest(mode="socket_mode", body=req.payload, headers=build_headers(req)) bolt_resp: BoltResponse = app.dispatch(bolt_req) return bolt_resp diff --git a/tests/adapter_tests/socket_mode/test_interactions_builtin.py b/tests/adapter_tests/socket_mode/test_interactions_builtin.py index 2ecd52554..aec04d938 100644 --- a/tests/adapter_tests/socket_mode/test_interactions_builtin.py +++ b/tests/adapter_tests/socket_mode/test_interactions_builtin.py @@ -36,7 +36,7 @@ def teardown_method(self): def test_interactions(self): app = App(client=self.web_client) - result = {"shortcut": False, "command": False} + result = {"shortcut": False, "command": False, "message": False} @app.shortcut("do-something") def shortcut_handler(ack): @@ -48,6 +48,13 @@ def command_handler(ack): result["command"] = True ack() + @app.message("<@W111>") + def message_handler(ack, req): + result["message"] = req.headers.get("x-slack-retry-num") == ["1"] and req.headers.get( + "x-slack-retry-reason" + ) == ["timeout"] + ack() + handler = SocketModeHandler( app_token="xapp-A111-222-xyz", app=app, @@ -66,5 +73,6 @@ def command_handler(ack): time.sleep(2) assert result["shortcut"] is True assert result["command"] is True + assert result["message"] is True finally: handler.client.close() diff --git a/tests/adapter_tests/socket_mode/test_interactions_websocket_client.py b/tests/adapter_tests/socket_mode/test_interactions_websocket_client.py index ccaa89d3e..90e027f9d 100644 --- a/tests/adapter_tests/socket_mode/test_interactions_websocket_client.py +++ b/tests/adapter_tests/socket_mode/test_interactions_websocket_client.py @@ -37,7 +37,7 @@ def test_interactions(self): app = App(client=self.web_client) - result = {"shortcut": False, "command": False} + result = {"shortcut": False, "command": False, "message": False} @app.shortcut("do-something") def shortcut_handler(ack): @@ -49,6 +49,13 @@ def command_handler(ack): result["command"] = True ack() + @app.message("<@W111>") + def message_handler(ack, req): + result["message"] = req.headers.get("x-slack-retry-num") == ["1"] and req.headers.get( + "x-slack-retry-reason" + ) == ["timeout"] + ack() + handler = SocketModeHandler( app_token="xapp-A111-222-xyz", app=app, @@ -67,5 +74,6 @@ def command_handler(ack): time.sleep(2) assert result["shortcut"] is True assert result["command"] is True + assert result["message"] is True finally: handler.client.close() diff --git a/tests/adapter_tests/socket_mode/test_internals.py b/tests/adapter_tests/socket_mode/test_internals.py index 2289196d4..fede30b48 100644 --- a/tests/adapter_tests/socket_mode/test_internals.py +++ b/tests/adapter_tests/socket_mode/test_internals.py @@ -1,12 +1,12 @@ from slack_sdk.socket_mode.request import SocketModeRequest -from slack_bolt.adapter.socket_mode.internals import build_retry_headers, run_bolt_app +from slack_bolt.adapter.socket_mode.internals import build_headers, run_bolt_app class TestSocketModeInternals: def test_build_retry_headers_without_retry(self): req = SocketModeRequest(type="events_api", envelope_id="e1", payload={"type": "event_callback"}) - assert build_retry_headers(req) is None + assert build_headers(req) is None def test_build_retry_headers_with_retry(self): req = SocketModeRequest( @@ -16,24 +16,5 @@ def test_build_retry_headers_with_retry(self): retry_attempt=2, retry_reason="http_timeout", ) - headers = build_retry_headers(req) + headers = build_headers(req) assert headers == {"x-slack-retry-num": "2", "x-slack-retry-reason": "http_timeout"} - - def test_run_bolt_app_propagates_retry_headers(self): - captured = {} - - class FakeApp: - def dispatch(self, bolt_req): - captured["headers"] = bolt_req.headers - return None - - req = SocketModeRequest( - type="events_api", - envelope_id="e1", - payload={"type": "event_callback", "event": {"type": "app_mention"}}, - retry_attempt=1, - retry_reason="http_timeout", - ) - run_bolt_app(FakeApp(), req) - assert captured["headers"]["x-slack-retry-num"] == ["1"] - assert captured["headers"]["x-slack-retry-reason"] == ["http_timeout"] diff --git a/tests/adapter_tests_async/socket_mode/test_async_aiohttp.py b/tests/adapter_tests_async/socket_mode/test_async_aiohttp.py index e8077f10c..812806a8c 100644 --- a/tests/adapter_tests_async/socket_mode/test_async_aiohttp.py +++ b/tests/adapter_tests_async/socket_mode/test_async_aiohttp.py @@ -40,7 +40,7 @@ async def test_events(self): app = AsyncApp(client=self.web_client) - result = {"shortcut": False, "command": False} + result = {"shortcut": False, "command": False, "message": False} @app.shortcut("do-something") async def shortcut_handler(ack): @@ -52,6 +52,13 @@ async def command_handler(ack): result["command"] = True await ack() + @app.message("<@W111>") + async def message_handler(ack, req): + result["message"] = req.headers.get("x-slack-retry-num") == ["1"] and req.headers.get( + "x-slack-retry-reason" + ) == ["timeout"] + await ack() + handler = AsyncSocketModeHandler( app_token="xapp-A111-222-xyz", app=app, @@ -67,6 +74,7 @@ async def command_handler(ack): await asyncio.sleep(2) assert result["shortcut"] is True assert result["command"] is True + assert result["message"] is True finally: await handler.client.close() stop_socket_mode_server(self) diff --git a/tests/adapter_tests_async/socket_mode/test_async_websockets.py b/tests/adapter_tests_async/socket_mode/test_async_websockets.py index 84d20b2f9..fc27150ee 100644 --- a/tests/adapter_tests_async/socket_mode/test_async_websockets.py +++ b/tests/adapter_tests_async/socket_mode/test_async_websockets.py @@ -40,7 +40,7 @@ async def test_events(self): app = AsyncApp(client=self.web_client) - result = {"shortcut": False, "command": False} + result = {"shortcut": False, "command": False, "message": False} @app.shortcut("do-something") async def shortcut_handler(ack): @@ -52,6 +52,13 @@ async def command_handler(ack): result["command"] = True await ack() + @app.message("<@W111>") + async def message_handler(ack, req): + result["message"] = req.headers.get("x-slack-retry-num") == ["1"] and req.headers.get( + "x-slack-retry-reason" + ) == ["timeout"] + await ack() + handler = AsyncSocketModeHandler( app_token="xapp-A111-222-xyz", app=app, @@ -67,6 +74,7 @@ async def command_handler(ack): await asyncio.sleep(2) assert result["shortcut"] is True assert result["command"] is True + assert result["message"] is True finally: await handler.client.close() stop_socket_mode_server(self)