summaryrefslogtreecommitdiffstats
path: root/internal/bot/bot.go
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-27 20:46:40 -0300
committerMurilo Ijanc <[email protected]>2026-07-27 20:46:40 -0300
commit83ce95cf10fd9e9d581362453c558239d37ae06e (patch)
treedcaf1e9258e1c55c2df19f6556e15c39eaf622bb /internal/bot/bot.go
parent3ca1d2c4370e8e79aba3940d5c8fe115960b75a8 (diff)
downloadtelegram-83ce95cf10fd9e9d581362453c558239d37ae06e.tar.gz
Name the municipality when the CEP does not existv0.2.0
Answering only "não encontrei" wastes the trip. A CEP that fails is almost never a random number: it is someone who knows the city and guessed the rest, most often at the "-000" that 957 municipalities never received. The API now names that municipality on the 404, so the reply names it too. It stays an answer to a failure. No 📮, no address block, and no CEP suggested from inside the range — the range is sparse (Areal's 118 CEPs span nearly five thousand numbers), so the reply gives the count and says so instead of letting the two ends read as a list of valid CEPs. cep.is/go v0.1.0 discards the 404 body, so internal/lookup reads it with one extra GET, on that path alone and never inside a retry. Everything that can go wrong there — a slow answer, broken JSON, a faixa naming no municipality — falls back to the reply the bot has always given. The wrapper goes away the day the library exposes the field.
Diffstat (limited to 'internal/bot/bot.go')
-rw-r--r--internal/bot/bot.go21
1 files changed, 20 insertions, 1 deletions
diff --git a/internal/bot/bot.go b/internal/bot/bot.go
index b29dc36..4abf02c 100644
--- a/internal/bot/bot.go
+++ b/internal/bot/bot.go
@@ -13,11 +13,16 @@ import (
cepis "cep.is/go"
+ "cep.is/telegrambot/internal/lookup"
"cep.is/telegrambot/internal/telegram"
)
// Lookups is the subset of the cep.is client this bot needs. Depending on the
// interface rather than the concrete client keeps the seam narrow and visible.
+//
+// A failure may be a [*lookup.NotFoundError], which still matches
+// cepis.ErrCEPNotFound and additionally names the municipality the CEP would
+// belong to; nothing here has to know that, because [ErrorMessage] reads it.
type Lookups interface {
Lookup(ctx context.Context, cep string) (*cepis.Address, error)
}
@@ -211,7 +216,7 @@ func (b *Bot) handleInline(ctx context.Context, query *telegram.InlineQuery) err
if err != nil {
b.logger.Info("inline lookup failed", slog.String("error", err.Error()))
return b.answerInline(ctx, query, []telegram.InlineQueryResult{
- b.inlineNotice(query, inlineErrorTitle(err), "Toque para enviar o motivo", ErrorMessage(err)),
+ b.inlineNotice(query, inlineErrorTitle(err), inlineErrorDescription(err), ErrorMessage(err)),
}, inlineCacheOther)
}
@@ -260,6 +265,20 @@ func inlineErrorTitle(err error) string {
return "Não consegui consultar agora"
}
+// inlineErrorDescription is the second line of the notice. Naming the
+// municipality here is what lets someone see, in the results list, that the
+// city they had in mind is right and the number is not — before sending
+// anything to the chat.
+//
+// Titles and descriptions are plain text for Telegram, so nothing here is
+// escaped: HTML applies to the message body alone.
+func inlineErrorDescription(err error) string {
+ if faixa := lookup.FaixaOf(err); faixa != nil {
+ return "Cairia em " + faixa.Place() + " — toque para ver"
+ }
+ return "Toque para enviar o motivo"
+}
+
// rateKey is the token bucket's key: the author when there is one, and the chat
// otherwise. A channel post has no author, and channel ids are negative, so the
// two spaces cannot collide.