LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 5 years have passed since last update.

Lamda function and API Gateway for Slack bot

Last updated at Posted at 2016-09-26

Slack Bot with Lambda function

Screen Shot 2016-09-18 at 10.07.25 AM.png

If you make the Wikipedia search bot, you use the below code

Setting Lambda

You choose the Lambda

Screen Shot 2016-09-18 at 10.29.43 AM.png

You make the function by the Create a Lambda function

Screen Shot 2016-09-18 at 10.29.24 AM.png

You don't choose the any Bleu Print.
You choose the "Skip"

You remove the Api Gateway Configure triggers. Because it is setting the after part.

Screen Shot 2016-09-18 at 10.00.02 AM.png

You set the functionname.
You choose the Runtime "Python2.7"

Screen Shot 2016-09-27 at 7.33.03 AM.png

Setting the code

You set the elasticsearch endpoint.
Because it is different situation for each user.

query = "curl -XGET {your elasticsearch endpoint}:9200/_all/_search?pretty -d\'"

You set the below code.
Before run the below code, you have to run the Elasticsearch.


import logging
import subprocess
import json
import random

"""
Reference:
    http://www.yamamanx.com/slack-bot-aws-lambda-python-api-gateway/
"""

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def make_query(keyword):
    """
    Make a Elasticsearch search query
    :param keyword(string): set the search key words
    :return (string): elasticsearch search query
    """
    # Simple Query
    query = "curl -XGET {your elasticsearch endpoint}:9200/_all/_search?pretty -d\'"
    make_query_before = '{ "query": { "match" : { "title": { "query": '
    query_keyword = "\"" + keyword + "\""
    make_query_after = "} } } }\'"
    elasticsearch_query = query + make_query_before + query_keyword + make_query_after
    return elasticsearch_query

def return_code(text):
    """
    Make return code for slack
    :param text(string): slack return text
    :return (string): json format for slack
    """
    payload={'text': text}
    return payload

def lambda_handler(event, context):
    """
    Get the Slack command (using the outgoing) and return the search result
    :param event:
    :param context:
    :return (json): if the exists the image data in the search key, return the image, if the no exist the image, r
                    eturn the wiki url link
    """
    command_text = event['text'].replace("bot_lambda_out ", "")

    elasticsearch_query = make_query(command_text)
    try:
        sysmte_output = subprocess.Popen(elasticsearch_query, shell=True, stdout=subprocess.PIPE).stdout.read()
    except OSError:
        print(OSError)
    json_data = json.loads(sysmte_output)
    if json_data['hits']['hits']:
        title = json_data['hits']['hits'][0]['_source']['title']
        abstract = json_data['hits']['hits'][0]['_source']['abstract']
        url = json_data['hits']['hits'][0]['_source']['url']
        return_data = title + "\n" + abstract + "\n" + url + "\n"
    else:
        return return_code("No match")

    image_list = []
    for hit_data in json_data['hits']['hits']:
        if hit_data['_source']['image']:
            image_list.append(hit_data['_source']['image'])

    if image_list:
        return return_code(return_data + random.choice(image_list))

    if json_data['hits']['hits']:
        return return_code(return_data)

Setting the Role

You make the new rolw by the "Create new role from templates(s)"
You set the Role name

Screen Shot 2016-09-27 at 7.37.03 AM.png

You choose the create function

Screen Shot 2016-09-27 at 7.38.28 AM.png

Setting the API Gateway

You choose the API Gateway

Screen Shot 2016-09-18 at 10.47.12 AM.png

You choose the Create API

Screen Shot 2016-09-18 at 10.48.19 AM.png

You choose the Create Method
You choose the Post

Screen Shot 2016-09-18 at 10.49.07 AM.png

Mapping the Request by the Integration Request

Screen Shot 2016-09-18 at 10.50.35 AM.png

When you choose Body Mapping Templates, you can watch the below screen you choose the Add mapping template

Screen Shot 2016-09-18 at 10.52.02 AM.png

You input the [application/x-www-form-urlencoded]
You input the below sentence for the template

## convert HTML POST data or HTTP GET query string to JSON

## get the raw post data from the AWS built-in variable and give it a nicer name
#if ($context.httpMethod == "POST")
 #set($rawAPIData = $input.path('$'))
#elseif ($context.httpMethod == "GET")
 #set($rawAPIData = $input.params().querystring)
 #set($rawAPIData = $rawAPIData.toString())
 #set($rawAPIDataLength = $rawAPIData.length() - 1)
 #set($rawAPIData = $rawAPIData.substring(1, $rawAPIDataLength))
 #set($rawAPIData = $rawAPIData.replace(", ", "&"))
#else
 #set($rawAPIData = "")
#end

## first we get the number of "&" in the string, this tells us if there is more than one key value pair
#set($countAmpersands = $rawAPIData.length() - $rawAPIData.replace("&", "").length())

## if there are no "&" at all then we have only one key value pair.
## we append an ampersand to the string so that we can tokenise it the same way as multiple kv pairs.
## the "empty" kv pair to the right of the ampersand will be ignored anyway.
#if ($countAmpersands == 0)
 #set($rawPostData = $rawAPIData + "&")
#end

## now we tokenise using the ampersand(s)
#set($tokenisedAmpersand = $rawAPIData.split("&"))

## we set up a variable to hold the valid key value pairs
#set($tokenisedEquals = [])

## now we set up a loop to find the valid key value pairs, which must contain only one "="
#foreach( $kvPair in $tokenisedAmpersand )
 #set($countEquals = $kvPair.length() - $kvPair.replace("=", "").length())
 #if ($countEquals == 1)
  #set($kvTokenised = $kvPair.split("="))
  #if ($kvTokenised[0].length() > 0)
   ## we found a valid key value pair. add it to the list.
   #set($devNull = $tokenisedEquals.add($kvPair))
  #end
 #end
#end

## next we set up our loop inside the output structure "{" and "}"
{
#foreach( $kvPair in $tokenisedEquals )
  ## finally we output the JSON for this pair and append a comma if this isn't the last pair
  #set($kvTokenised = $kvPair.split("="))
 "$util.urlDecode($kvTokenised[0])" : #if($kvTokenised[1].length() > 0)"$util.urlDecode($kvTokenised[1])"#{else}""#end#if( $foreach.hasNext ),#end
#end
}

You save it.

Deploy

After mapping, you deploy the code.
After deploy You copy the API Endpoint.

Deploy

Screen Shot 2016-09-18 at 10.55.20 AM.png

End Point

Screen Shot 2016-09-18 at 10.57.01 AM.png

If the stage doesn't exist you have to create the stage.

Screen Shot 2016-09-18 at 10.58.14 AM.png

Setting the Slack

You search the "Outgoing Webhook"

Screen Shot 2016-09-18 at 10.14.58 AM.png

You add the Outgoing Webhook in the Custom Integratations

After that you set the [Add Configuration]

1: You set the channel for slack bot
2: You set the trigger word for slack bot
3: You set the API endpoint URL(It is set the Lambda(API Gateway)) to the URL(s)
4: You set the Customize Name bot
5: You set the Customize Icon bot

You copy the End Point URL for Slack Outgoing Webhooks and save setting

In my case, I set the trigger word is "bot_lambda_out"
And search word is "earch"

Screen Shot 2016-09-27 at 7.41.56 AM.png

You confirm the wikipedia title and abstrat, link , image.

参考

0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up