Вотчеры
Вотчер видит каждое сообщение в каждом чате, доступном аккаунту, — не только команды.
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)
}Паники
Паника в вотчере перехватывается и логируется с именем вашего модуля; бот продолжает работать.
Вотчер или команда?
| Что использовать | Когда |
|---|---|
| Команду | Пользователь явно о чём-то просит |
| Вотчер | Вы реагируете на обычный разговор |
Если внутри вотчера вы разбираете префикс — вам нужна команда.