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)))
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if update.Message == nil {
|
||||
if update.Message == nil || !hasCommandEntity(update.Message.Entities) {
|
||||
return
|
||||
}
|
||||
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.
|
||||
func (h *botHandlers) reply(ctx context.Context, b *bot.Bot, update *models.Update, text string) {
|
||||
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) {
|
||||
svc := testService(t, Rota{}, nil)
|
||||
b, sent := newTestBot(t)
|
||||
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"))
|
||||
|
||||
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)
|
||||
if got := sent(); len(got) != 0 {
|
||||
t.Fatalf("plain text should not reply, got %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue