Skip to content

Commit 8b8c085

Browse files
committed
Use aws_lambda_powertools for logging and SSM parameter retrieval in slackBotFunction Lambda
1 parent 2926083 commit 8b8c085

File tree

1 file changed

+32
-73
lines changed
  • packages/slackBotFunction

1 file changed

+32
-73
lines changed

packages/slackBotFunction/app.py

Lines changed: 32 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,26 @@
1-
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2-
# SPDX-License-Identifier: MIT-0.
3-
4-
"""
5-
AWS Lambda hosted Slack ChatBot integration to Amazon Bedrock Knowledge Base.
6-
Expects Slack Bot Slash Command given by the SLACK_SLASH_COMMAND param and presents
7-
a user query to the Bedrock Knowledge Base described by the KNOWLEDGEBASE_ID parameter.
8-
9-
The user query is used in a Bedrock KB ReteriveandGenerate API call and the KB
10-
response is presented to the user in Slack.
11-
12-
Slack integration based on SlackBolt library and examples given at:
13-
https://github.com/slackapi/bolt-python/blob/main/examples/aws_lambda/lazy_aws_lambda.py
14-
"""
15-
16-
__version__ = "0.0.1"
17-
__status__ = "Development"
18-
__copyright__ = "Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved."
19-
__author__ = "Dean Colcott <https://www.linkedin.com/in/deancolcott/>"
20-
211
import os
222
import json
233
import boto3
24-
import logging
254
from slack_bolt import App
265
from slack_bolt.adapter.aws_lambda import SlackRequestHandler
6+
from aws_lambda_powertools import Logger
7+
from aws_lambda_powertools.utilities.parameters import get_parameter
8+
from aws_lambda_powertools.utilities.typing import LambdaContext
279

28-
29-
# Get params from SSM
30-
def get_parameter(parameter_name):
31-
ssm = boto3.client("ssm")
32-
try:
33-
response = ssm.get_parameter(Name=parameter_name, WithDecryption=True)
34-
# Parse the JSON string from the parameter
35-
parameter_value = response["Parameter"]["Value"]
36-
37-
# Remove the JSON structure and extract just the value
38-
try:
39-
json_value = json.loads(parameter_value)
40-
# Get the first value from the dictionary
41-
value = next(iter(json_value.values()))
42-
return value
43-
except (json.JSONDecodeError, StopIteration):
44-
# If parsing fails or dictionary is empty, return the raw value
45-
return parameter_value
46-
47-
except Exception as e:
48-
print(f"Error getting parameter {parameter_name}: {str(e)}")
49-
raise e
50-
10+
# Initialize Powertools Logger
11+
logger = Logger()
5112

5213
# Get parameter names from environment variables
5314
bot_token_parameter = os.environ["SLACK_BOT_TOKEN_PARAMETER"]
5415
signing_secret_parameter = os.environ["SLACK_SIGNING_SECRET_PARAMETER"]
5516

56-
# Retrieve the parameters from SSM Parameter Store
57-
bot_token = get_parameter(bot_token_parameter)
58-
signing_secret = get_parameter(signing_secret_parameter)
17+
# Retrieve and parse parameters from SSM Parameter Store
18+
bot_token_raw = get_parameter(bot_token_parameter, decrypt=True)
19+
signing_secret_raw = get_parameter(signing_secret_parameter, decrypt=True)
20+
21+
# Parse JSON values and extract tokens
22+
bot_token = json.loads(bot_token_raw)["token"]
23+
signing_secret = json.loads(signing_secret_raw)["secret"]
5924

6025
# Initialize Slack app
6126
app = App(
@@ -72,16 +37,15 @@ def get_parameter(parameter_name):
7237
GUARD_RAIL_ID = os.environ["GUARD_RAIL_ID"]
7338
GUARD_VERSION = os.environ["GUARD_RAIL_VERSION"]
7439

75-
print(f"GR_ID,{GUARD_RAIL_ID}")
76-
print(f"GR_V, {GUARD_VERSION}")
40+
logger.info(f"Guardrail ID: {GUARD_RAIL_ID}, Version: {GUARD_VERSION}")
7741

7842

7943
@app.middleware
80-
def log_request(logger, body, next):
44+
def log_request(_, body, next):
8145
"""
8246
SlackBolt library logging.
8347
"""
84-
logger.debug(body)
48+
logger.debug("Slack request received", extra={"body": body})
8549
return next()
8650

8751

@@ -97,16 +61,15 @@ def respond_to_slack_within_3_seconds(body, ack):
9761
"""
9862
try:
9963
user_query = body["text"]
100-
logging.info(
101-
f"${SLACK_SLASH_COMMAND} - Acknowledging command: {SLACK_SLASH_COMMAND} - User Query: {user_query}\n"
64+
logger.info(
65+
f"Acknowledging command: {SLACK_SLASH_COMMAND}",
66+
extra={"user_query": user_query},
10267
)
103-
ack(f"\n${SLACK_SLASH_COMMAND} - Processing Request: {user_query}")
68+
ack(f"\n{SLACK_SLASH_COMMAND} - Processing Request: {user_query}")
10469

10570
except Exception as err:
106-
print(f"${SLACK_SLASH_COMMAND} - Error: {err}")
107-
respond(
108-
f"${SLACK_SLASH_COMMAND} - Sorry an error occurred. Please try again later. Error: {err}"
109-
)
71+
logger.error(f"Error acknowledging command: {err}")
72+
ack(f"{SLACK_SLASH_COMMAND} - Sorry an error occurred. Please try again later.")
11073

11174

11275
def process_command_request(respond, body):
@@ -115,21 +78,19 @@ def process_command_request(respond, body):
11578
and return the response to Slack to be presented in the users chat thread.
11679
"""
11780
try:
118-
# Get the user query
11981
user_query = body["text"]
120-
logging.info(
121-
f"${SLACK_SLASH_COMMAND} - Responding to command: {SLACK_SLASH_COMMAND} - User Query: {user_query}"
82+
logger.info(
83+
f"Processing command: {SLACK_SLASH_COMMAND}",
84+
extra={"user_query": user_query},
12285
)
12386

12487
kb_response = get_bedrock_knowledgebase_response(user_query)
12588
response_text = kb_response["output"]["text"]
126-
respond(f"\n${SLACK_SLASH_COMMAND} - Response: {response_text}\n")
89+
respond(f"\n{SLACK_SLASH_COMMAND} - Response: {response_text}\n")
12790

12891
except Exception as err:
129-
print(f"${SLACK_SLASH_COMMAND} - Error: {err}")
130-
respond(
131-
f"${SLACK_SLASH_COMMAND} - Sorry an error occurred. Please try again later. Error: {err}"
132-
)
92+
logger.error(f"Error processing command: {err}")
93+
respond(f"{SLACK_SLASH_COMMAND} - Sorry an error occurred. Please try again later.")
13394

13495

13596
def get_bedrock_knowledgebase_response(user_query):
@@ -164,10 +125,8 @@ def get_bedrock_knowledgebase_response(user_query):
164125
},
165126
}
166127

167-
response = client.retrieve_and_generate(
168-
input=query_input, retrieveAndGenerateConfiguration=config
169-
)
170-
logging.info(f"Bedrock Knowledge Base Response: {response}")
128+
response = client.retrieve_and_generate(input=query_input, retrieveAndGenerateConfiguration=config)
129+
logger.info("Bedrock Knowledge Base Response received", extra={"response": response})
171130
return response
172131

173132

@@ -179,11 +138,11 @@ def get_bedrock_knowledgebase_response(user_query):
179138

180139
# Init the Slack Bolt logger and log handlers.
181140
SlackRequestHandler.clear_all_log_handlers()
182-
logging.basicConfig(format="%(asctime)s %(message)s", level=logging.DEBUG)
183141

184142

185143
# Lambda handler method.
186-
def handler(event, context):
187-
print(f"${SLACK_SLASH_COMMAND} - Event: {event}\n")
144+
@logger.inject_lambda_context
145+
def handler(event: dict, context: LambdaContext) -> dict:
146+
logger.info(f"Lambda invoked for {SLACK_SLASH_COMMAND}", extra={"event": event})
188147
slack_handler = SlackRequestHandler(app=app)
189148
return slack_handler.handle(event, context)

0 commit comments

Comments
 (0)