Lambda関数でLINEのメッセージを受信してSlackに通知する手順をまとめておきます。
自分用メモ。
前提
- 開発環境:Cloud9
- OS:Amazon Linux 2023
- Pythonバージョン:3.10
Slack側準備
動作環境作成
自分が管理者権限を持つワークスペースと投稿先のチャンネルを作成しておきます。
改めて説明することは特にない。
Slackアプリの作成
外部からSlackにアクセスするため、窓口となるアプリを作成します。
Slack の bot を自作する(AWS Lambda + API Gateway)記載の手順を参考にSlack Appを作成しました。が、今回はLINE⇒Slack連携なのでApp作成後は「Event Subscriptions」の設定は不要です。
Webhookの追加
App作成後、左メニューから「Incomming Webhooks」を選択して「Activate Incoming Webhooks」をOnにします。
同じ画面一番下の「Add New Webhook to Workspace」を選択。
Appが通知するチャンネルを指定して投稿を許可します。
slack apiの画面に戻るとWebhook URLが生成されているので控えておきます。
AWS側作業
Lambda関数作成~LINE連携
手順はLambdaにLine BOTを作ったメモ参照。
Slackに送信するメッセージ作成
Slackは画像やらボタンやらマークダウンやらが使えるので、せっかくなら多少リッチな見た目にしたいですね。しかしPOST通信のbodyに何を渡せば思ったような見た目になるのかわからない…となったのでBlock Kit Builderを使ってみました。
# | 画面要素の概要 |
---|---|
1 | Slackに投稿されたときのメッセージの見た目。 セクションの並び順変更や削除もここを操作する。 |
2 | セクションやボタン、テキストボックス等のブロックを選んで追加できる。 |
3 | テンプレートを読み込む。1から並べるのは面倒なので便利。 |
4 | メッセージの本体となるJSON。 テキストボックスになっているので文章を入れてみることも可能。 |
Lambda関数実装
お試しのつもりなので何も考えずにWebhookのURLにリクエストを送る実装にしました。Lambda環境変数「slack」にwebhookの追加で控えておいたWebhook URLを登録しています。
環境変数周りの話もLambdaにLine BOTを作ったメモでまとめたので省略。
import json
import os
import urllib.request
import logging
# Slack Webhook URL
SLACK_URL = os.environ['slack']
# Logging Initialize
log = logging.getLogger()
log.setLevel(os.environ['logLevel'])
def lambda_handler(event, context):
log.debug(event)
for message_event in json.loads(event['body'])['events']:
headers = {
'Content-Type': 'application/json; charset=utf-8',
}
body = {
"blocks": [{
# ここにBlock Kit Builderで作ったPayloadが入る
# どこかのtextにmessage_event['message']['text']を入れておく
}]
}
log.debug(body)
req = urllib.request.Request(SLACK_URL, data=json.dumps(body).encode('utf-8'), method='POST', headers=headers)
with urllib.request.urlopen(req) as res:
log.info(res.read().decode("utf-8"))
return {
"statusCode": 200,
"body": json.dumps({
"message": "success",
}),
}
以下を参考に実装しているんですが、bodyの構造に関するドキュメントが見つけられてないのでSlackに送信するメッセージ作成で作ったblockはattachments以下に入れておきました。slack apiのDocsのchat.postMessageに近いけど、必須項目とかが違うしなぁ…。
参考:Line API × AWS Lambda×Slack Incoming WebhookでLineのメッセージをSlackに自動投稿させる
⇒'24/4/4:引用の入れ子みたいになってたのがattachments削除すると直ったのでサンプルコードから削除
テスト
LINEにメッセージを送ってみたらSlackに投稿されるようになった!
下記の引用テキスト「テストだよ」がLINEで送信されたテキストになっています。
bodyにusername入れてみたけど別に動いてないからattachments以下だけでよさそう。
⇒'24/4/4:サンプルコードから削除
ボタンは今後追加したいという気持ちのハリボテです。
今回はloggingを入れているので動かなかったらCloudWatchで原因確認しつつ、デバッグが終わったらLambdaのコンソールから環境変数を編集してログレベルをINFOにしておく感じにしました。コード直して再デプロイするよりは楽。
おわりに
メッセージの組み立てがややこしいだけでただのPOSTなので簡単でよかった。次回はこのSlack通知のスレッドでLINEに返信できるか検討しつつ、コードをsdkでキレイにしていければいいなぁという気持ちです。
先人の皆さんに感謝感謝。