From fc139f6c62362d0124a8e61d0c072f665e5deda0 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 13 Oct 2020 11:03:30 -0700 Subject: [PATCH] Introduce a new turbot_interactive function Now that we've introduced a new entry point for our Slack app, which is the interactive features, (that is, an entry point that Slack will POST to when the user clicks on a button or some other interactive element that our app. provides to them). --- turbot_lambda/turbot_lambda.py | 49 +++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/turbot_lambda/turbot_lambda.py b/turbot_lambda/turbot_lambda.py index b8853b3..e3efa6d 100644 --- a/turbot_lambda/turbot_lambda.py +++ b/turbot_lambda/turbot_lambda.py @@ -68,15 +68,18 @@ def turbot_lambda(event, context): return error("Invalid Slack signature") # It's a bit cheesy, but we'll just use the content-type header to - # determine if we're being called from a slash command or from a - # slack event. (The more typical way to do this would be to have - # different routes setup, but I want a single function, and with - # AWS Lambda I don't have the option to have multiple defined - # entry-point functions. - if (headers['Content-Type'] == "application/json"): + # determine if we're being called from a Slack event or from a + # slash command or other interactivity. (The more typical way to + # do this would be to have different URLs for each Slack entry + # point, but it's simpler to have our Slack app implemented as a + # single AWS Lambda, (which can only have a single entry point). + content_type = headers['content-type'] + + if (content_type == "application/json"): return turbot_event_handler(event, context) - else: - return turbot_slash_command(event, context) + if (content_type == "application/x-www-form-urlencoded"): + return turbot_interactive_or_slash_command(event, context) + return error("Unknown content-type: {}".format(content_type)) def turbot_event_handler(event, context): """Handler for all subscribed Slack events""" @@ -147,14 +150,40 @@ def app_home_opened_handler(body): }) return "OK" -def turbot_slash_command(event, context): +def turbot_interactive_or_slash_command(event, context): + """Handler for Slack interactive things (buttons, shortcuts, etc.) + as well as slash commands. + + This function simply makes a quiuck determination of what we're looking + at and then defers to either turbot_interactive or turbot_slash_command.""" + + # Both interactives and slash commands have a urlencoded body + body = parse_qs(event['body']) + + # The difference is that an interactive thingy has a 'payload' + # while a slash command has a 'command' + if 'payload' in body: + return turbot_interactive(json.loads(body['payload'][0])) + if 'command' in body: + return turbot_slash_command(body) + return error("Unrecognized event (neither interactive nor slash command)") + +def turbot_interactive(payload): + """Handler for Slack interactive requests + + These are the things that come from a user interacting with a button + a shortcut or some other interactive element that our app has made + available to the user.""" + + print("In turbot_interactive, payload is: {}".format(str(payload))) + +def turbot_slash_command(body): """Implementation for Slack slash commands. This parses the request and arguments and farms out to supporting functions to implement all supported slash commands. """ - body = parse_qs(event['body']) command = body['command'][0] args = body['text'][0] -- 2.43.0