]> git.cworth.org Git - turbot/commitdiff
Implement url_verification for Slack event handling
authorCarl Worth <cworth@cworth.org>
Tue, 13 Oct 2020 03:07:40 +0000 (20:07 -0700)
committerCarl Worth <cworth@cworth.org>
Tue, 13 Oct 2020 04:12:39 +0000 (21:12 -0700)
This isn't a real event, but it is required to correctly be able to handle
this url_verification challenge before Slack will allow us to register
our URL in its interface.

turbot_lambda/turbot_lambda.py

index b86d9184921c9a61fb67a4b1b89a97d4f308dd0e..19aee47aa74005575b970d8f40a60fdd34657c06 100644 (file)
@@ -5,6 +5,7 @@ import boto3
 import requests
 import hashlib
 import hmac
+import json
 
 ssm = boto3.client('ssm')
 
@@ -54,17 +55,52 @@ def turbot_lambda(event, context):
     Slack, (by means of the SLACK_SIGNING_SECRET SSM parameter), and
     refuses to do anything if not.
 
-    Then this parses the request and arguments and farms out to
-    supporting functions to implement all supported slash commands.
-
+    Then this defers to either turbot_event_handler or
+    turbot_slash_command to do any real work.
     """
 
-    signature = event['headers']['X-Slack-Signature']
-    timestamp = event['headers']['X-Slack-Request-Timestamp']
+    headers = requests.structures.CaseInsensitiveDict(event['headers'])
+
+    signature = headers['X-Slack-Signature']
+    timestamp = headers['X-Slack-Request-Timestamp']
 
     if not slack_is_valid_request(signature, timestamp, event['body']):
         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"):
+        return turbot_event_handler(event, context)
+    else:
+        return turbot_slash_command(event, context)
+
+def turbot_event_handler(event, context):
+    """Handler for all subscribed Slack events"""
+
+    body = json.loads(event['body'])
+
+    # First, we have to properly respond to url_verification
+    # challenges or else Slack won't let us configure our URL as an
+    # event handler.
+    if (body['type'] == 'url_verification'):
+        return {
+            'statusCode': 200,
+            'body': body['challenge']
+        }
+
+    return error("Event not yet implemented")
+
+def turbot_slash_command(event, context):
+    """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]