fix(wc): send silent daily push at midnight ict

This commit is contained in:
2026-06-30 08:56:01 +07:00
parent 564b6635d4
commit 0d866cb7a0
7 changed files with 17 additions and 16 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ Atlas via long polling and an in-process cron scheduler.
| `wordle` | Daily Wordle game |
| `loldle` | League-of-Legends "guess the champion" |
| `lolschedule` | Pro-match schedule + daily push |
| `wc` | World Cup schedule + daily push |
| `wc` | World Cup schedule + silent daily push |
| `stock` | VN-stocks paper trading |
| `gold` | Gold paper trading (opt-in; primary VNAppMob SJC buy/sell VND/luong, fallback spot XAU) |
| `coin` | Crypto paper trading in USD (Binance -> Coinbase -> CoinGecko price fallback) |
+7 -6
View File
@@ -16,8 +16,8 @@ import (
const dailyPushCronName = "wc_daily_push"
// 01:00 UTC is 08:00 ICT.
const dailyPushSchedule = "0 1 * * *"
// 17:00 UTC is 00:00 UTC+7 (ICT).
const dailyPushSchedule = "0 17 * * *"
const lastPushDateKey = "daily_push:last_date"
@@ -114,10 +114,11 @@ func runDailyPush(ctx context.Context, s *state, sender messageSender) error {
}
}
if _, err := sender.SendMessage(ctx, &bot.SendMessageParams{
ChatID: sub.ChatID,
MessageThreadID: sub.ThreadID,
Text: text,
ParseMode: models.ParseModeHTML,
ChatID: sub.ChatID,
MessageThreadID: sub.ThreadID,
Text: text,
ParseMode: models.ParseModeHTML,
DisableNotification: true,
}); err != nil {
log.Warn("wc daily push send failed", "chat", sub.ChatID, "thread", sub.ThreadID, "err", err)
failed++
+3 -3
View File
@@ -81,8 +81,8 @@ func TestRunDailyPush_SendsAndIsIdempotent(t *testing.T) {
t.Fatalf("calls = %d, want 1", len(sender.calls))
}
call := sender.calls[0]
if call.MessageThreadID != 7 || call.ParseMode != models.ParseModeHTML {
t.Fatalf("call = %+v, want thread 7 HTML", call)
if call.MessageThreadID != 7 || call.ParseMode != models.ParseModeHTML || !call.DisableNotification {
t.Fatalf("call = %+v, want thread 7 HTML silent notification", call)
}
}
@@ -107,7 +107,7 @@ func TestRunDailyPush_PrunesDeadChat(t *testing.T) {
func TestDailyPushCronRegistrationAndNilBot(t *testing.T) {
s := newTestState()
c := s.dailyPushCron()
if c.Name != dailyPushCronName || c.Schedule != dailyPushSchedule || c.Handler == nil {
if c.Name != dailyPushCronName || c.Schedule != "0 17 * * *" || c.Handler == nil {
t.Fatalf("cron = %+v", c)
}
err := s.dailyPushHandler(context.Background(), modules.Deps{Store: storage.NewMemoryProvider().Collection("wc")})
+1 -1
View File
@@ -97,7 +97,7 @@ func (s *state) handleSubscribe(ctx context.Context, b *bot.Bot, update *models.
}
if added {
return chathelper.Reply(ctx, b, msg,
"Subscribed. You'll get today's World Cup schedule at 08:00 ICT.\n"+
"Subscribed. You'll get today's World Cup schedule at 00:00 UTC+7.\n"+
"If you block the bot, you'll be auto-unsubscribed on the next push.")
}
return chathelper.Reply(ctx, b, msg, "Already subscribed.")
+2 -2
View File
@@ -79,8 +79,8 @@ func TestHandleSchedule_BadDateInput(t *testing.T) {
func TestHandleSubscribe_AddsAndIsIdempotent(t *testing.T) {
rb, store := installWC(t, sampleMatchesBody, fakeNow)
rb.Bot.ProcessUpdate(context.Background(), testutil.NewPrivateMessage(7, "/wc_subscribe"))
if got := rb.LastSent().Text(); !strings.Contains(got, "Subscribed") {
t.Fatalf("first reply = %q, want subscribed", got)
if got := rb.LastSent().Text(); !strings.Contains(got, "Subscribed") || !strings.Contains(got, "00:00 UTC+7") {
t.Fatalf("first reply = %q, want subscribed with 00:00 UTC+7", got)
}
rb.Reset()
rb.Bot.ProcessUpdate(context.Background(), testutil.NewPrivateMessage(7, "/wc_subscribe"))
+1 -1
View File
@@ -36,7 +36,7 @@ func New(deps modules.Deps) modules.Module {
{
Name: "wc_subscribe",
Visibility: modules.VisibilityPublic,
Description: "Get the daily World Cup schedule digest at 08:00 ICT",
Description: "Get the daily World Cup schedule digest at 00:00 UTC+7",
Handler: s.handleSubscribe,
},
{
+2 -2
View File
@@ -18,7 +18,7 @@ func TestNewRegistersExpectedCommandsAndCron(t *testing.T) {
t.Fatalf("missing command %s", name)
}
}
if len(mod.Crons) != 1 || mod.Crons[0].Name != dailyPushCronName {
t.Fatalf("crons = %+v, want %s", mod.Crons, dailyPushCronName)
if len(mod.Crons) != 1 || mod.Crons[0].Name != dailyPushCronName || mod.Crons[0].Schedule != "0 17 * * *" {
t.Fatalf("crons = %+v, want %s at 00:00 UTC+7", mod.Crons, dailyPushCronName)
}
}