Watcher
Ein Watcher sieht jede Nachricht in jedem Chat, den das Konto lesen kann — nicht nur Befehle.
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 hat dieselbe Form wie ein Befehls-Handler: func(msg *goroku.Message) error.
Filtern
Filtere deklarativ mit WatcherMetas, positionsweise zum Slice aus Watchers zugeordnet. Der Dispatcher wendet den Filter an, bevor dein Code läuft — das ist klarer und billiger als ein if am Anfang jedes Watchers:
go
func (m *Mod) WatcherMetas() []goroku.CommandMeta {
return []goroku.CommandMeta{
{
OnlyGroups: true,
NoForwarded: true,
Contains: "goroku",
},
}
}Es stehen dieselben Felder wie bei CommandMeta zur Verfügung.
Kosten
Watcher laufen bei jeder Nachricht. Ein langsamer oder gesprächiger Watcher ist im ganzen Bot spürbar.
- Gib sofort
nilzurück, wenn die Nachricht nicht deine ist. Die billigste Prüfung zuerst. - Schreibe nicht pro Nachricht in die Datenbank — siehe das Sammel-Beispiel unter Speicher.
- Watcher laufen nebenläufig in einem begrenzten Pool. Ist der Pool voll, werden Aufrufe verworfen statt eingereiht — ein langsamer Watcher kostet dich also Nachrichten.
go
func(msg *goroku.Message) error {
if msg.Out || msg.Text == "" {
return nil // die billigstmögliche Ablehnung zuerst
}
if !strings.Contains(msg.Text, "goroku") {
return nil
}
return m.handle(msg)
}Panics
Ein Panic in einem Watcher wird abgefangen und mit deinem Modulnamen geloggt; der Bot läuft weiter.
Watcher oder Befehl?
| Nimm | Wenn |
|---|---|
| Befehl | Der Nutzer verlangt ausdrücklich etwas |
| Watcher | Du reagierst auf gewöhnliche Unterhaltung |
Wenn du im Watcher ein Präfix parst, willst du eigentlich einen Befehl.