mirror of
https://github.com/tiennm99/tiennm99bot.git
synced 2026-10-11 03:13:46 +00:00
Cards from /wordledaily and the 07:00 push now use the BotFather game wordle, and Play answers it. The module, commands and page route keep the wordledaily name.
118 lines
3.6 KiB
Go
118 lines
3.6 KiB
Go
package wordledaily
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/go-telegram/bot"
|
|
"github.com/go-telegram/bot/models"
|
|
|
|
"github.com/tiennm99/tiennm99bot/internal/modules/util/chathelper"
|
|
"github.com/tiennm99/tiennm99bot/internal/modules/util/subscription"
|
|
)
|
|
|
|
const (
|
|
msgChannel = "Wordle Daily can't be played in channels."
|
|
msgSendGameFail = "Couldn't send Wordle Daily. Try again later."
|
|
)
|
|
|
|
// handleCommand (/wordledaily) sends the BotFather game in the same chat and
|
|
// topic. No reply markup: Telegram then adds the Play button itself, which
|
|
// is the button a game message requires first.
|
|
func (s *service) handleCommand(ctx context.Context, b *bot.Bot, update *models.Update) error {
|
|
msg := update.Message
|
|
if msg == nil {
|
|
return nil
|
|
}
|
|
if msg.Chat.Type == models.ChatTypeChannel {
|
|
return chathelper.Reply(ctx, b, msg, msgChannel)
|
|
}
|
|
if !s.enabled() {
|
|
return chathelper.Reply(ctx, b, msg, msgDisabled)
|
|
}
|
|
if _, err := b.SendGame(ctx, &bot.SendGameParams{
|
|
ChatID: msg.Chat.ID,
|
|
MessageThreadID: topicOf(msg),
|
|
GameShorName: GameShortName, // the library's field name is misspelled
|
|
}); err != nil {
|
|
_ = chathelper.Reply(ctx, b, msg, msgSendGameFail)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// handleSubscribe (/wordledaily_subscribe) opts the chat topic into the
|
|
// 07:00 ICT push. Anyone in the chat may subscribe, like the other daily
|
|
// pushes.
|
|
func (s *service) handleSubscribe(ctx context.Context, b *bot.Bot, update *models.Update) error {
|
|
msg := update.Message
|
|
if msg == nil {
|
|
return nil
|
|
}
|
|
if msg.Chat.Type == models.ChatTypeChannel {
|
|
return chathelper.Reply(ctx, b, msg, msgChannel)
|
|
}
|
|
// The push cron exists only when the game is enabled, so a
|
|
// subscription would never be served.
|
|
if !s.enabled() {
|
|
return chathelper.Reply(ctx, b, msg, msgDisabled)
|
|
}
|
|
thread := topicOf(msg)
|
|
s.subscribersMu.Lock()
|
|
defer s.subscribersMu.Unlock()
|
|
added, err := subscription.Add(ctx, s.subscribers, msg.Chat.ID, thread)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
scope := scopeOf(thread)
|
|
if added {
|
|
return chathelper.Reply(ctx, b, msg,
|
|
"✅ Subscribed "+scope+" to Wordle Daily: a new puzzle and yesterday's group results every day at 07:00 ICT.\n"+
|
|
"If you block the bot, you'll be auto-unsubscribed on the next push.")
|
|
}
|
|
return chathelper.Reply(ctx, b, msg, "Already subscribed in "+scope+".")
|
|
}
|
|
|
|
// handleUnsubscribe (/wordledaily_unsubscribe) opts the chat topic out. It
|
|
// works while the game is disabled too, so a chat can always leave.
|
|
func (s *service) handleUnsubscribe(ctx context.Context, b *bot.Bot, update *models.Update) error {
|
|
msg := update.Message
|
|
if msg == nil {
|
|
return nil
|
|
}
|
|
if s.subscribers == nil {
|
|
return chathelper.Reply(ctx, b, msg, msgDisabled)
|
|
}
|
|
thread := topicOf(msg)
|
|
s.subscribersMu.Lock()
|
|
defer s.subscribersMu.Unlock()
|
|
removed, err := subscription.Remove(ctx, s.subscribers, msg.Chat.ID, thread)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
scope := scopeOf(thread)
|
|
if removed {
|
|
return chathelper.Reply(ctx, b, msg, "Unsubscribed "+scope+".")
|
|
}
|
|
return chathelper.Reply(ctx, b, msg, strings.ToUpper(scope[:1])+scope[1:]+" wasn't subscribed.")
|
|
}
|
|
|
|
// topicOf is the message's forum topic, or 0 for the whole chat. Telegram
|
|
// also gives a reply chain in an ordinary supergroup a thread id;
|
|
// IsTopicMessage marks a real topic. Plays key the group results the same
|
|
// way (playClaims), so a subscription made by replying still gets its
|
|
// chat's recap and streak.
|
|
func topicOf(msg *models.Message) int {
|
|
if !msg.IsTopicMessage {
|
|
return 0
|
|
}
|
|
return msg.MessageThreadID
|
|
}
|
|
|
|
func scopeOf(thread int) string {
|
|
if thread != 0 {
|
|
return "this topic"
|
|
}
|
|
return "this chat"
|
|
}
|