22 Commits
Author SHA1 Message Date
tiennm99 7008a57cf5 refactor!: rebrand miti99bot to tiennm99bot
BREAKING CHANGE: the Go module path is now github.com/tiennm99/tiennm99bot,
the default sticker pack is stickers_by_<bot username>, and the health body,
deploy DM, User-Agents and image names say tiennm99bot.
2026-10-07 15:14:02 +07:00
tiennm99 79104ef3d7 feat(config): resolve the bot username from BOT_USERNAME or getMe
The default sticker pack name and the lol User-Agent now follow whichever
bot runs the code, so a bot account change needs no code edit. The default
pack becomes miti99_by_<bot username>.
2026-10-07 15:08:08 +07:00
tiennm99 59c74de9a9 refactor(lol): move the subscriber list and daily push fan-out into a shared package
The subscriber store, the once-per-day claim, the terminal-error
classifier and the throttled fan-out with dead-chat pruning now live in
internal/modules/util/subscription so another module can offer an
opt-in daily push. Stored document shapes and keys are unchanged.
2026-10-02 13:06:07 +07:00
tiennm99 7cc0ead54f refactor: remove the unused gold spot-price chain and lol ErrEmptyResult 2026-09-30 14:20:38 +07:00
tiennm99 cf620a257e docs: fix stale code comments and add missing package docs
Correct comments that described the retired webhook transport, a removed
/cron route, the old KV store and wrapper types, and behaviour that has since
changed; drop plan and review labels; reword two startup log lines that
overstated or misnamed what they report.
2026-09-30 14:19:01 +07:00
tiennm99 749cd516a3 feat(lol): drop EMEA Masters and CBLOL from the schedule allowlist 2026-09-21 08:47:32 +07:00
tiennm99 58c42c312b feat(lol): replace schedule source with PandaScore API
Swap the lol module upstream from the lolesports.com gql persisted-query
client to PandaScore REST (/lol/matches, Bearer LOL_PANDASCORE_TOKEN,
free tier 1000 req/h). The gql transport broke whenever Riot redeployed
their frontend; PandaScore is a stable versioned contract.

ScheduleEvent, formatters, cron, and the bson cache shape are unchanged:
only the transport and response mapping moved. PandaScore league slugs
canonicalize to the existing major-league allowlist; results join to
opponents by team_id so reversed arrays cannot swap scores; outcomes are
declared only once upstream commits a winner, preserving the
score-pending rendering. A still-full final page now logs
lol_page_budget_exhausted and the live page budget covers 500 raw
matches per window.

Missing token short-circuits with lol_token_missing before any upstream
call; the 60-minute stale cache still covers outages. Document the new
env var and cancel the superseded Leaguepedia score-enrichment plan.
2026-08-05 17:39:20 +07:00
tiennm99 d50dd3f2f5 fix(lol): switch schedule fetch to lolesports.com gql persisted queries
Riot retired esports-api.lolesports.com and revoked its public x-api-key
(403 for everyone), so fetch schedules from the lolesports.com /api/gql
gateway instead using the web client's registered homeEvents operation.
The persisted-query ID comes from the frontend's operations manifest;
the package doc records how to refresh it when Riot rotates it, and a
rotated ID logs lol_persisted_query_rotated instead of caching an empty
schedule. Date windows are padded a day each side and filtered to exact
instants locally because the gateway's date params have unspecified
timezone semantics.
2026-08-05 16:29:25 +07:00
tiennm99 2f69ce2f34 fix(lol): omit score when a finished match has none published
lolesports drives event.state off the broadcast timeline but fills
result.outcome and result.gameWins from a separate per-game ingestion
path. A match therefore reads as "completed" for hours before gaining a
score, and in that window every team carries {"outcome": null,
"gameWins": 0}.

The renderer used `Result != nil` as its has-a-score test, which cannot
catch this: the result object is present, only its contents are empty.
The absent gameWins fell through to Go's zero value and printed as a
literal 0, so an unscored series was reported as a definitive draw
("MKOI 0-0 KC") with neither side bolded.

Gate the score on a declared outcome instead, and render unscored
finished matches as the matchup alone with a pending marker. An outcome
on either side is enough to trust the score - it proves the ingestion
ran. inProgress keeps rendering 0-0, which is truthful for a live series
that has not resolved its first game.

Also collapses the score extraction both branches duplicated into
shared helpers.
2026-07-26 09:16:39 +07:00
tiennm99 a211b7f8b7 fix(commands): remove examples from command discovery 2026-07-21 13:52:53 +07:00
tiennm99 f5ba9d4032 feat(commands): improve discovery and normalize parameters 2026-07-21 11:45:20 +07:00
tiennm99 3316eec74c test: provision MongoDB 8 with Testcontainers 2026-07-21 09:39:06 +07:00
tiennm99 194caf17eb fix(lol): rename next week command 2026-07-06 20:46:10 +07:00
tiennm99 00a5ff1c0b feat(lol): add tomorrow and next-week schedules 2026-07-06 20:20:07 +07:00
tiennm99 a6a24ba4c9 feat(lol): add EWC schedule support 2026-07-06 09:40:01 +07:00
tiennm99 beebddf1d8 refactor(lol): remove match cache cleanup logic 2026-07-01 16:53:11 +07:00
tiennm99 275c83b8a6 feat(lol): make match cache fallback-only 2026-07-01 16:41:59 +07:00
tiennm99 2fb10ff632 refactor: remove completed migration logic 2026-07-01 16:20:30 +07:00
tiennm99 b0b4321fa1 feat(lol): expire match cache 2026-07-01 13:40:37 +07:00
tiennm99 e6d5bc3cc9 feat: refine command names and behavior 2026-07-01 13:19:42 +07:00
tiennm99 5254ab4c8e refactor: remove completed startup migrations 2026-07-01 11:42:59 +07:00
tiennm99 ccaa34336d feat: rename lol schedule module 2026-07-01 10:38:49 +07:00