import requests
import hashlib
import hmac
+import json
ssm = boto3.client('ssm')
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]