(まえがき)
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.flow
とkiyoshi_flows.py
)
- 最初の「ズン」を検知して、フロー開始
- フロー中は「ズン」を何回も受け付ける。途中から「ズンドコ」も受け付ける
- 「ズンドコ」を受け付けたら終了
フロー自体にはbotのコマンドを持たないので、プラグイン自体も定義してあげる必要があります。
プラグインの方
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
上に状態を管理しつつ、会話しながら情報を取得- 出発駅と到着駅を設定しながら、中継地点を入れ替えたりしつつ時刻表検索
それでは皆さん、よいズンドコ節を