I have a python app built on Slack's Bolt framework and deployed on AWS Lambda.
The flow is as such:
- A user triggers a global shortcut which opens a modal
- The modal has a small form where the user fills it and clicks submit.
- The request is sent to AWS API gateway where it is then sent to my AWS Lambda
- The lambda authenticates the user to Okta and invokes another lambda where the main logic is stored
- When the lambda is invoked, the Bolt app's work is done.
The issue here is that after submission of a form, Slack demands that an acknowledgement is sent within 3 seconds.
I don't think my app is meeting this requirement because of the Okta authentication. Because of that, an error message is showing after submission and the form is not closing:
This message is showing even though the request is successfull (It is showing because i am not meeting the 3 seconds requirements)
I want the modal to close even if there are errors.
Below is my python code:
main.py
app = App(
process_before_response=True,
raise_error_for_unhandled_request=True
)
def main(event, context):
# * Log to cloudwatch
logging.info(f"Main function started with event:\n {event}")
# * Create a slack handler
slack_handler = SlackRequestHandler(app=app)
# * Return the slack handler
return slack_handler.handle(event, context)
After the main is executed, it goes to a middleware where i verify whether the token is valid:
@app.use
def middleware_verifications(payload, next):
# * Log to Cloudwatch
logging.info(f"Middleware `middleware_verifications` running with payload:\n {payload}")
# * Get the request type
type = payload["type"].lower() if 'type' in payload else "command"
# * Verify if this is a modal
# * Do not do anything if request is a modal
if type != "modal":
# * Verify if the verification token matches
if not (TOKEN == payload['token']):
raise BoltError(f'Error while verifying the slack token')
# * Goes to the next middleware
next()
The view_submission is then sent to the function below:
# * View submissions goes here * #
@app.view("patching_scheduler_submit") @authenticate([TG.IT_PLATFORM.value]) def view_patching_scheduler(ack, body, client, view):
# * Log event to cloudwatch
logging.info(f"View patching scheduler body: {body}")
# * Acknowledge request
ack(
{
"response_action": "clear"
}
)
# * Get the user id
user = body["user"]
# *** Extract input values
patching_type = view['state']['values']['ptype']['multi_static_select-action']['selected_option']['value']
patching_start_date = view['state']['values']['pstartdate']['datepicker-action']['selected_date']
patching_end_date = view['state']['values']['penddate']['datepicker-action']['selected_date']
patching_start_time = view['state']['values']['pstarttime']['timepicker-action']['selected_time']
patching_end_time = view['state']['values']['pendtime']['timepicker-action']['selected_time']
# * Log to cloudwatch
logging.info(f"patching_type: {patching_type}")
logging.info(f"patching_start_date: {patching_start_date}")
logging.info(f"patching_end_date: {patching_end_date}")
logging.info(f"patching_start_time: {patching_start_time}")
logging.info(f"patching_end_time: {patching_end_time}")
# * Invoke the lambda integration
PatchingScheduler(
username=user['username'],
patching_type=patching_type,
patching_start_date=patching_start_date,
patching_end_date=patching_end_date,
patching_start_time=patching_start_time,
patching_end_time=patching_end_time
).call_integration()
# * Send a message to the user
client.chat_postMessage(channel=user["id"], text="Patching scheduler in progress.")
returnobject={
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": "",
"response_action": "clear"
}
return returnobject
The decorator @authenticate([TG.IT_PLATFORM.value]) is where the code takes time because it has to check the user against the Okta API which takes more than 3 seconds.
I also tried to remove the decorator and use the authenticate inside the function after the ack() but it still gave me the error on the modal:
@app.view("patching_scheduler_submit")
def view_patching_scheduler(ack, body, client, view):
# * Log event to cloudwatch
logging.info(f"View patching scheduler body: {body}")
# * Acknowledge request
ack(
{
"response_action": "clear"
}
)
# * Get the user id
user = body["user"]
# Authenticate
authenticate([TG.IT_PLATFORM.value])
The modal doesn't close. Can someone help me out ?

