Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog

This post is Private. Only a writer or those who know its URL can access this post.

Improve article
RevisionsShow article in Markdown
Report article
Help us understand the problem. What is going on with this article?

Lamda function and API Gateway for Slack bot

More than 3 years have passed since last update.

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

https://github.com/SnowMasaya/AWS_Lambda_ChatBot

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.

参考

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away