Cloud FunctionsでSlack通知をする関数を作る

どうも初めまして。grasysの福嶌です。
今回は初歩的な内容ですがご愛嬌ということで。

先日行いましたセミナーの記事 - ‘GCEとGKEのアーキテクチャを一挙公開――GCP活用のコツをgrasys 長谷川祐介氏が伝授’ を見る機会あったのでちょっとしたことをやってみようと思いました。

記事の中で解説されていますが弊社のコーポレートサイトとブログサイトにGoogle Cloud Storage(以下GCS)を利用しているのでGoogle Cloud Functions(以下GCF)で何かできないかなと思いGCFを触ってみました。

今回のゴール

GCSの変更をトリガーにしてGCF使いslackにスクレイピング内容を通知できるようにする

GCFとは?

GCPで関数を実行するためのサービス(サーバーレス)、詳しくは公式のドキュメントへ!

作ってみた

自分の考えたロジックは以下のようになりました。

考えるまでもなくとてもシンプルですねー
作成したFunctionsのコードは以下のようになります。ここで注意しなければいけないのは実行したい関数のエントリーポイントはmain.pyにしないといけない点です。

#!/usr/bin/env python
#coding:utf-8

import requests, json
from bs4 import BeautifulSoup


# スクレイピングを行いデータを抽出する関数
def create_text(url):
    """
    BeautifulSoupを利用してスクレイピングをする。
    スクレイピングには作法やルールがあるためここでサンプルコードを載せるのは割愛
    """
    return msg

# Cloud Functionsでデプロイする関数
def cloud_func_gcs(event, context):
    targetURL = "{スクレイピングを行うWEBサイトのURL}"
    Webhook = "{WebhookURL}"
    # 指定したファイルのイベントかどうかの判定
    if content['name'] == "index.html":
      requests.post(Webhook , data = json.dumps({
          'text': create_text(targetURL),
          'username': 'grasys news',
          'icon_emoji': u':herb:',
          'link_names': 1,
      }))

今回は簡単な関数なので1ファイルにしていますが応用して以下のようにパッケージを分ける構成でも実行は可能です。

├── main.py
├── requirements.txt
├── package1
│   ├── hoge.py
│   └── fuga.py
└── package2
    └── piyo.py
デプロイ

デプロイは以下のコマンドでできます。
何か変な箇所やビルドが失敗したらエラーがStackdriver Loggingで確認できるのでコツコツと修正していきましょう。
自分は関数のファイル名がmain.pyじゃないぞと言われました。

試行錯誤→デプロイしながらを繰り返すとバージョンがどんどん上がっていきます(汗)

$ gcloud functions deploy {EntryPoint} \
  --runtime python37 --stage-bucket {BUCKET} \
  --trigger-bucket {BUCKET} \
  --region asia-northeast1

各オプションの説明ですが
--runtimeは実行する言語の指定になります。今回はPython 3.7を利用します。
--stage-bucketはfunctionsのソースコードをあげるバケットの指定になります。
--trigger-bucketはどのGCSバケットをトリガーとするかの指定になります。
--regionはどこのリージョンを利用するか

その他、詳しくは--helpに書いてる。

動作確認

試しに弊社のコーポレートサイトをスクレイピングして最新情報を通知する関数を試してみました! (更新タイミングに出会えなかったのでストレージはコーポレートサイトとは違うストレージを利用しました(^_^;))
そんなこんなで実行した結果以下のようになりました。


動作してますねー

近々、合同採用イベントを行うようです。

まとめ

今回はslackのWebhookを叩いて通知するということをしましたが
LINE Messaging APIやTwitterなどにも利用できそうですね。夢が広がりんぐ
ただ今回、一点懸念点で考えたのことはスクレイピングする対象箇所以外(例として弊社コーポレートサイトだと最新情報以外)が変更されてもトリガーを引いてしまいます。これはHTML側にhidden属性をつけて日付を入れて関数の方で日付の判定を行えば大丈夫かなと思いました。
最後にCloud Functionsには様々なイベントとトリガーがあるので上記以外にもたくさん使えそうですね!

それでは!アディオス!