対象読者
- 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とは、なにかしらのイベントによってプログラムを駆動させることができるサービスです。
このようなサービスはFunction as a Service(FaaS)と呼ばれたりします。
FaaSは様々なメリットがありますが、今回Slack botを作る上でのメリットは以下2つかと思われます。
- サーバの管理を意識しなくて良い
- 必要なときしかリソースが確保されない (コストが安く抑えらえる可能性)
また、AWS Lambdaは無料枠があり、ひと月あたり一定回数or一定動作時間以内なら無料で使用することができます。
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しか使用する予定がないので、2つ目の「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
後にAWS Lambdaから呼ぶことを考えるとメソッドにまとめておいたほうが良いでしょう。
# 投稿内容は最初に挙げた例に揃えました
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
を追加すると、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バレたらすぐに再生成といった感じでしょうか。