fix: only answer unknown /commands, not ordinary messages
The default handler fired for every update the command matchers didn't claim, so plain chatter, service messages, media, and replies to the bot all drew a "Nieznana komenda" response — spammy in group chats. Gate the fallback on a leading bot_command entity so only real (unrecognized) commands get the help reply.
This commit is contained in:
parent
41980e4f6f
commit
5a10eda3e1
19
telegram.go
19
telegram.go
|
|
@ -156,14 +156,29 @@ func (h *botHandlers) sync(ctx context.Context, b *bot.Bot, update *models.Updat
|
||||||
"Zsynchronizowano: %d tygodni, %d osób.", len(rota.Weeks), len(rota.People)))
|
"Zsynchronizowano: %d tygodni, %d osób.", len(rota.Weeks), len(rota.People)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// unknown is the fallback for any text the bot does not recognize.
|
// unknown is the fallback for any update the command matchers don't claim. It
|
||||||
|
// only answers messages that actually carry a bot_command entity (a mistyped or
|
||||||
|
// unsupported /command); plain chatter, service messages (joins/pins), media,
|
||||||
|
// and replies to the bot fall through here too but get no response, so the bot
|
||||||
|
// stays quiet in groups instead of "Nieznana komenda"-spamming every message.
|
||||||
func (h *botHandlers) unknown(ctx context.Context, b *bot.Bot, update *models.Update) {
|
func (h *botHandlers) unknown(ctx context.Context, b *bot.Bot, update *models.Update) {
|
||||||
if update.Message == nil {
|
if update.Message == nil || !hasCommandEntity(update.Message.Entities) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
h.reply(ctx, b, update, "Nieznana komenda. Użyj /kto_sprzata lub /sync.")
|
h.reply(ctx, b, update, "Nieznana komenda. Użyj /kto_sprzata lub /sync.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hasCommandEntity reports whether the message carries any bot_command entity,
|
||||||
|
// i.e. the user typed a /command (recognized or not) rather than plain text.
|
||||||
|
func hasCommandEntity(entities []models.MessageEntity) bool {
|
||||||
|
for _, e := range entities {
|
||||||
|
if e.Type == models.MessageEntityTypeBotCommand {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// reply sends text back to the originating chat, logging send failures.
|
// reply sends text back to the originating chat, logging send failures.
|
||||||
func (h *botHandlers) reply(ctx context.Context, b *bot.Bot, update *models.Update, text string) {
|
func (h *botHandlers) reply(ctx context.Context, b *bot.Bot, update *models.Update, text string) {
|
||||||
if update.Message == nil {
|
if update.Message == nil {
|
||||||
|
|
|
||||||
|
|
@ -293,18 +293,39 @@ func TestSyncReplyFailure(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestUnknownReply checks the fallback handler answers unrecognized text.
|
// TestUnknownReply checks the fallback answers an unrecognized /command (a
|
||||||
|
// message carrying a bot_command entity that no matcher claimed).
|
||||||
func TestUnknownReply(t *testing.T) {
|
func TestUnknownReply(t *testing.T) {
|
||||||
svc := testService(t, Rota{}, nil)
|
svc := testService(t, Rota{}, nil)
|
||||||
b, sent := newTestBot(t)
|
b, sent := newTestBot(t)
|
||||||
h := &botHandlers{svc: svc, now: fixedNow()}
|
h := &botHandlers{svc: svc, now: fixedNow()}
|
||||||
|
|
||||||
|
cmd := &models.Update{Message: &models.Message{
|
||||||
|
Text: "/foo",
|
||||||
|
Chat: models.Chat{ID: 123},
|
||||||
|
Entities: cmdEntity("/foo"),
|
||||||
|
}}
|
||||||
|
h.unknown(context.Background(), b, cmd)
|
||||||
|
|
||||||
|
got := sent()
|
||||||
|
want := "Nieznana komenda. Użyj /kto_sprzata lub /sync."
|
||||||
|
if len(got) != 1 || got[0] != want {
|
||||||
|
t.Fatalf("reply = %v, want [%q]", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestUnknownPlainTextIgnored checks ordinary chatter (no bot_command entity)
|
||||||
|
// gets no reply, so the bot doesn't spam "Nieznana komenda" on every group
|
||||||
|
// message, service notice, or reply to its own messages.
|
||||||
|
func TestUnknownPlainTextIgnored(t *testing.T) {
|
||||||
|
svc := testService(t, Rota{}, nil)
|
||||||
|
b, sent := newTestBot(t)
|
||||||
|
h := &botHandlers{svc: svc, now: fixedNow()}
|
||||||
|
|
||||||
h.unknown(context.Background(), b, updateMsg(123, "siema"))
|
h.unknown(context.Background(), b, updateMsg(123, "siema"))
|
||||||
|
|
||||||
got := sent()
|
if got := sent(); len(got) != 0 {
|
||||||
want := "Nieznana komenda. Użyj /kto_sprzata lub /sync."
|
t.Fatalf("plain text should not reply, got %v", got)
|
||||||
if len(got) != 1 || got[0] != want {
|
|
||||||
t.Fatalf("reply = %v, want [%q]", got, want)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue