Skip to content

Commit 9bcac78

Browse files
committed
wip to forward event
1 parent 52534e4 commit 9bcac78

File tree

2 files changed

+65
-10
lines changed

2 files changed

+65
-10
lines changed

packages/slackBotFunction/app/slack/slack_handlers.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import traceback
1313
from typing import Any, Dict
1414
from botocore.exceptions import ClientError
15-
from slack_bolt import Ack, App
15+
from slack_bolt import Ack, App, BoltRequest
1616
from slack_sdk import WebClient
1717
from app.core.config import (
1818
bot_messages,
@@ -26,6 +26,7 @@
2626
extract_conversation_context,
2727
extract_pull_request_id,
2828
extract_session_pull_request_id,
29+
forward_event_to_pull_request_lambda,
2930
gate_common,
3031
is_latest_message,
3132
strip_mentions,
@@ -68,7 +69,7 @@ def respond_to_action(ack: Ack):
6869
ack()
6970

7071

71-
def mention_handler(event: Dict[str, Any], body: Dict[str, Any], client: WebClient) -> None:
72+
def mention_handler(event: Dict[str, Any], body: Dict[str, Any], client: WebClient, req: BoltRequest) -> None:
7273
"""
7374
Channel interactions that mention the bot.
7475
Pulls some details unique to mentions and removes slack user name
@@ -91,10 +92,11 @@ def mention_handler(event: Dict[str, Any], body: Dict[str, Any], client: WebClie
9192
event=event,
9293
event_id=event_id,
9394
post_to_thread=True,
95+
req=req,
9496
)
9597

9698

97-
def dm_message_handler(event: Dict[str, Any], event_id: str, client: WebClient) -> None:
99+
def dm_message_handler(event: Dict[str, Any], event_id: str, client: WebClient, req: BoltRequest) -> None:
98100
"""
99101
Direct messages:
100102
Pulls some details unique to direct messages
@@ -105,7 +107,10 @@ def dm_message_handler(event: Dict[str, Any], event_id: str, client: WebClient)
105107
message_text = (event.get("text") or "").strip()
106108
user_id = event.get("user", "unknown")
107109
conversation_key, thread_root = conversation_key_and_root(event=event)
108-
logger.info(f"Processing DM from user {user_id}", extra={"event_id": event_id})
110+
logger.info(
111+
f"Processing DM from user {user_id}",
112+
extra={"event_id": event_id, "conversation_key": conversation_key, "thread_root": thread_root},
113+
)
109114
_common_message_handler(
110115
message_text=message_text,
111116
conversation_key=conversation_key,
@@ -114,10 +119,11 @@ def dm_message_handler(event: Dict[str, Any], event_id: str, client: WebClient)
114119
event=event,
115120
event_id=event_id,
116121
post_to_thread=True,
122+
req=req,
117123
)
118124

119125

120-
def thread_message_handler(event: Dict[str, Any], event_id: str, client: WebClient) -> None:
126+
def thread_message_handler(event: Dict[str, Any], event_id: str, client: WebClient, req: BoltRequest) -> None:
121127
"""
122128
Thread messages:
123129
Pulls some details unique to threads
@@ -155,10 +161,11 @@ def thread_message_handler(event: Dict[str, Any], event_id: str, client: WebClie
155161
event=event,
156162
event_id=event_id,
157163
post_to_thread=True,
164+
req=req,
158165
)
159166

160167

161-
def unified_message_handler(event: Dict[str, Any], body: Dict[str, Any], client: WebClient) -> None:
168+
def unified_message_handler(event: Dict[str, Any], body: Dict[str, Any], client: WebClient, req: BoltRequest) -> None:
162169
"""Handle message events (but not app mentions) - DMs and channel messages"""
163170
event_id = gate_common(event=event, body=body)
164171
if not event_id:
@@ -167,13 +174,13 @@ def unified_message_handler(event: Dict[str, Any], body: Dict[str, Any], client:
167174
# Route to appropriate handler based on message type
168175
if event.get("channel_type") == constants.CHANNEL_TYPE_IM:
169176
# DM handling
170-
dm_message_handler(event=event, event_id=event_id, client=client)
177+
dm_message_handler(event=event, event_id=event_id, client=client, req=req)
171178
else:
172179
# Channel message handling
173-
thread_message_handler(event=event, event_id=event_id, client=client)
180+
thread_message_handler(event=event, event_id=event_id, client=client, req=req)
174181

175182

176-
def feedback_handler(body: Dict[str, Any], client: WebClient) -> None:
183+
def feedback_handler(body: Dict[str, Any], client: WebClient, req: BoltRequest) -> None:
177184
"""Handle feedback button clicks (both positive and negative)."""
178185
try:
179186
channel_id = body["channel"]["id"]
@@ -189,6 +196,10 @@ def feedback_handler(body: Dict[str, Any], client: WebClient) -> None:
189196
f"Feedback in pull request session {session_pull_request_id}",
190197
extra={"session_pull_request_id": session_pull_request_id},
191198
)
199+
forward_event_to_pull_request_lambda(
200+
req=req, pull_request_id=session_pull_request_id, forward_type="feedback"
201+
)
202+
return
192203

193204
if message_ts and not is_latest_message(conversation_key=conversation_key, message_ts=message_ts):
194205
logger.info(f"Feedback ignored - not latest message: {message_ts}")
@@ -247,6 +258,7 @@ def _common_message_handler(
247258
event: Dict[str, Any],
248259
event_id: str,
249260
post_to_thread: bool,
261+
req: BoltRequest,
250262
) -> None:
251263
"""
252264
All messages get processed by this code
@@ -264,6 +276,8 @@ def _common_message_handler(
264276
f"Message in pull request session {session_pull_request_id} from user {user_id}",
265277
extra={"session_pull_request_id": session_pull_request_id},
266278
)
279+
forward_event_to_pull_request_lambda(req=req, pull_request_id=session_pull_request_id, forward_type="event")
280+
return
267281
if message_text.lower().startswith(constants.FEEDBACK_PREFIX):
268282
feedback_text = message_text.split(":", 1)[1].strip() if ":" in message_text else ""
269283
try:

packages/slackBotFunction/app/utils/handler_utils.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
import json
88
import traceback
99
from typing import Any, Dict, Tuple
10+
import urllib.parse
1011
import boto3
1112
from botocore.exceptions import ClientError
13+
from slack_bolt import BoltRequest
1214
from slack_sdk import WebClient
1315
from mypy_boto3_cloudformation.client import CloudFormationClient
1416
from mypy_boto3_lambda.client import LambdaClient
@@ -78,6 +80,43 @@ def trigger_pull_request_processing(pull_request_id: str, event: Dict[str, Any],
7880
raise e
7981

8082

83+
def forward_event_to_pull_request_lambda(req: BoltRequest, pull_request_id: str, forward_type: str) -> None:
84+
cloudformation_client: CloudFormationClient = boto3.client("cloudformation")
85+
lambda_client: LambdaClient = boto3.client("lambda")
86+
try:
87+
logger.debug("Getting arn for pull request", extra={"pull_request_id": pull_request_id})
88+
response = cloudformation_client.describe_stacks(StackName=f"epsam-pr-{pull_request_id}")
89+
outputs = {o["OutputKey"]: o["OutputValue"] for o in response["Stacks"][0]["Outputs"]}
90+
91+
pull_request_lambda_arn = outputs.get("SlackBotLambdaArn")
92+
if forward_type == "feedback":
93+
forwarded_body = f"payload={urllib.parse.quote_plus(json.dumps(req.body, separators=(',', ':')))}"
94+
else:
95+
forwarded_body = json.dumps(req.body)
96+
forward_req = {
97+
"body": forwarded_body,
98+
"headers": req.headers,
99+
"httpMethod": "POST",
100+
"isBase64Encoded": False,
101+
"method": "NONE",
102+
"path": "/slack/events",
103+
"resource": "/slack/events",
104+
"stageVariables": None,
105+
}
106+
logger.debug(
107+
"Forwarding request to pull request lambda",
108+
extra={"lambda_arn": pull_request_lambda_arn, "forward_req": forward_req},
109+
)
110+
response = lambda_client.invoke(
111+
FunctionName=pull_request_lambda_arn, InvocationType="Event", Payload=json.dumps(forward_req)
112+
)
113+
logger.info("Triggered pull request lambda", extra={"lambda_arn": pull_request_lambda_arn})
114+
115+
except Exception as e:
116+
logger.error("Failed to forward request to pull request lambda", extra={"error": traceback.format_exc()})
117+
raise e
118+
119+
81120
def is_latest_message(conversation_key: str, message_ts: str) -> bool:
82121
"""Check if message_ts is the latest bot message using session data"""
83122
try:
@@ -147,7 +186,7 @@ def conversation_key_and_root(event: Dict[str, Any]) -> Tuple[str, str]:
147186
channel_id = event["channel"]
148187
root = event.get("thread_ts") or event.get("ts")
149188
if event.get("channel_type") == constants.CHANNEL_TYPE_IM:
150-
return f"{constants.DM_PREFIX}{channel_id}", root
189+
return f"{constants.DM_PREFIX}{channel_id}#{root}", root
151190
return f"{constants.THREAD_PREFIX}{channel_id}#{root}", root
152191

153192

@@ -165,10 +204,12 @@ def extract_conversation_context(event: Dict[str, Any]) -> Tuple[str, str, str |
165204

166205
def extract_session_pull_request_id(conversation_key: str) -> str | None:
167206
"""Check if the conversation is associated with a pull request"""
207+
logger.debug("Checking for existing pull request session", extra={"conversation_key": conversation_key})
168208
try:
169209
response = get_state_information({"pk": conversation_key, "sk": constants.PULL_REQUEST_SK})
170210
if "Item" in response:
171211
logger.info("Found existing pull request session", extra={"conversation_key": conversation_key})
212+
logger.debug("response", extra={"response": response})
172213
return response["Item"]["pull_request_id"]
173214
return None
174215
except Exception as e:

0 commit comments

Comments
 (0)