Fix duplicate leaderboard entries, add /version command, fix jail DNS
- db/db.go: Add write-time username sync in AddLog to prevent duplicate leaderboard entries when users change display names. Revert correlated subqueries back to GROUP BY user_id, username (simpler approach). - db/db.go: Early return in onMessageCreate if bot already reacted (prevents duplicate emoji reactions on Discord reconnection). - bot/bot.go: Add /version slash command with build version injection. - main.go: Add version variable with ldflags support. - Makefile: Add dns-fix, test, vet, build-native, pg-*, boot targets. Prepend test+vet to deploy pipeline. Add version ldflags to build. - db/migrations/002_fix_usernames.sql: One-time SQL to backfill old usernames. - scripts/fix-jail-dns.sh: Script to update jail resolv.conf from 8.8.8.8 to reachable nameservers (1.1.1.1, 9.9.9.9, 172.16.0.1). Signed-off-by: Blake Ridgway <blake@blakeridgway.com>
This commit is contained in:
22
bot/bot.go
22
bot/bot.go
@@ -25,19 +25,20 @@ type Bot struct {
|
||||
session *discordgo.Session
|
||||
db *db.DB
|
||||
guildID string
|
||||
version string
|
||||
|
||||
topicMu sync.Mutex
|
||||
topicTimer *time.Timer
|
||||
}
|
||||
|
||||
func New(token string, database *db.DB, guildID string) (*Bot, error) {
|
||||
func New(token string, database *db.DB, guildID, version string) (*Bot, error) {
|
||||
s, err := discordgo.New("Bot " + token)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create session: %w", err)
|
||||
}
|
||||
s.Identify.Intents = discordgo.IntentsGuilds | discordgo.IntentsGuildMessages | discordgo.IntentsMessageContent
|
||||
|
||||
b := &Bot{session: s, db: database, guildID: guildID}
|
||||
b := &Bot{session: s, db: database, guildID: guildID, version: version}
|
||||
s.AddHandler(b.onMessageCreate)
|
||||
s.AddHandler(b.onMessageDelete)
|
||||
s.AddHandler(b.onInteraction)
|
||||
@@ -115,6 +116,9 @@ func (b *Bot) RegisterCommands() error {
|
||||
{Name: "weeklyreport", Description: "Show distances logged this week"},
|
||||
{Name: "monthlyreport", Description: "Show distances logged this month"},
|
||||
|
||||
// ── Utility ──────────────────────────────────────────────────────────
|
||||
{Name: "version", Description: "Show the bot's build version"},
|
||||
|
||||
// ── Admin ────────────────────────────────────────────────────────────
|
||||
{Name: "addkm", Description: "[Admin] Manually add or subtract KM for a user",
|
||||
Options: []*discordgo.ApplicationCommandOption{
|
||||
@@ -230,6 +234,11 @@ func (b *Bot) onMessageCreate(s *discordgo.Session, m *discordgo.MessageCreate)
|
||||
if m.Author == nil || m.Author.Bot {
|
||||
return
|
||||
}
|
||||
// Skip messages the bot has already reacted to.
|
||||
// This prevents duplicate reactions from Discord reconnection event replays.
|
||||
if hasCheckmark(m.Message) {
|
||||
return
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
channelID, ok, err := b.db.GetSetting(ctx, m.GuildID, settingChannel)
|
||||
@@ -302,12 +311,21 @@ func (b *Bot) onInteraction(s *discordgo.Session, i *discordgo.InteractionCreate
|
||||
case "compare": b.handleCompare(ctx, s, i)
|
||||
case "weeklyreport": b.handleWeeklyReport(ctx, s, i)
|
||||
case "monthlyreport": b.handleMonthlyReport(ctx, s, i)
|
||||
case "version": b.handleVersion(ctx, s, i)
|
||||
case "addkm": b.handleAddKM(ctx, s, i)
|
||||
case "removelog": b.handleRemoveLog(ctx, s, i)
|
||||
case "audit": b.handleAudit(ctx, s, i)
|
||||
}
|
||||
}
|
||||
|
||||
// ── Version ───────────────────────────────────────────────────────────────────
|
||||
|
||||
func (b *Bot) handleVersion(ctx context.Context, s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||
respond(s, i, fmt.Sprintf("Cycling Bot version **%s**", b.version))
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ── Topic update ──────────────────────────────────────────────────────────────
|
||||
|
||||
func (b *Bot) scheduleTopicUpdate(guildID, channelID string) {
|
||||
|
||||
Reference in New Issue
Block a user