ウォッチャー
ウォッチャーは、アカウントが読めるすべてのチャットのすべてのメッセージを見ます。 コマンドだけではありません。
go
func (m *Mod) Watchers() []goroku.WatcherHandler {
return []goroku.WatcherHandler{
func(msg *goroku.Message) error {
if strings.Contains(strings.ToLower(msg.Text), "goroku") {
return msg.Reply("👋")
}
return nil
},
}
}WatcherHandler の形はコマンドハンドラと同じ func(msg *goroku.Message) error です。
フィルタリング
WatcherMetas で宣言的に絞り込みます。Watchers が返すスライスと位置で対応し ます。ディスパッチャがコードの実行前にフィルタを適用するので、各ウォッチャーの 先頭に if を置くより明快で、かつ安上がりです。
go
func (m *Mod) WatcherMetas() []goroku.CommandMeta {
return []goroku.CommandMeta{
{
OnlyGroups: true,
NoForwarded: true,
Contains: "goroku",
},
}
}CommandMeta と同じフィールドが使えます。
コスト
ウォッチャーはすべてのメッセージで動きます。遅い、あるいはおしゃべりな ウォッチャーはボット全体で体感されます。
- 自分の担当でないメッセージは即座に
nilを返してください。いちばん安い判定を 最初に。 - メッセージごとにデータベースへ書き込まないでください。まとめ書きの例は ストレージ にあります。
- ウォッチャーは上限付きプールで並行に動きます。プールが埋まると呼び出しは キューに入らず破棄されるので、遅いウォッチャーはメッセージの取りこぼしを招き ます。
go
func(msg *goroku.Message) error {
if msg.Out || msg.Text == "" {
return nil // 最も安い拒否を最初に
}
if !strings.Contains(msg.Text, "goroku") {
return nil
}
return m.handle(msg)
}panic
ウォッチャー内の panic は回復され、モジュール名とともにログに残ります。ボットは 動き続けます。
ウォッチャーかコマンドか
| 使うもの | 場面 |
|---|---|
| コマンド | 利用者が明示的に何かを求めている |
| ウォッチャー | 普通の会話に反応する |
ウォッチャーの中でプレフィックスを解析しているなら、本当に欲しいのはコマンドです。