本サイトで紹介しているSlackbotライブラリ
では、Bot同士のメンションが発生してしまう場合があるのでこれを回避する方法を説明します。

Botを同じチャンネルに招待しているとBot同士で会話が発生してしまう可能性があります。Bot同士の会話が発生すると無限ループに入ったり意図しない処理が発生したりなどいいことは特にありません。Bot同士で会話が発生しないように注意しながら開発する必要があります。

無限ループって怖くね

この前やってしまったのですが、エラーが発生したことを起点にしてBot同士の会話が発生、無限ループに入りました。

無限ループって怖くね?

デフォルトリプライで延々と会話を続けます。
こうなると片方を停止するしかありません。

無限ループを避けるためには

無限ループを避ける為には以下の3つを意識して開発する必要があります。

・メンションに注意する
・正規表現を細かく設定する
・デフォルトリプライが返された時の応答を用意しておく

一つずつ説明していきます。

メンションに注意する

ライブラリに用意されているBotの応答のデコレータとして「@respond_to」「@listen_to」の2種類があります。

「@respond_to」はメンションされたメッセージに対して応答を返します。
「@listen_to」はメンションされたかどうかに関係なく全てのメッセージに応答を返します。

「@listen_to」を多用してしまうとBotが反応してしまう機会が増える為に思わぬ誤作動が発動しやすいです。
できる限り「@respond_to」の方を使うようにしましょう。

逆にBotから応答する時はメンションをしない方が良いです。
メンションのない「send()」メソッドかリアクションを返す「react()」メソッドを使うようにしましょう。

正規表現を細かく設定する

Botの応答は正規表現で定義しますが、大雑把な言葉で応答を作成してしまうとBotが反応する機会が多くなり誤射も発生しやすいです。
正規表現による指定は必ず行いましょう。

最低限の設定として開始(^)と終了($)の位置は明確にしておきましょう。

>>Pythonと正規表現

デフォルトリプライが返された時の応答を用意しておく

デフォルトリプライは登録されていない言葉に対して応答するメッセージです。このメッセージはリプライで応答する為、一度Botへのデフォルトリプライが発生すると上記画像のようにBot同士で返しあって無限ループとなります。

デフォルトリプライの対応をしておくだけで無限ループの可能性はグッと減ります。

# 他のBotからデフォルトメッセージが来た時の為のメッセージ
@respond_to(slackbot_settings.DEFAULT_REPLY)
def react_default(message):
    # OKリアクションを返す
    message.react('ok')

◆実行結果
デフォルトリプライを受け取った時にリアクションを返す

また、デフォルトリプライ自体の処理を変えることもできます。

from slackbot.bot import default_reply

# デフォルトリプライの応答を変更する
@default_reply
def my_default_handler(message):
    # デフォルトリプライをsendに変更する
    message.send(slackbot_settings.DEFAULT_REPLY)

◆実行結果
デフォルトリプライの変更

どちらか片方があれば十分なのでやりやすい方をやっておきましょう。

以上、Slackbot同士を反応させない方法についてでした。

まとめ

同じチャンネルで複数のBotを使っていると意図しない反応がおき、最悪無限ループに陥ります。
システムが拡大してくると複数のBotを一つのチャンネルで使う機会も増えてくることあるのでしっかりと検討しておくことが大切です。

今回は以下の3つの方法について紹介しました。

・メンションに注意する
・正規表現を細かく設定する
・デフォルトリプライが返された時の応答を用意しておく

対応できるものから対応して少しずつBotを改善していきましょう。

Slackbot+PythonまとめTOP>>Slackbotの作り方マニュアル〜Python編〜