4
2

More than 5 years have passed since last update.

ズンドコ節で学ぶ、ErrbotのFlow機能

Posted at

(まえがき)

Errbotで命令を実装する際に、命令となる関数が引数として受け取るのは、「メッセージ全体」及び「それをパースしたもの」に限られます。
つまり、標準の命令ではステートレスなやりとりのみをすることになります。

そんな中、ErrbotにはFlowという機能が存在し、contextを引き回すことによるステートフルなコミュニケーションができるようになります。
で、雑に覚えて手軽っぽいので「ズンドコ節」をflowで実装してみようと思います。

コード

動きの例

標準形

[@CHANGE_ME ➡ @errbot] >>> ズン
[@CHANGE_ME ➡ @errbot] [␍]
You are in the flow kiyoshi, you can continue with:
• ズン

[@CHANGE_ME ➡ @errbot] >>> ズン
[@CHANGE_ME ➡ @errbot] [␍]
You are in the flow kiyoshi, you can continue with:
• ズン
• ズンドコ

[@CHANGE_ME ➡ @errbot] >>> ズン
[@CHANGE_ME ➡ @errbot] [␍]
You are in the flow kiyoshi, you can continue with:
• ズン
• ズンドコ

[@CHANGE_ME ➡ @errbot] >>> ズンドコ
[@CHANGE_ME ➡ @errbot] [␍]
きよし!

数が足りない

[@CHANGE_ME ➡ @errbot] >>> ズン
[@CHANGE_ME ➡ @errbot] [␍]
You are in the flow kiyoshi, you can continue with:
• ズン

[@CHANGE_ME ➡ @errbot] >>> ズン
[@CHANGE_ME ➡ @errbot] [␍]
You are in the flow kiyoshi, you can continue with:
• ズン
• ズンドコ

[@CHANGE_ME ➡ @errbot] >>> ズンドコ
[@CHANGE_ME ➡ @errbot] [␍]
足りない!

数が多い

[@CHANGE_ME ➡ @errbot] >>> ズン
[@CHANGE_ME ➡ @errbot] [␍]
You are in the flow kiyoshi, you can continue with:
• ズン
You are in the flow kiyoshi, you can continue with:
• ズン
• ズンドコ

[@CHANGE_ME ➡ @errbot] >>> ズン
[@CHANGE_ME ➡ @errbot] [␍]
You are in the flow kiyoshi, you can continue with:
• ズン
• ズンドコ

[@CHANGE_ME ➡ @errbot] >>> ズン
[@CHANGE_ME ➡ @errbot] [␍]
You are in the flow kiyoshi, you can continue with:
• ズン
• ズンドコ

[@CHANGE_ME ➡ @errbot] >>> ズン
[@CHANGE_ME ➡ @errbot] [␍]
You are in the flow kiyoshi, you can continue with:
• ズン
• ズンドコ

[@CHANGE_ME ➡ @errbot] >>> ズンドコ
[@CHANGE_ME ➡ @errbot] [␍]
遅い!

ソースの中身

フローの方

Flowは***.flowファイルと、それが参照している**.pyファイルがセットになってます。
(例:kiyoshi.flowkiyoshi_flows.py)

kiyoshi_flow.png

  • 最初の「ズン」を検知して、フロー開始
  • フロー中は「ズン」を何回も受け付ける。途中から「ズンドコ」も受け付ける
  • 「ズンドコ」を受け付けたら終了

フロー自体にはbotのコマンドを持たないので、プラグイン自体も定義してあげる必要があります。

プラグインの方

kiyoshi.py
class Kiyoshi(BotPlugin):
    """
    Kiyoshi
    """
    @botmatch(r'^ズン$')
    def zun(self, msg, match):
        msg.ctx['zun'] = 1

    @botmatch(r'^ズン$', flow_only=True)
    def zun_re(self, msg, match):
        msg.ctx['zun'] += 1

    @botmatch(r'^ズンドコ$', flow_only=True)
    def kiyoshi(self, msg, match):
        if msg.ctx['zun'] == 3:
            msg.ctx['zun'] = -1
            return 'きよし!'
        if msg.ctx['zun'] < 3:
            return '足りない!'
        if msg.ctx['zun'] > 3:
            return '遅い!'

Messageオブジェクトにはctxというプロパティがあり、flow内で値の引き渡しができます。
最初の「ズン」で初期化、以降は「ズン」と喋るたびにカウンターが増えていきます。
適当なタイミングで、「ズンドコ」と喋ると、「ズン」の個数に応じてbotが反応します。

なお、デコレータ内にflow_only=Trueと宣言することで、通常の命令としては機能しなくなります。

応用例

  • ctxに設定情報を溜め込みつつ、セットアップを実行
    • Route53のレコードをまとめて登録とか
  • ctx上に状態を管理しつつ、会話しながら情報を取得
    • 出発駅と到着駅を設定しながら、中継地点を入れ替えたりしつつ時刻表検索

それでは皆さん、よいズンドコ節を

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2