Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply internal adjustments for Socket Mode support #154

Merged
merged 1 commit into from
Nov 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions slack_bolt/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
from slack_bolt.listener_matcher.listener_matcher import ListenerMatcher
from slack_bolt.logger import get_bolt_app_logger, get_bolt_logger
from slack_bolt.logger.messages import (
error_signing_secret_not_found,
warning_client_prioritized_and_token_skipped,
warning_token_skipped,
error_auth_test_failure,
Expand Down Expand Up @@ -106,9 +105,6 @@ def __init__(
signing_secret = signing_secret or os.environ.get("SLACK_SIGNING_SECRET")
token = token or os.environ.get("SLACK_BOT_TOKEN")

if signing_secret is None or signing_secret == "":
raise BoltError(error_signing_secret_not_found())

self._name: str = name or inspect.stack()[1].filename.split(os.path.sep)[-1]
self._signing_secret: str = signing_secret

Expand Down
4 changes: 0 additions & 4 deletions slack_bolt/app/async_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
)
from slack_bolt.error import BoltError
from slack_bolt.logger.messages import (
error_signing_secret_not_found,
warning_client_prioritized_and_token_skipped,
warning_token_skipped,
error_token_required,
Expand Down Expand Up @@ -113,9 +112,6 @@ def __init__(
signing_secret = signing_secret or os.environ.get("SLACK_SIGNING_SECRET")
token = token or os.environ.get("SLACK_BOT_TOKEN")

if signing_secret is None or signing_secret == "":
raise BoltError(error_signing_secret_not_found())

self._name: str = name or inspect.stack()[1].filename.split(os.path.sep)[-1]
self._signing_secret: str = signing_secret
self._verification_token: Optional[str] = verification_token or os.environ.get(
Expand Down
8 changes: 0 additions & 8 deletions slack_bolt/logger/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@
# -------------------------------


def error_signing_secret_not_found() -> str:
return (
"Signing secret not found, so could not initialize the Bolt app."
"Copy your Signing Secret from the Basic Information page "
"and then store it in a new environment variable"
)


def error_client_invalid_type() -> str:
return "`client` must be a slack_sdk.web.WebClient"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ async def async_process(
resp: BoltResponse,
next: Callable[[], Awaitable[BoltResponse]],
) -> BoltResponse:
if self._can_skip(req.body):
if self._can_skip(req.mode, req.body):
return await next()

body = req.raw_body
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def __init__(self, signing_secret: str):
def process(
self, *, req: BoltRequest, resp: BoltResponse, next: Callable[[], BoltResponse],
) -> BoltResponse:
if self._can_skip(req.body):
if self._can_skip(req.mode, req.body):
return next()

body = req.raw_body
Expand All @@ -36,8 +36,10 @@ def process(
# -----------------------------------------

@staticmethod
def _can_skip(body: Dict[str, Any]) -> bool:
return body is not None and body.get("ssl_check") == "1"
def _can_skip(mode: str, body: Dict[str, Any]) -> bool:
return mode == "socket_mode" or (
body is not None and body.get("ssl_check") == "1"
)

@staticmethod
def _build_error_response() -> BoltResponse:
Expand Down
22 changes: 18 additions & 4 deletions slack_bolt/request/async_request.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from typing import Dict, Optional, Union, Any, Sequence

from slack_bolt.context.async_context import AsyncBoltContext
from slack_bolt.error import BoltError
from slack_bolt.request.async_internals import build_async_context
from slack_bolt.request.internals import (
parse_query,
parse_body,
build_normalized_headers,
extract_content_type,
error_message_raw_body_required_in_http_mode,
error_message_unknown_request_body_type,
)


Expand All @@ -19,31 +22,42 @@ class AsyncBoltRequest:
context: AsyncBoltContext
lazy_only: bool
lazy_function_name: Optional[str]
mode: str # either "http" or "socket_mode"

def __init__(
self,
*,
body: str,
body: Union[str, dict],
query: Optional[Union[str, Dict[str, str], Dict[str, Sequence[str]]]] = None,
headers: Optional[Dict[str, Union[str, Sequence[str]]]] = None,
context: Optional[Dict[str, str]] = None,
mode: str = "http", # either "http" or "socket_mode"
):
"""Request to a Bolt app.

:param body: The raw request body (only plain text is supported)
:param body: The raw request body (only plain text is supported for "http" mode)
:param query: The query string data in any data format.
:param headers: The request headers.
:param context: The context in this request.
:param mode: The mode used for this request. (either "http" or "socket_mode")
"""
self.raw_body = body
if mode == "http" and not isinstance(body, str):
raise BoltError(error_message_raw_body_required_in_http_mode())
self.raw_body = body if mode == "http" else ""
self.query = parse_query(query)
self.headers = build_normalized_headers(headers)
self.content_type = extract_content_type(self.headers)
self.body = parse_body(self.raw_body, self.content_type)
if isinstance(body, str):
self.body = parse_body(self.raw_body, self.content_type)
elif isinstance(body, dict):
self.body = body
else:
raise BoltError(error_message_unknown_request_body_type())
self.context = build_async_context(
AsyncBoltContext(context if context else {}), self.body
)
self.lazy_only = self.headers.get("x-slack-bolt-lazy-only", [False])[0]
self.lazy_function_name = self.headers.get(
"x-slack-bolt-lazy-function-name", [None]
)[0]
self.mode = mode
8 changes: 8 additions & 0 deletions slack_bolt/request/internals.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,11 @@ def build_normalized_headers(
f"Unsupported type ({type(value)}) of element in headers ({headers})"
)
return normalized_headers # type: ignore


def error_message_raw_body_required_in_http_mode() -> str:
return "`body` must be a raw string data when running in the HTTP server mode"


def error_message_unknown_request_body_type() -> str:
return "`body` must be either str or dict"
23 changes: 19 additions & 4 deletions slack_bolt/request/request.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from typing import Dict, Optional, Union, Any, Sequence

from slack_bolt.context.context import BoltContext
from slack_bolt.error import BoltError
from slack_bolt.request.internals import (
parse_query,
parse_body,
build_normalized_headers,
build_context,
extract_content_type,
error_message_raw_body_required_in_http_mode,
error_message_unknown_request_body_type,
)


Expand All @@ -19,29 +22,41 @@ class BoltRequest:
context: BoltContext
lazy_only: bool
lazy_function_name: Optional[str]
mode: str # either "http" or "socket_mode"

def __init__(
self,
*,
body: str,
body: Union[str, dict],
query: Optional[Union[str, Dict[str, str], Dict[str, Sequence[str]]]] = None,
headers: Optional[Dict[str, Union[str, Sequence[str]]]] = None,
context: Optional[Dict[str, str]] = None,
mode: str = "http", # either "http" or "socket_mode"
):
"""Request to a Bolt app.

:param body: The raw request body (only plain text is supported)
:param body: The raw request body (only plain text is supported for "http" mode)
:param query: The query string data in any data format.
:param headers: The request headers.
:param context: The context in this request.
:param mode: The mode used for this request. (either "http" or "socket_mode")
"""
self.raw_body = body
if mode == "http" and not isinstance(body, str):
raise BoltError(error_message_raw_body_required_in_http_mode())
self.raw_body = body if mode == "http" else ""
self.query = parse_query(query)
self.headers = build_normalized_headers(headers)
self.content_type = extract_content_type(self.headers)
self.body = parse_body(self.raw_body, self.content_type)
if isinstance(body, str):
self.body = parse_body(self.raw_body, self.content_type)
elif isinstance(body, dict):
self.body = body
else:
raise BoltError(error_message_unknown_request_body_type())

self.context = build_context(BoltContext(context if context else {}), self.body)
self.lazy_only = self.headers.get("x-slack-bolt-lazy-only", [False])[0]
self.lazy_function_name = self.headers.get(
"x-slack-bolt-lazy-function-name", [None]
)[0]
self.mode = mode
Loading