練習を兼ねてAWS LambdaからSlackにPOSTするプログラムを組んだ

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る

こんにちは、おてらです。

あれ?随分と久しぶりな更新なような…。

すみません、完全に更新をサボってました!

 

今回はPythonド素人の私がコーディングの練習を兼ねてSlackに定期的にPOSTするPythonのコードを書いてみたのでその記録をしたためます。

発端

私の所属する部門は毎朝8:45から会議室で営業とエンジニア全員が顔を揃えて案件や連絡事項の共有を行っています。

会議室は本社勤務の社員全員の共有リソースなので当然予約が必要です。基本的に毎朝同じ会議室を予約しておきたかったのですが、曜日によっては他の部署の人たちに先に予約されているので毎朝同じ会議室、というわけにはいかなかったんですね。

なので結果的に1週間で複数の会議室を予約している状況なんですが、そうすると毎朝「あれ?今日はどっちだっけ?」というめんどくさい確認が入ってしまうので、それを何とかすべく「Slackに今日の会議室どっちか通知させてよ」というご意見をいただいたので実装した次第です。

準備

Slack

Slackの管理画面からIncomming WebHooksに1つアプリケーションを追加します。

追加したらPOSTさせるチャンネルを設定し、Webhook URLをコピーしておきます。

コーディング

AWS LambdaではPython3.6が利用できるようになっていたのでPython3.6で書いていきます。

また、サードパーティ製のrequestsライブラリを利用します。

Lambda上ではpipが使えないので、あらかじめローカル環境で使いたいライブラリをインストールし、それらをソースコードとひとまとめにしてzip化し、Lambda上で実行できるようにします。

 

作業ディレクトリに移動して以下のコマンドを実行すると、カレントディレクトリにライブラリをインストールすることができるのでこれでrequestsライブラリをインストールします。
最後の .(ドット)を忘れないよう注意。

pip install requests -t .

 

で、実際にSlackにPOSTさせるためのソースコードがこちら。

import json
import datetime
import requests


# Slack の設定
SLACL_POST_URL = "https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXX"

# 今日の曜日を取得
def get_weekday():
    return datetime.datetime.now().weekday()

# 曜日から会議室を判断
def build_message():
    weekday = get_weekday()

    if (weekday == 0 or weekday == 1):
        return "今日の申し送りは第4会議室だよ"
    else:
        return "今日の申し送りは第5会議室だよ"


def lambda_handler(event, context):
    content = build_message()

    # SlackにPOSTする内容をセット
    payload_dic = {
    "text": content,
    "icon": ':katty:',
    "channel": '#random',
    }

    # SlackにPOST
    r = requests.post(SLACL_POST_URL, data=json.dumps(payload_dic))

 

weekday()メソッドの戻り値は0~6で以下のように各曜日と対応しています。

戻り値 0 1 2 3 4 5 6
曜日

火曜日と水曜日が第4会議室、それ以外が第5会議室なので条件分岐はこんなところでいいでしょう。

あとで思いましたがわざわざ get_weekday() メソッド作る意味ないな。

 

2017/5/9 追記

またしてもハマりポイントだったんですが、CloudWatchやLambdaの実行環境はUTCなので日本時間の午前9:00以前に何かしら実行させたい場合、UTCでは前日の時刻になるため時間だけじゃなく曜日もずれることになります。

その結果…

ということが起きてしまいました。

 

なので上記のコードを修正しています。

17行目の曜日判断の部分で火曜日(戻り値:1)と水曜日(戻り値:2)は第4会議室、としていたのを、1日前日にずらして(UTCで)月曜日(戻り値:0)と火曜日(戻り値:1)が第4会議室であるという条件に変更しました。

実行時間のずれには気づいていましたが、曜日が変わることまで気が付かなかったですね。みなさんもご注意ください。

==========追記おわり==========

実装

Zip圧縮化

ここがハマりポイントでした。

私はWindow環境でこれらを作っていたんですが、Zip圧縮するときに普通にWindows標準の機能でいけるだろうと下の画像の手順でZip圧縮しました。

▼NGなやり方

 

ところがこれだとLambda上にアップロードして実行した際に正常に動作しなかったので圧縮解凍ツールを使ってZip圧縮したところうまくいきました。

やはりWindows標準の機能だと何らかの不要なファイルが含まれちゃうとかあるんですかね。

 

Lambda に登録

AWSマネジメントコンソールにログインし、Lambda関数を作成します。

 

このLambda関数の実行トリガーは何か聞かれるのですが、一旦スキップします。

 

詳細設定をしていきます。

名前は適当につけます。

コードエントリタイプは「.ZIPファイルをアップロード」を選択して、先ほど作成したZipファイルをアップロードします。

 

ここもハマりポイントだったんですが、ハンドラの部分、ヘルプにも書かれているように、実行するPythonファイルのファイル名とメソッド名の組み合わせをハンドラとして設定します。

今回はファイル名を「meeting_room_notice.py」、メソッド名を「lambda_handler」としているので、ここに入力するハンドラは「meeting_room_notice.lambda_handler」となります。

 

デフォルト値は「lambda_function.lambda_handler」となっているので不安な人はファイル名を「lambda_function.py」に、メソッド名を「lambda_handler」にしておくとよいでしょう。

ロールはLambdaのデフォルトを利用します。

 

あとは保存してテストしてみます。問題なければ設定したチャンネルにPOSTされるはずです。

CloudWatchのイベントスケジュールをトリガーとして登録

きちんとPOSTされれば定期的にPOSTしてくれるようにCloudWatchのイベントスケジュールをトリガーとして登録します。

 

ルール名は任意。

スケジュール式はCRONで記述するのですが、タイムゾーンがUTCなので日本時間から9時間マイナスしなければならない点に注意。

平日の朝8:40にPOSTして欲しいのでUTCだと日曜日~木曜日の23:40になります。

 

結果

一旦CloudWatchからちゃんとキックしてくれるかを確認したかったので13:45(UTCだと4:45)に設定して放置したところ、指定した時刻にきちんとPOSTされました。

これで明日からはギークナビのマスコットキャラクター、カティちゃんが会議室を通知してくれます!

 

 

 

あっ明日から弊社もゴールデンウィークだった。

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る

SNSでもご購読できます。

コメントを残す