AWS Lambdaで作るSlack bot (Incoming Webhook)
AWS Lambdaで作るSlack bot (Incoming Webhook):
Incomming Webhookは、アプリケーション→Slackの単方向の通知が行える機能です。
Incoming WebhookからURLが提供され、アプリケーションがそのURLにPOSTリクエストを送るとSlackの指定したチャンネルに通知が飛びます。
Slackで何かしらの通知を行いたいとき、単純な内容 + 定期的な予定であればリマインダーの使用が考えられますが、何かしらのイベントを受けて通知を出したり、少し複雑な内容を通知する場合はIncomming Webhookが便利です。
AWS Lambdaとは、なにかしらのイベントによってプログラムを駆動させることができるサービスです。
このようなサービスはFanction as a Service(FaaS)と呼ばれたりします。
FaaSは様々なメリットがありますが、今回Slack botを作る上でのメリットは以下2つかと思われます。
以下の順序で作業を行っていきます。
WorkspaceにIncoming Webhookを登録する方法は2種類あります。
まずSlackAppディレクトリから
いかにも検索できそうなテキストボックスに
サジェストされた
Botを働かせたいチャンネルを選択して
これでIncoming Webhookを使用する準備ができました。
表示されているWebhook URLを手元に記録しましょう。
このURLに指定されたフォーマットでPOSTを投げると、先程指定したチャンネルに投稿が出ます。
フォーマットを含む使用方法やカスタマイズ方法は、Webhook URLが表示されているページに全て記述されています。
また、Webhook URLが表示されているページには以下の手順でアクセスできます。
Webhook URLが表示されているページではBotのアイコンや名前、説明を変更できます。
必要があればここで設定できますが、Webhook URLに投げるPOSTにアイコンや名前のパラメータを入れることで投稿の度に変更することもできます。
単純な例を以下に挙げます。行っている作業は以下の通りです。
AWSのアカウントを作成しましょう。
以下が公式が出しているアカウント作成の流れです。これに従えば難なく登録できるかと思います。
https://aws.amazon.com/jp/register-flow/
クレジットカードの登録と電話による認証が必須となることに注意してください。
無料枠を超えた分は機能しないのではなく、課金されながら機能し続けます。
また事前にリージョン(地理的に離れたデータセンタの集合体)を東京に変更しておいたほうが良いでしょう。
サービス一覧からLambdaを選択し、
関数の設定画面の
今回は特定の時間になったら起動するようにしたいので、
ルールから
すると
また、画面右上の
すると
関数コードには予め
以下例です。
return文の値はSlackに対して影響を与えないので今回は未編集です。
最後に画面右上の
画面右上の
テストイベントを作成しイベントの中身を記述します。
ココに記述されたjsonが、引数
今回は引数
今回AWS Lambdaを利用してアプリ→Slackの単方向のbotを作成しました。
追々Slash commandなどの使用を考える場合はHerokuなどのほうが楽だったかもしれません。
Webhook URLはお手軽で良いのですが、URL一個で使用できるのはセキュリティ的に大丈夫なのでしょうか。
URLバレたらすぐに再生成といった感じでしょうか。
対象読者
- Slackを既に利用している (Workspaceに所属している)
- Slack botの作成経験がない
- Python3が書ける
- AWSを使用したことがない
サービス説明
Slack Incoming Webhookについて
Incomming Webhookは、アプリケーション→Slackの単方向の通知が行える機能です。Incoming WebhookからURLが提供され、アプリケーションがそのURLにPOSTリクエストを送るとSlackの指定したチャンネルに通知が飛びます。
Slackで何かしらの通知を行いたいとき、単純な内容 + 定期的な予定であればリマインダーの使用が考えられますが、何かしらのイベントを受けて通知を出したり、少し複雑な内容を通知する場合はIncomming Webhookが便利です。
Amazon Web Service(AWS) Lambdaについて
AWS Lambdaとは、なにかしらのイベントによってプログラムを駆動させることができるサービスです。このようなサービスはFanction as a Service(FaaS)と呼ばれたりします。
FaaSは様々なメリットがありますが、今回Slack botを作る上でのメリットは以下2つかと思われます。
- サーバの管理を意識しなくて良い
- 必要なときしかリソースが確保されない (コストが安く抑えらえる可能性)
AWS 無料利用枠 (無期限提供分):
これらの AWS 無料利用枠は、12 か月間の AWS 無料利用枠の期間が終了しても自動的に期限切れになることはありません。AWS のすべてのお客様にご利用いただけます。
AWS Lambda
1 か月当たり 1,000,000 件の無料リクエスト**
1 か月当たり最大 320 万秒のコンピューティング時間**
※ 2018-11-24現在
作業順序
以下の順序で作業を行っていきます。- SlackのWorkspaceにIncoming Webhookを登録
- SlackにPOSTするプログラム作成 (Python)
- AWSの設定
SlackのWorkspaceにIncoming Webhookを登録
WorkspaceにIncoming Webhookを登録する方法は2種類あります。- Slackアプリを作成して登録
Incoming Webhook
アプリから登録
Incoming Webhook
アプリから登録」で行います。Incoming Webhook
アプリを使用する場合の登録手順は以下になります。-
Incoming Webhook
アプリを登録 (設定を追加) - チャンネルを選択
- Webhook URLを(手元に)記録
- (名前、アイコンなどをカスタマイズ)
1.Incoming Webhookアプリを登録
まずSlackAppディレクトリからIncoming Webhook
アプリを検索します。いかにも検索できそうなテキストボックスに
Incoming Webhook
と入力するとサジェストしてくれます。サジェストされた
Incoming Webhook
アプリをクリックして、設定を追加
ボタンを押しましょう。
2. チャンネルを選択
設定を追加
を押すとチャンネル選択画面に移行します。Botを働かせたいチャンネルを選択して
Incoming Webhookインテグレーションの追加
を押しましょう。
3. Webhook URLを(手元に)記録
これでIncoming Webhookを使用する準備ができました。表示されているWebhook URLを手元に記録しましょう。
このURLに指定されたフォーマットでPOSTを投げると、先程指定したチャンネルに投稿が出ます。
フォーマットを含む使用方法やカスタマイズ方法は、Webhook URLが表示されているページに全て記述されています。
また、Webhook URLが表示されているページには以下の手順でアクセスできます。
Slackをカスタマイズ
(左メニューの)App管理
(左メニューの)カスタムインテグレーション
Incoming Webhook
- 設定の鉛筆アイコンクリック
4. (名前、アイコンなどをカスタマイズ)
Webhook URLが表示されているページではBotのアイコンや名前、説明を変更できます。必要があればここで設定できますが、Webhook URLに投げるPOSTにアイコンや名前のパラメータを入れることで投稿の度に変更することもできます。
SlackにPOSTするプログラム作成 (Python)
単純な例を以下に挙げます。行っている作業は以下の通りです。- 表示するメッセージ作成
- アイコンと名前指定(しなくても良い)
- Webhook URLにPOST
# 投稿内容は最初に挙げた例に揃えました import json import urllib.request def post_slack(): message = """ 今日のお昼ご飯はこの中から選んでみては? 1. めし屋 2. 洋食 3. 焼き肉 """ send_data = { "username": "お昼ご飯推薦", "icon_emoji": ":bento:", "text": message, } send_text = "payload=" + json.dumps(send_data) # URLにはご自分のWebhook URLを入力してください request = urllib.request.Request( "https://hook.slack.com/~~~~~~~~", data=send_text.encode("utf-8"), method="POST" ) with urllib.request.urlopen(request) as response: response_body = response.read().decode("utf-8")
AWSの設定
(AWSアカウント作成)
AWSのアカウントを作成しましょう。以下が公式が出しているアカウント作成の流れです。これに従えば難なく登録できるかと思います。
https://aws.amazon.com/jp/register-flow/
クレジットカードの登録と電話による認証が必須となることに注意してください。
無料枠を超えた分は機能しないのではなく、課金されながら機能し続けます。
また事前にリージョン(地理的に離れたデータセンタの集合体)を東京に変更しておいたほうが良いでしょう。
AWS Lambdaにプログラム設置
サービス一覧からLambdaを選択し、関数の作成
をクリックすると以下の画面に遷移します。一から作成
を選択し、必要事項を選択・記述します。-
名前
は任意のものを入力してください。ランタイムは今回はPython3.7(3.6でも可)を選択します。 -
ランタイム
は今回はPython 3.7
を選択します。(3.6でも可) -
ロール
は、今回はAWS内のリソースにアクセスしないため、カスタムロールの作成
を選択し、特に権限を持たないロールを一つ作成して割り当てます。
-
ロール
というのはAWSリソースへのアクセスをコントロールする機能で、AWS Identity and Access Management (IAM) によって管理されます。 - 作成するLambdaの関数がAWS内のデータベースなどにアクセスする場合は適切な権限を付与する必要があります。
-
関数の作成
を押すと関数が作成され、関数の設定画面に遷移します。
トリガー(起動タイミング)追加
関数の設定画面のDesigner
からトリガー(起動タイミング)を設定します。今回は特定の時間になったら起動するようにしたいので、
Designer
のトリガーの追加
からCloudWatch Events
を追加します。CloudWatch Events
追加前CloudWatch Events
追加後CloudWatch Events
を追加すると、Designer
上で追加されたCoudWatch Events
が選択された状態になり、Designer
の下にトリガーの設定
が現れます。ルールから
新規ルールの作成
を選択しましょう。すると
トリガーの設定
の項目が変化しますので、それぞれ記述していきます。-
ルール名
は、任意の名前を入力してください。 -
ルールタイプ
は、今回のように時間を利用して起動する場合はスケジュール式
を選択します。 -
スケジュール式
は、cron
かrate式
で記述できます。
- 式についての詳細はAWSドキュメント:ルールのスケジュール式を確認してください。
-
cron
は指定した時間に、rate式
では一定時間ごとに関数を起動できます。 -
cron
で記述する場合、UTCで設定することに注意してください。 - 例として、日本の月-金曜日の午前11時45分に起動する場合、
cron(45 2 ? * MON-FRI *)
となります。
追加
をしましょう。また、画面右上の
保存
ボタンを押すまで保存されませんので注意してください。
コード設置
Designer
の中央の関数を選択します。(例ではForQiita
)すると
CloudWatch Events
を選択していたときはトリガーの設定
だった枠が関数コード
となります。関数コードには予め
lambda_function.py
が入っており、以下のコードが記述されています。import json def lambda_handler(event, context): # TODO implement return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') }
lambda_handler(event, context)
はトリガーによってLambda関数が呼び出されたときに、最初に呼び出されるメソッドです。(関数コード
のハンドラ
から変更可能)- 引数である
event
はdictであり、トリガーによって中身が変化します。
- 例として、AWS API GatewayをトリガーとしてHTTPでアクセスによってLambdaが呼び出されたとき、
event
にはHTTPヘッダやボディが含まれます。
- 例として、AWS API GatewayをトリガーとしてHTTPでアクセスによってLambdaが呼び出されたとき、
-
context
はオブジェクトであり、Lambdaのランタイム情報を得ることができます。
SlackにPOSTするプログラム作成 (Python)
で作成したコードを統合します。以下例です。
import json import urllib.request def lambda_handler(event, context): # TODO implement post_slack() return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') } def post_slack(): message = """ 今日のお昼ご飯はこの中から選んでみては? 1. めし屋 2. 洋食 3. 焼き肉 """ send_data = { "username": "お昼ご飯推薦", "icon_emoji": ":bento:", "text": message, } send_text = "payload=" + json.dumps(send_data) # URLにはご自分のWebhook URLを入力してください request = urllib.request.Request( "https://hooks.slack.com/~~~~~~~~~~~~~~~~~~~", data=send_text.encode('utf-8'), method="POST" ) with urllib.request.urlopen(request) as response: response_body = response.read().decode('utf-8')
lambda_handler()
が呼び出されたときにSlackにPOSTするよう追記しました。return文の値はSlackに対して影響を与えないので今回は未編集です。
最後に画面右上の
保存
ボタンを忘れずに押しましょう。
テスト
画面右上のテスト
ボタンからテストを行うことができます。テストイベントを作成しイベントの中身を記述します。
ココに記述されたjsonが、引数
event
の内容となります。今回は引数
event
を使用していないためどのような内容でも問題ありません。イベント名
をつけて作成
ボタンを押すと、画面左上のテスト
ボタンから作成したテストイベントを利用してテストできます。
最後に
今回AWS Lambdaを利用してアプリ→Slackの単方向のbotを作成しました。追々Slash commandなどの使用を考える場合はHerokuなどのほうが楽だったかもしれません。
Webhook URLはお手軽で良いのですが、URL一個で使用できるのはセキュリティ的に大丈夫なのでしょうか。
URLバレたらすぐに再生成といった感じでしょうか。
コメント
コメントを投稿