Created
May 12, 2017 02:37
-
-
Save kmix/3255a3bd93065d9265e60354b8e76a37 to your computer and use it in GitHub Desktop.
Simple Wordnik Slackbot (Deployed via AWS Lambda to implement define & synonym slash commands)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import boto3 | |
| import json | |
| import logging | |
| import os | |
| import socket | |
| import urllib2 | |
| from base64 import b64decode | |
| from urlparse import parse_qs | |
| ENCRYPTED_EXPECTED_TOKEN = os.environ['kmsEncryptedToken'] | |
| WORDNIK_API_KEY = os.environ['wordnikApiKey'] | |
| kms = boto3.client('kms') | |
| expected_token = kms.decrypt(CiphertextBlob=b64decode( | |
| ENCRYPTED_EXPECTED_TOKEN))['Plaintext'] | |
| logger = logging.getLogger() | |
| logger.setLevel(logging.INFO) | |
| def respond(err, res=None): | |
| return { | |
| 'statusCode': '400' if err else '200', | |
| 'body': err.message if err else json.dumps(res), | |
| 'headers': { | |
| 'Content-Type': 'application/json', | |
| }, | |
| } | |
| def slack_response(title, attachment_body, ephemeral): | |
| if ephemeral: | |
| response_type = "ephemeral" | |
| else: | |
| response_type = "in_channel" | |
| return {'text': title, 'response_type': response_type, 'attachments': [{'text': attachment_body}]} | |
| def equals_ignore_case(left, right): | |
| try: | |
| return left.lower() == right.lower() | |
| except AttributeError: | |
| return left == right | |
| def get_definition(value, ephemeral): | |
| global WORDNIK_API_KEY | |
| title = "Definition Search - %s" % value | |
| attachment_body = "" | |
| try: | |
| url = "https://api.wordnik.com/v4/word.json/%s/definitions?api_key=%s" % (value, WORDNIK_API_KEY) | |
| req = urllib2.Request(url) | |
| req.add_header('Accept', 'application/json') | |
| response = urllib2.urlopen(req) | |
| data = json.loads(response.read()) | |
| for def_object in data: | |
| if attachment_body != "": | |
| attachment_body += "\n" | |
| attachment_body += "%s / %s" % ( | |
| def_object["partOfSpeech"], def_object["text"]) | |
| return slack_response(title, attachment_body, ephemeral) | |
| except urllib2.URLError as url_exception: | |
| if hasattr(url_exception, 'reason'): | |
| error_msg = "Unable to connect to the Wordnik server: <%s>" % url_exception.reason | |
| elif hasattr(url_exception, 'code'): | |
| error_msg = "Error received from the Wordnik server: <%s>" % url_exception.code | |
| return slack_response(title, error_msg, True) | |
| except Exception as generic_exception: | |
| error_msg = "Error retrieving data from Wordnik: %s" % generic_exception.message | |
| return slack_response(title, error_msg, True) | |
| def get_synonym(value, ephemeral): | |
| global WORDNIK_API_KEY | |
| title = "Synonym Search - %s" % value | |
| attachment_body = "" | |
| try: | |
| url = "https://api.wordnik.com/v4/word.json/%s/relatedWords?relationshipTypes=synonym&api_key=%s" % (value, WORDNIK_API_KEY) | |
| req = urllib2.Request(url) | |
| req.add_header('Accept', 'application/json') | |
| response = urllib2.urlopen(req) | |
| data = json.loads(response.read()) | |
| for def_object in data: | |
| if attachment_body != "": | |
| attachment_body += "\n" | |
| attachment_body += ", ".join(def_object["words"]) | |
| return slack_response(title, attachment_body, ephemeral) | |
| except urllib2.URLError as url_exception: | |
| if hasattr(url_exception, 'reason'): | |
| error_msg = "Unable to connect to the Wordnik server: <%s>" % url_exception.reason | |
| elif hasattr(url_exception, 'code'): | |
| error_msg = "Error received from the Wordnik server: <%s>" % url_exception.code | |
| return slack_response(title, error_msg, True) | |
| except Exception as generic_exception: | |
| error_msg = "Error retrieving data from Wordnik: %s" % generic_exception.message | |
| return slack_response(title, error_msg, True) | |
| def lambda_handler(event, context): | |
| params = parse_qs(event['body']) | |
| token = params['token'][0] | |
| if token != expected_token: | |
| logger.error("Request token (%s) does not match expected", token) | |
| return respond(Exception('Invalid request token')) | |
| user = params['user_name'][0] | |
| command = params['command'][0] | |
| channel = params['channel_name'][0] | |
| try: | |
| command_text = params['text'][0] | |
| except KeyError: | |
| return respond(None, slack_response("Invalid Syntax", "Parameter required for the %s command!" % command, True)) | |
| ephemeral = True | |
| # Determine if response is ephemeral and set boolean accordingly | |
| if command_text[0:1] == "#": | |
| ephemeral = False | |
| command_text = command_text[1:] | |
| if equals_ignore_case(command, '/define'): | |
| return respond(None, get_definition(command_text, ephemeral)) | |
| elif equals_ignore_case(command, '/synonym'): | |
| return respond(None, get_synonym(command_text, ephemeral)) | |
| else: | |
| return respond(None, "%s invoked unsupported command <%s> in <%s> with the following text: %s" % (user, command, channel, command_text)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment