はじめに
Slackでslackbotを利用した自作botを運用しています。
用途別にチャンネルを作成しており、botの各プラグインはそれぞれ専用のチャンネルで実行する、という運用にしております。
しかし、チャンネルの用途とは異なるプラグインを実行してしまうというヒューマンエラーが度々起きており、なんとかしたいと考えていました。
そこで、特定のチャンネルでのみ処理を実行する機構をbotに実装しました。
※本記事にはslackbotの使用方法は記載しておりません
検証環境
Python 3.6.1
slackbot 0.5.3
デコレータによる処理を実行するチャンネルの指定
実行を許可するチャンネルを引数にとるデコレータを作ります。
import functools
def in_channel(allow_channel):
def decorator(func):
@functools.wraps(func)
def wrapper(message, *args, **kargs):
channel_id = message.body['channel']
channel_info = message.channel._client.channels[channel_id]
channel = channel_info['name']
if allow_channel not in (channel, channel_id):
message.reply("Please post in #{}".format(allow_channel))
return
return func(message, *args, **kargs)
return wrapper
return decorator
上記コードでは、引数はチャンネル名/チャンネルIDのどちらでもOKです。
そして、特定のチャンネルでのみ実行したい関数にデコレータを適用します。
私は先ほどのコードをutils.py
というファイルに記述しています。
from slackbot.bot import listen_to
from .utils import in_channel
@listen_to("^強い$")
@in_channel("playground")
def tsuyoi(message):
message.reply("強くない:white_frowning_face:")
上記コードでは、 playground というチャンネルでのみ、関数tsuyoi
が実行するように設定しています。
注意する点
@in_channel
はslackbotのデコレータ(上記例では@listen_to
)よりも下に記述してください。
順番が逆だと@listen_to
の方が先に適用されます。その場合、メッセージが投稿されてしまうことを確認しています。
おわりに
デコレータでチャンネルを指定することで、用途が異なるチャンネルでプラグインを実行してしまうミスを防ぐことができました。
課題としては、(私の運用では問題ないのですが)チャンネルを1つしか指定できない点です。
複数のチャンネルを指定したい場合は、上記コードを少しいじる必要があります。
参考にしたページ
Limit slackbot responce to certain channel · Issue #152 · lins05/slackbot · GitHub
Python デコレータ再入門 ~デコレータは種類別に覚えよう~ - Qiita