はじめに
Slackで自分が投稿したメッセージに対してリアクションされた場合に通知されて欲しいなと思い調べてみましたが見つかりません…。
未読やメンションは通知され、かつバッヂで残るので見逃しは基本ありませんが、リアクションは自発的に確認する必要があるので確認が遅れたり忘れたりすることがあります。
返信が必ず欲しい内容ではメンションしてもらうよう促せば良いですがリアクションでの返事の手軽さは中々手放せません。
なのでリアクションが通知されるようにSlackアプリを作りました。
※今回作成したアプリにスラッシュコマンドを追加した記事も書いてます。
Slackのスラッシュコマンドを作成する
漠然と以下をイメージしながら進めました。
- 自分にだけ表示
- 自分のリアクションは無視
- 特定のメッセージのみ通知
環境
- Python3.8
- Azure App Service
Slackアプリ作成
以下URLにアクセスしてアプリ作成開始。
https://api.slack.com/apps
アプリ作成後はアプリのスコープを設定します。
設定するのは以下です。
- channels:history
- channels:read
- chat:write
- groups:history
- reactions:read
- users:read
botユーザを作成します。
次にイベントAPIの設定をしていきますが、先にChallengeパラメータを返す処理を用意する必要があります。
Slackの設定はまた後で行います。
Pythonアプリの作成
WebフレームワークはFlaskを利用します。
Slackとの接続やAPI処理はslack-bolt
、slack-sdk
を使用します。
必要なパッケージは requirements.txt
に追加します。
slack-boltの指定でslack-sdkも一緒にインストールされます。
Flask>=1.0
slack-bolt
BOTのトークン等はApp Serviceのアプリケーション設定
で設定して処理の中で取得するようにします。
os.environ
で取得している箇所です。
import logging
import os
from slack_bolt import App
from slack_bolt.adapter.flask import SlackRequestHandler
from slack_sdk import WebClient
logging.basicConfig(level=logging.INFO)
client = WebClient(os.environ["SLACK_BOT_TOKEN"])
app = App()
@app.event("reaction_added")
def reaction_add(event, say):
emoji = event["reaction"]
user = event["user"]
item_user = event["item_user"]
channel = event["item"]["channel"]
ts = event["item"]["ts"]
if user == item_user:
return
# タイムスタンプでメッセージを特定
conversations_history = client.conversations_history(
channel=channel, oldest=ts, latest=ts, inclusive=1
)
messages = conversations_history.data["messages"]
# メッセージが取得出来ない場合、スレッドからメッセージを特定
if not messages:
group_history = client.conversations_replies(channel=channel, ts=ts)
messages = group_history.data["messages"]
reactions = messages[0]["reactions"]
target_reaction = os.environ["SLACK_REACTION_KEY"]
start_postmessage = False
reactions_text = ""
for reaction in reactions:
reactions_text += ":{}:{} ".format(reaction["name"], reaction["count"])
if reaction["name"] == target_reaction:
start_postmessage = True
if not start_postmessage:
return
userslist = client.users_list()
members = userslist["members"]
for member in members:
if member["id"] == user:
reaction_user = member["real_name"]
break
response = client.chat_postEphemeral(
channel=channel,
user=item_user,
text=f"{reaction_user} さんが以下のメッセージにリアクション :{emoji}: を追加しました\n\n"
+ messages[0]["text"]
+ f"\n{reactions_text}",
)
from flask import Flask, request
flask_app = Flask(__name__)
handler = SlackRequestHandler(app)
@flask_app.route("/slack/events", methods=["POST"])
def slack_events():
return handler.handle(request)
if __name__ == "__main__":
flask_app.run(host="0.0.0.0", port=3000)
Azure App Serviceの作成
WebサーバはAzureのApp Serviceを使用します。
ローカルGitリポジトリでデプロイするため、コード
を選択します。
資格情報を登録します。
Gitクローン作製時の認証に使用します。
アプリケーション設定
環境変数を定義します。
SLACK_REACTION_KEY
はリアクション通知対象のフラグを立てる絵文字名を入れます。
今回はstar
を入れてます。
SLACK_BOT_TOKEN
とSLACK_SIGNING_SECRET
はSlackのアプリ画面から取得します。
次にカスタムスタートアップコマンド
を設定します。
デフォルトはapp
というWSGIサーバが指定されています。
Pythonソースコード上はflask_app
としているのでこちらで起動するように設定します。
gunicorn --bind=0.0.0.0 --timeout 600 app:flask_app
App Serviceの設定が完了したらPythonアプリをデプロイします。
MSドキュメントの手順に従ってデプロイ設定をします。
Azure App Service へのローカル Git デプロイ
Slackアプリ設定
Event Subscriptions画面でChallengeパラメータを返すURLを入力し、Verified
になれば成功です。
今回のRequest URLは以下の赤枠 + /slack/events
です。
続いてリアクションされた時のイベントを連携するための設定をします。
Slackのチャンネルにアプリ追加
アプリを利用したいチャンネルの詳細画面を開きアプリを追加します。
これで冒頭のようにアプリ設定したチャンネルにおいてリアクションが通知されるようになります。
今回の例ですと自身の投稿にのリアクションがついているものは他の人が追加でリアクションした場合に通知されます。
投稿のリアクションが即座に確認したい場合に利用してみてください。
参考にさせていただいたサイトや記事
slackapi/bolt-python(サンプルプログラムもあります)
Slack Bolt for Python
Python で Slack API や Webhook を扱うなら公式 SDK(slack-sdk/slack-bolt)を使おう
Slack Python SDK でチャンネルにメッセージを投稿しよう
Azure App Service 向けの Linux Python アプリを構成する