From dbad795b52c137b49a70a2fde1a235e92dbcebba Mon Sep 17 00:00:00 2001 From: Kieran Wilkinson Date: Wed, 24 Dec 2025 11:04:39 +0000 Subject: [PATCH 1/3] update: add app command for test --- packages/slackBotFunction/app/slack/slack_handlers.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/slackBotFunction/app/slack/slack_handlers.py b/packages/slackBotFunction/app/slack/slack_handlers.py index 2100be2d..45b82d2b 100644 --- a/packages/slackBotFunction/app/slack/slack_handlers.py +++ b/packages/slackBotFunction/app/slack/slack_handlers.py @@ -41,6 +41,7 @@ def setup_handlers(app: App) -> None: app.event("message")(ack=respond_to_events, lazy=[unified_message_handler]) app.action("feedback_yes")(ack=respond_to_action, lazy=[feedback_handler]) app.action("feedback_no")(ack=respond_to_action, lazy=[feedback_handler]) + app.command("test")(ack=respond_to_command, lazy=[feedback_handler]) for i in range(1, 10): app.action(f"cite_{i}")(ack=respond_to_action, lazy=[feedback_handler]) @@ -64,6 +65,11 @@ def respond_to_action(ack: Ack): ack() +def respond_to_command(ack: Ack): + logger.debug("Sending ack response") + ack() + + def feedback_handler(body: Dict[str, Any], client: WebClient) -> None: """Handle feedback button clicks (both positive and negative).""" try: From 43cbf6367d14c7c6ee9993b4e9bbaf0b8c1d2327 Mon Sep 17 00:00:00 2001 From: Kieran Wilkinson Date: Wed, 24 Dec 2025 11:24:17 +0000 Subject: [PATCH 2/3] update: add app command for test --- packages/cdk/resources/Apis.ts | 11 +++++++++++ .../slackBotFunction/app/slack/slack_handlers.py | 13 ++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/cdk/resources/Apis.ts b/packages/cdk/resources/Apis.ts index 39702ddb..1ea5475d 100644 --- a/packages/cdk/resources/Apis.ts +++ b/packages/cdk/resources/Apis.ts @@ -37,6 +37,17 @@ export class Apis extends Construct { lambdaFunction: props.functions.slackBot }) + // Create the '/slack/commands' POST endpoint for Slack Events API + // This endpoint will handle slash commands, such as /test + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const slackCommandsEndpoint = new LambdaEndpoint(this, "SlackCommandsEndpoint", { + parentResource: slackResource, + resourceName: "commands", + method: HttpMethod.POST, + restApiGatewayRole: apiGateway.role, + lambdaFunction: props.functions.slackBot + }) + this.apis = { api: apiGateway } diff --git a/packages/slackBotFunction/app/slack/slack_handlers.py b/packages/slackBotFunction/app/slack/slack_handlers.py index 45b82d2b..e535ab75 100644 --- a/packages/slackBotFunction/app/slack/slack_handlers.py +++ b/packages/slackBotFunction/app/slack/slack_handlers.py @@ -41,7 +41,7 @@ def setup_handlers(app: App) -> None: app.event("message")(ack=respond_to_events, lazy=[unified_message_handler]) app.action("feedback_yes")(ack=respond_to_action, lazy=[feedback_handler]) app.action("feedback_no")(ack=respond_to_action, lazy=[feedback_handler]) - app.command("test")(ack=respond_to_command, lazy=[feedback_handler]) + app.command("test")(ack=respond_to_command, lazy=[prompt_test_handler]) for i in range(1, 10): app.action(f"cite_{i}")(ack=respond_to_action, lazy=[feedback_handler]) @@ -133,3 +133,14 @@ def unified_message_handler(client: WebClient, event: Dict[str, Any], body: Dict process_async_slack_event(event=event, event_id=event_id, client=client) except Exception: logger.error("Error triggering async processing", extra={"error": traceback.format_exc()}) + + +def prompt_test_handler(body: Dict[str, Any], event: Dict[str, Any], client: WebClient) -> None: + """Handle /test command to prompt the bot to respond.""" + try: + event_id = gate_common(event=event, body=body) + logger.debug("logging result of gate_common", extra={"event_id": event_id, "body": body}) + if not event_id: + return + except Exception as e: + logger.error(f"Error handling /test command: {e}", extra={"error": traceback.format_exc()}) From bba70d6129301f9dd7c2531dbde031fce97a9b0e Mon Sep 17 00:00:00 2001 From: Kieran Wilkinson Date: Wed, 24 Dec 2025 11:35:13 +0000 Subject: [PATCH 3/3] update: add app command for test --- packages/cdk/nagSuppressions.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/cdk/nagSuppressions.ts b/packages/cdk/nagSuppressions.ts index 9f3c61b1..d0f9220f 100644 --- a/packages/cdk/nagSuppressions.ts +++ b/packages/cdk/nagSuppressions.ts @@ -45,6 +45,22 @@ export const nagSuppressions = (stack: Stack) => { safeAddNagSuppression( stack, "/EpsAssistMeStack/Apis/EpsAssistApiGateway/ApiGateway/Default/slack/events/POST/Resource", + [ + { + id: "AwsSolutions-APIG4", + reason: "Slack event endpoint is intentionally unauthenticated." + }, + { + id: "AwsSolutions-COG4", + reason: "Cognito not required for this public endpoint." + } + ] + ) + + // Suppress unauthenticated API route warnings + safeAddNagSuppression( + stack, + "/EpsAssistMeStack/Apis/EpsAssistApiGateway/ApiGateway/Default/slack/commands/POST/Resource", [ { id: "AwsSolutions-APIG4",