Skip to content

Instantly share code, notes, and snippets.

@kmix
Created May 12, 2017 02:37
Show Gist options
  • Select an option

  • Save kmix/3255a3bd93065d9265e60354b8e76a37 to your computer and use it in GitHub Desktop.

Select an option

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)
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