PythonでSlackbotを作る(2)

現在、弊社でもSlackを試験的に利用しているのですが、RTM APIを使えばローカルでもbotが作成できることを知ったのでPythonで作ってみようという記事です。
今回は第2回目です。

前回でSlackbotが稼働する環境はできたので、今回は独自機能をプラグインを作成してみましょう。

プラグイン

今回の記事で利用しているPythonのSlackbotライブラリはプラグイン機構が備わっています。その機構を用いて独自にDMやBotが参加しているチャンネル(グループ含む)内でのメンションや投稿内の特定の言葉に反応する機能を実装することができます。

まずは前回作成したbot用のディレクトリにプラグイン配置用ディレクトリを作成します。

$ cd bossan/
$ mkdir plugins
$ touch plugins/__init__.py

Slackbotのプラグインとして読み込ませるディレクトリはモジュールである必要があるので「__init__.py」が必要になります。これは空ファイルでいいので作成しておきます。さて、プラグイン配置ディレクトリを作成したら、実際にプラグインスクリプトを作成しましょう。

$ vi plugins/bossan_mention.py
from slackbot.bot import respond_to

@respond_to('疲れた')
@respond_to('つかれた')
def cheer(message):
    message.reply('ファイト!')

関数”cheer()”に対して、”respond_to”というデコレータが付与されています。

A function decorated with respond_to is called when a message matching the pattern is sent to the bot (direct message or @botname in a channel/group chat)

lins05/slackbot: A chat bot for Slack (https://slack.com).

“respond_to”デコレータの引数にマッチするキーワードを指定することでプラグインロード時に関数がBotに対するメンションに反応するように登録されます。キーワードの指定は正規表現で行うことも可能です。また、今回のサンプルのようにデコレータを複数付与することで複数キーワードに対応させることもできます。

最後に、プラグインロードが行われるように“slackbot_settings.py”に以下を追記します。

PLUGINS = [
    'plugins',
]

Slackbotを起動して、メンションを送ってみましょう。

$ python3 run.py

08_slack

一匹余計なBotが返信してきてますが、今回作成したBotが意図した通りに反応しているのがわかります。

もう一つプラグインスクリプトを作成しましょう。

$ vi plugins/bossan_listen.py
from slackbot.bot import listen_to

@listen_to('あきらめたら')
@listen_to('諦めたら')
def anzai(message):
    message.send('そこで試合終了ですよ。')

@listen_to('いいですか')
def reaction(message):
    message.react('+1')

関数”anzai()”と”reaction()”に対して、”listen_to”というデコレータが付与されています。

A function decorated with listen_to is called when a message matching the pattern is sent on a channel/group chat (not directly sent to the bot)

lins05/slackbot: A chat bot for Slack (https://slack.com).

“listen_to”デコレータの引数にマッチする言葉を指定することでプラグインロード時に関数がBotが参加しているチャンネルへの投稿に反応するように登録されます。”respond_to”デコレータと同じく指定は正規表現で行うことが可能です。

プラグインの読込は起動時のみ行われるので、Slackbotを再起動してチャンネルに投稿してみましょう。

$ python3 run.py

09_slack

またしても余計なBotが(しかも先に)反応していますが、今回も作成したBotが意図した通りに反応しているのがわかります。

なお、今回はあえてデコレータ毎にスクリプトを分けましたが、もちろん同じファイル内で定義しても問題はありません。

最後に、今回のサンプルでは各関数内で以下のメソッドを使っています。

  • message.reply()
  • message.send()
  • message.react()

「reply()」はキーワードとマッチした投稿の送信相手へのリプライとしてメッセージを送信します。「send()」は投稿されたチャンネルに対する投稿としてメッセージを送信します。「react()」はマッチした投稿に対してリアクションを取ります。この時指定する絵文字は「:」で囲わないので注意しましょう。

ということで、これでキーワード検出契機でのBotは作成できました。簡単ですよね。
あれ?でも…これって元々存在するBotとあんまり変わらないんじゃ…。い、いやだなぁ、そんな訳ないじゃないですかー。ということで、次回はBot自らメッセージ送信するサンプルを作ってみましょう。

6 Comments

  1. 初めまして。ちょうどslackでのbot制作をしようと思っていたので大変参考になりました。pluginの追加についてですが、slackbot_setting.pyにpluginのモジュールを追記する部分も説明されていればより良いのではと思ったので投稿させて頂きました。

  2. とある大学で自然対話の研究を行っている者です。
    ちょうどPythonもSlackも使いたてなので、とてもありがたい記事です、勉強の参考にしています。

    どうもmention.pyが上手く動かないので困っていたら、どうやら原因はhalotasoさんがおっしゃっていたpulginのモジュール追加が原因だと判明しました。
    ただ、gitHubを参考にしても上手くモジュールが追加できず難儀しております。その点の補足なども記事にしていただければ大変ありがたいなと、厚かましいお願いですがどうか宜しくお願いします。

  3. コメントありがとうございます。記事中のサンプル実行の場合のプラグイン設定について追記しましたので参考になれば幸いです(PLUGINSにモジュールのパスを追記するのですが、公式の説明は”mybot/plugins”をプラグインディレクトリとした例なので”mybot.plugins”となっています)。

  4. 返答・追記ありがとうございます。
    参考になりました! 無事botのほうも動きました。
    公式の説明をもっとまともに読むことにします…何はともあれ、細かい説明ありがとうございました。

  5. このサイトを参考にして、slackのbotを作って動かして見たのですが、数分立つと、何かの拍子に以下のようなエラーが出力されます。
    どう対処すればいいのでしょうか…知恵をお貸しいただけると幸いです

    Exception in websocket_safe_read: [Errno 54] Connection reset by peer
    lost websocket connection, try to reconnect now
    reconnected to slack rtm websocket

  6. コメントありがとうございます。このメッセージは利用しているPythonのSlackbotライブラリ「lins05/slackbot」が出力しているのですが、ソースを見た限りWebSocketが切断された時と、再接続した時の出力のようです。(再接続が成功しているので)動作上問題はない出力かと思いますが、気になるのでしたら標準パッケージのloggingのwaringで出力されているので、レベルをerrorにすれば出力は停止できるかと思います(すいませんそこは色々と調べてみて下さい)。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*