mirror of
https://github.com/tiennm99/tiennm99bot.git
synced 2026-10-11 03:13:46 +00:00
feat(wordledaily): add the daily Wordle HTML5 game
/wordledaily sends a BotFather game card whose page plays one shared word per day, changing at 07:00 ICT. The server checks guesses, saves each player's board after every guess and keeps NYT-style stats. A win is reported with setGameScore, and in a group one live results message shows everyone's colour grids. /wordledaily_subscribe and /wordledaily_unsubscribe opt a chat or topic in to the 07:00 push: yesterday's recap, opening with the answer and the group's win streak, then today's card. The HTML5 game plumbing that noitu used is now shared in util/htmlgame, and the wordle word list and scoring live in wordle/wordlist.
This commit is contained in:
1 parent
871b4a1042
commit
c0231ceadf
56 files changed
+8013
-306
No files matched your search
@@ -107,6 +107,10 @@ func TestCommandDiscovery_AllPublicCommandsHaveSafeMetadata(t *testing.T) {
|
||||
"tth": "[target...]",
|
||||
"wheelofnames": "<option,...>",
|
||||
"wordle": "[word]",
|
||||
|
||||
"wordledaily": "",
|
||||
"wordledaily_subscribe": "",
|
||||
"wordledaily_unsubscribe": "",
|
||||
}
|
||||
|
||||
menu := botCommandMenu(reg)
|
||||
|
||||
@@ -42,6 +42,7 @@ import (
|
||||
"github.com/tiennm99/tiennm99bot/internal/modules/util"
|
||||
"github.com/tiennm99/tiennm99bot/internal/modules/weather"
|
||||
"github.com/tiennm99/tiennm99bot/internal/modules/wordle"
|
||||
"github.com/tiennm99/tiennm99bot/internal/modules/wordledaily"
|
||||
"github.com/tiennm99/tiennm99bot/internal/server"
|
||||
"github.com/tiennm99/tiennm99bot/internal/storage"
|
||||
"github.com/tiennm99/tiennm99bot/internal/systemstate"
|
||||
@@ -101,6 +102,7 @@ func factories() map[string]modules.Factory {
|
||||
"amlich": amlich.New,
|
||||
"monkeyd": monkeyd.New,
|
||||
"wordle": wordle.New,
|
||||
wordledaily.ShortName: wordledaily.New,
|
||||
noitu.ShortName: noitu.New,
|
||||
"loldle": loldle.New,
|
||||
lol.CollectionName: lol.New,
|
||||
|
||||
@@ -122,6 +122,30 @@ func TestFactoriesRegistersNoituDisabledByDefault(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// wordledaily is in the catalog and, with GAME_BASE_URL unset, registers its
|
||||
// commands and game but no public HTTP route and no daily push.
|
||||
func TestFactoriesRegistersWordleDailyDisabledByDefault(t *testing.T) {
|
||||
t.Setenv("GAME_BASE_URL", "")
|
||||
t.Setenv("WORDLEDAILY_GAME_SECRET", "")
|
||||
reg, err := modules.Build([]string{"wordledaily"}, factories(), storage.NewMemoryProvider(), modules.BuildOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("Build wordledaily: %v", err)
|
||||
}
|
||||
for _, name := range []string{"wordledaily", "wordledaily_subscribe", "wordledaily_unsubscribe"} {
|
||||
if _, ok := reg.AllCommands[name]; !ok {
|
||||
t.Fatalf("missing command %s", name)
|
||||
}
|
||||
}
|
||||
if routes := serverRoutes(reg); len(routes) != 0 {
|
||||
t.Fatalf("disabled game exposes routes: %+v", routes)
|
||||
}
|
||||
for _, m := range reg.Modules {
|
||||
if len(m.Crons) != 0 {
|
||||
t.Fatalf("disabled game registers crons: %+v", m.Crons)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// An empty MODULES loads every module, so a command name that collides with an
|
||||
// existing module surfaces here as a test failure rather than as a startup
|
||||
// crash on deploy.
|
||||
|
||||
Reference in new issue
Block a user