概要
やりたいこと
slackbotを作って、Slackに通知があったら自動でアクションをとりたい。
最終的に AWS アラートに対して色々なアクションを行う Slack Bot を作成したい。
Slack Bot
こちらの記事を見ると 5 種類の作り方がある。
- Incoming webhooks
- Slash command
- Bot users (RTM API)
- Bot users (Events API)
- Bot users (フル)
今回は 4 の Events API を利用する。
スコープ
API を実行する際の権限のこと。Bot 用と User 用の 2 種類ある。
Bot Token Scopes
: Bot(プログラム)からアクションしたい場合User Token Scopes
: ユーザとしてアクションしたい場合
手順
投稿用 Slack App 作成
最初にシンプルな Slack チャンネルにメッセージを投稿する Slack App を作成する。
以下のリンクから Slack App を作成する。
App Name と Slack Workspace を入力。
サイドバー「OAuth & Permission」の Scopes セクションがある。
Bot Token Scopes と User Token Scopes の両方に以下のスコープを追加。
ページ上部の「Install App to Workspace」でアプリをワークスペースに追加する。
Slack Workspace との連携後に、アクセストークンが発行される。
Slack チャンネル Slackbot を追加する。以下のコマンドで入れる。
/invite @sec-aws-alert
Bot ユーザのトークンで Slack チャンネルに投稿。
curl -X POST 'https://slack.com/api/chat.postMessage' \ -d 'token=xoxb-xxxxxxxxx' \ -d 'channel=#test-sec-alert' \ -d 'text=テキスト'
以下のように Slack チャンネルに投稿できた。
投稿をモニタリングする Slack App 作成
続いて投稿をモニタリングする Slack App を作成する。
Slack App のスコープには以下を選択。
プライベートチャンネルでもモニタリング・投稿する場合は以下のスコープを選択する。
Slack bot 用アプリデプロイ
下記を参考に、API Gateway + Lambda を作成する。
発行された inveke url をメモする。
Slack APP Event Subscriptions 登録
サイドバー「Event Subscriptions」より、Enable Events を On にし、上記で取得した invoke url を Request URL に登録する。
Subscribe to bot events に以下2つを設定。
message.groupsはプライベートチャンネル用。
対象のチャンネルに slack bot を招待した状態で、アラートを投げる。
Slack Events API 再送対応(X-Slack-Retry-Numヘッダー)
下記を参考に、X-Slack -Retry-Num ヘッダーの有無による再送処理判定を Lambda Function に追加する。
初めに、ヘッダーを Lambda で受け取れるよう API Gateway で Lambda プロキシ統合を有効化する。
- API Gateway コンソール
- API を選択
- リソース
- POST を選択
- 統合リクエスト
- lambda 統合プロキシにチェック
- APIを再デプロイ
これで Lambda にヘッダー含むリクエスト情報が送られるようになる。
以下のように Lambda を修正。
- リクエスト情報から header と body を取得
- header に X-Slack-Retry-Num が存在する場合、Slack Events API 再送を防止
def handle_slack_event(request: dict, context) -> str:
header = request['headers']
slack_event = json.loads(request['body'])
logging.info(json.dumps(header))
logging.info(json.dumps(slack_event))
if 'X-Slack-Retry-Num' in header:
logging.info('X-Slack-Retry-Num: ' + header['X-Slack-Retry-Num'])
return 200
エラー
Your request URL responded with an HTTP error. Update your URL to receive a new request and challenge value.
Slack からの challenge
を受け取る際にエラー。
以下2つの現象
- 最初から Lambda プロキシ統合を有効にして作成すると challenge が通らない
- Lambda まで届いていない
Lambda 統合プロキシを有効化した状態で Slack からの challenge を受ける場合、レスポンスを以下のようにする。
if "challenge" in slack_event:
#return slack_event.get("challenge")
return {
'statusCode': 200,
'body': slack_event.get("challenge")
}
参考
[slack]もしかしてRTMはもう使えなくなったのか(2020/03/11)?
コメント