Skip to content

ウォッチャー

ウォッチャーは、アカウントが読めるすべてのチャットのすべてのメッセージを見ます。 コマンドだけではありません。

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 は回復され、モジュール名とともにログに残ります。ボットは 動き続けます。

ウォッチャーかコマンドか

使うもの場面
コマンド利用者が明示的に何かを求めている
ウォッチャー普通の会話に反応する

ウォッチャーの中でプレフィックスを解析しているなら、本当に欲しいのはコマンドです。

Released under the GNU AGPL v3 License.