Post images of Papillon regularly on Python + AWS Lambda + Slack

This is the article on the 15th day of Advent Calendar 2015 Python Part 2. Immediately after I came to work, I recently uploaded a Papillon image to Slack's Papillon room, but it became a little troublesome, so I tried to automate it.

Overview

We regularly post images of papillons (dogs) to Slack, which is a common chat within the company. Since it is troublesome to select and post an image by myself, I thought of a structure that can automatically post at regular intervals.

I will write a simple configuration diagram below.

python_advent_01.png

(1) AWS Lambda starts regularly and gets multiple Papillon image URLs from the GCS API (2) Select an image from multiple images (3) Post the selected image URL to Slack

By using AWS Lambda, you can configure without a server.

Google Custom Search API

The Google Custom Search API allows you to perform Google's custom search from code. This time, we will use image search. Until November 2015, the Google image search API was available, but it is currently unavailable, so I will use it. GCS API requires API KEY to use, but the free plan has a daily usage limit of 1000 times, which is not many, but there is no problem for this use, so get the KEY with the free plan To do.

The details are explained in the blog here, so please refer to it if you like.

Slack

Slack is a service used as the main chat for our engineers. There are various methods for integration, but there is a mechanism for posting to chat with POST messages. This time, we will post a message using that mechanism (Incoming Webhook).

Incoming WebHook settings

You need to get the URL for the post to which the POST message will be sent. Publish the posting URL on Slack's Incoming WebHook Settings Page.

Select a channel and click the ʻAdd Incoming WebHooks Integration` button. Screenshot 2015-06-22 18.47.17.png

Make a copy of the displayed webhook URL Screenshot 2015-06-22 18.48.30.png

(Optional) You can change the default post settings if you want.

AWS Lambda

AWS Lambda is a service that allows you to execute code without preparing a server by uploading executable code. A simple API can be implemented serverlessly by executing a scheduling task like Cron or combining it with API Gateway. Until now, only node.js and java were supported, but in October 2015, python was supported. This time, I will implement it using AWS Lambda Python.

Scheduling task registration

Select Lambda from AWS and create a new Lambda Function. You can register tasks that can be executed regularly by selecting lambda-canary fromselectblue print`.

スクリーンショット 2015-12-13 17.59.44.png

Schedule registration

Set the schedule of the task you want to execute regularly. It can be described like cron in Schedule expression. Note that if specified by cron, the specified time will be UTC. For more information, see Processing Scheduled Events Using Lambda Functions.

Here, it is set to be executed every 5 minutes.

スクリーンショット 2015-12-13 18.01.58.png

Task settings

Set the task. Basically, paste the following code as the default setting. After that, set CUSTOM_SEARCH_API_KEY, CUSTOM_ENGINE_ID, and SLACK_POST_URL obtained in the previous step.

.python


#-*- coding:utf-8 -*-
from urlparse import urljoin
from urllib import urlencode
import urllib2 as urlrequest
import json
import random


#Settings around CUSTOM SEARCH API
CUSTOM_SEARCH_API_KEY = "XXXXXXXXXXXXXXXXXXXXXXX"
CUSTOM_ENGINE_ID = "XXXXXXXXXXXXXXXXXXXXXXX"
URL_TEMPLATE = "https://www.googleapis.com/customsearch/v1?key={key}&cx={cx}&searchType=image&q={search_word}"

#Settings around SLACK
SLACK_POST_URL = "https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"


def post_image_to_slack(search_word):
    """
Get the URL of the image with google custom serach and post it to SLACK at random
    """
    #Get multiple urls
    urls = get_image_urls(search_word)

    #Do not post if url could not be obtained
    if len(urls) == 0:
        return "no images were found."

    #Randomly select url
    url = random.choice(urls)

    #Compose a message for slack
    post_msg = build_message(url)

    #Post to slack
    return post(post_msg)


def get_image_urls(search_word):
    """
Get the URL of an image with a keyword from the GOOGLE CUSTOM SEARCH API
    """
    encoded_search_word = urlrequest.quote(search_word)
    url = URL_TEMPLATE.format(key=CUSTOM_SEARCH_API_KEY, cx=CUSTOM_ENGINE_ID, search_word=encoded_search_word)
    req = urlrequest.Request(url)
    res = urlrequest.build_opener(urlrequest.HTTPHandler()).open(req)
    data = json.load(res)

    if "items" not in data:
        return []

    links = []
    for item in data["items"]:
        links.append(item["link"])
    return links


def post(payload):
    """
POST a message to Slack
    """
    payload_json = json.dumps(payload)
    data = urlencode({"payload": payload_json})
    req = urlrequest.Request(SLACK_POST_URL)
    response = urlrequest.build_opener(urlrequest.HTTPHandler()).open(req, data.encode('utf-8')).read()
    return response.decode('utf-8')


def build_message(url, **kwargs):
    """
Compose a message for Slack
    """
    post_message = {}
    post_message["text"] = url
    post_message.update(kwargs)
    return post_message


def lambda_handler(event, context):
    post_image_to_slack('Papillon')

When the task is executed, the def lambda_handler (event, context): part is executed (can be changed in the settings). This time, it is statically set as Papillon, but since JSON can be passed at runtime, it is also possible to specify search parameters as arguments. Also, if it is not executed, the registered schedule may be disabled, so please check it.

Execution result

The following images are posted at the set time.

スクリーンショット 2015-12-14 22.54.51.png

It's a good papillon!

At the end

By using AWS Lambda Python, I was able to regularly search for images on Google and post images of Papillon without preparing a server. You can also post Papillon interactively by using API Gateway. (It may be better to use Hubot, but ...)

Have a good Python life with AWS Lambda!

Reference article

Recommended Posts

Post images of Papillon regularly on Python + AWS Lambda + Slack
Support for Python 2.7 runtime on AWS Lambda (as of 2020.1)
Posted as an attachment to Slack on AWS Lambda (Python)
Run Python on Schedule on AWS Lambda
Regularly post to Twitter using AWS lambda!
[Python] Run Headless Chrome on AWS Lambda
Periodically run a python program on AWS Lambda
Summary of studying Python to use AWS Lambda
Check types_map when using mimetypes on AWS Lambda (Python)
Deploy Python3 function with Serverless Framework on AWS Lambda
I want to AWS Lambda with Python on Mac!
Post from Python to Slack
Post to vim → Python → Slack
[Python] Scraping in AWS Lambda
Post to slack with Python 3
Handling of python on mac
Post processing of python (NG)
Faster loading of Python images
[Python] Allow pip3 packages to be imported on AWS Lambda
Site monitoring and alert notification with AWS Lambda + Python + Slack
Post to Slack in Python
xgboost (python) on EC2 Spot instance environment prepared by AWS Lambda
Things to note when running Python on EC2 from AWS Lambda
Best practice for logging in JSON format on AWS Lambda / Python
Pixel manipulation of images in Python
Write AWS Lambda function in Python
Post multiple Twitter images with python
Post images from Python to Tumblr
Notify HipChat with AWS Lambda (Python)
Use AWS lambda to scrape the news and notify LINE of updates on a regular basis [python]
Easy server monitoring with AWS Lambda (Python) and result notification in Slack
Modules cannot be imported in Python on EC2 run from AWS Lambda
Prepare the environment of Chainer on EC2 spot instance with AWS Lambda
[AWS] Using ini files with Lambda [Python]
Install python library on Lambda using [/ tmp]
Regularly notify Slack of missed Backlog issues
Post the subject of Gmail on twitter
Slack notification of weather information on OpenWhisk
Study on Tokyo Rent Using Python (3-1 of 3)
Connect to s3 with AWS Lambda Python
[Python] Japanese localization of matplotlib on Ubuntu
Summary of how to write AWS Lambda
Get rid of DICOM images in Python
Python + Selenium + Headless Chromium with aws lambda
Create a setting in terraform to send a message from AWS Lambda Python3.8 to Slack