Posted at
pythonDay 10

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

More than 1 year has passed since last update.


(まえがき)

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

つまり、標準の命令ではステートレスなやりとりのみをすることになります。

そんな中、ErrbotにはFlowという機能が存在し、contextを引き回すことによるステートフルなコミュニケーションができるようになります。

で、雑に覚えて手軽っぽいので「ズンドコ節」をflowで実装してみようと思います。


コード

https://gist.github.com/attakei/0f6b3d2cdab52b6c63faa1f9f02e1c42


動きの例


標準形

[@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上に状態を管理しつつ、会話しながら情報を取得


    • 出発駅と到着駅を設定しながら、中継地点を入れ替えたりしつつ時刻表検索



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