Skip to content
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
2 changes: 2 additions & 0 deletions slack_bolt/request/async_internals.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from slack_bolt.context.async_context import AsyncBoltContext
from slack_bolt.request.internals import (
extract_enterprise_id,
extract_is_enterprise_install,
extract_team_id,
extract_user_id,
extract_channel_id,
Expand All @@ -14,6 +15,7 @@ def build_async_context(
context: AsyncBoltContext,
body: Dict[str, Any],
) -> AsyncBoltContext:
context["is_enterprise_install"] = extract_is_enterprise_install(body)
enterprise_id = extract_enterprise_id(body)
if enterprise_id:
context["enterprise_id"] = enterprise_id
Expand Down
4 changes: 4 additions & 0 deletions slack_bolt/request/internals.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ def parse_body(body: str, content_type: Optional[str]) -> Dict[str, Any]:


def extract_is_enterprise_install(payload: Dict[str, Any]) -> Optional[bool]:
if payload.get("authorizations") is not None and len(payload["authorizations"]) > 0:
# To make Events API handling functioning also for shared channels,
# we should use .authorizations[0].is_enterprise_install over .is_enterprise_install
return extract_is_enterprise_install(payload["authorizations"][0])
if "is_enterprise_install" in payload:
is_enterprise_install = payload.get("is_enterprise_install")
return is_enterprise_install is not None and (
Expand Down
49 changes: 48 additions & 1 deletion tests/scenario_tests/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from slack_sdk.signature import SignatureVerifier
from slack_sdk.web import WebClient

from slack_bolt import App, BoltRequest, Say
from slack_bolt import App, BoltRequest, Say, BoltContext
from tests.mock_web_api_server import (
setup_mock_web_api_server,
cleanup_mock_web_api_server,
Expand Down Expand Up @@ -541,3 +541,50 @@ def handle():
app.event({"type": "message.channels"})(handle)
with pytest.raises(ValueError):
app.event({"type": re.compile("message\\..*")})(handle)

def test_context_generation(self):
body = {
"token": "verification-token",
"enterprise_id": "E222", # intentionally inconsistent for testing
"team_id": "T222", # intentionally inconsistent for testing
"api_app_id": "A111",
"event": {
"type": "member_left_channel",
"user": "W111",
"channel": "C111",
"channel_type": "C",
"team": "T111",
},
"type": "event_callback",
"event_id": "Ev111",
"event_time": 1610493715,
"authorizations": [
{
"enterprise_id": "E333",
"user_id": "W222",
"is_bot": True,
"is_enterprise_install": True,
}
],
"is_ext_shared_channel": False,
"event_context": "1-message-T111-G111",
}
app = App(
client=self.web_client,
signing_secret=self.signing_secret,
process_before_response=True,
)

@app.event("member_left_channel")
def handle(context: BoltContext):
assert context.enterprise_id == "E333"
assert context.team_id is None
assert context.is_enterprise_install is True
assert context.user_id == "W111"

timestamp, json_body = str(int(time())), json.dumps(body)
request: BoltRequest = BoltRequest(
body=json_body, headers=self.build_headers(timestamp, json_body)
)
response = app.dispatch(request)
assert response.status == 200
49 changes: 49 additions & 0 deletions tests/scenario_tests_async/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from slack_sdk.web.async_client import AsyncWebClient

from slack_bolt.app.async_app import AsyncApp
from slack_bolt.context.async_context import AsyncBoltContext
from slack_bolt.context.say.async_say import AsyncSay
from slack_bolt.request.async_request import AsyncBoltRequest
from tests.mock_web_api_server import (
Expand Down Expand Up @@ -552,6 +553,54 @@ async def handle():
with pytest.raises(ValueError):
app.event({"type": re.compile("message\\..*")})(handle)

@pytest.mark.asyncio
async def test_context_generation(self):
body = {
"token": "verification-token",
"enterprise_id": "E222", # intentionally inconsistent for testing
"team_id": "T222", # intentionally inconsistent for testing
"api_app_id": "A111",
"event": {
"type": "member_left_channel",
"user": "W111",
"channel": "C111",
"channel_type": "C",
"team": "T111",
},
"type": "event_callback",
"event_id": "Ev111",
"event_time": 1610493715,
"authorizations": [
{
"enterprise_id": "E333",
"user_id": "W222",
"is_bot": True,
"is_enterprise_install": True,
}
],
"is_ext_shared_channel": False,
"event_context": "1-message-T111-G111",
}
app = AsyncApp(
client=self.web_client,
signing_secret=self.signing_secret,
process_before_response=True,
)

@app.event("member_left_channel")
async def handle(context: AsyncBoltContext):
assert context.enterprise_id == "E333"
assert context.team_id is None
assert context.is_enterprise_install is True
assert context.user_id == "W111"

timestamp, json_body = str(int(time())), json.dumps(body)
request: AsyncBoltRequest = AsyncBoltRequest(
body=json_body, headers=self.build_headers(timestamp, json_body)
)
response = await app.async_dispatch(request)
assert response.status == 200


app_mention_body = {
"token": "verification_token",
Expand Down