Merge pull request #6 from the-programmers-hangout/feat/add-better-debugging

Feat/add better debugging
This commit is contained in:
Khinshan Khan
2025-04-01 10:25:54 -04:00
committed by GitHub
4 changed files with 88 additions and 3 deletions
+4
View File
@@ -12,3 +12,7 @@ DELETE_CONSPIRACY_DELAY=3s
# Probability of sending a conspiracy message (0.0 to 1.0)
CONSPIRACY_PROBABILITY=0.4
# Optional indices for resuming bot
# PRAISE_INDEX=0
# CONSPIRACY_INDEX=0
+1 -1
View File
@@ -15,7 +15,7 @@ MAKEFLAGS += --no-builtin-rules
# VARIABLES
GIT_COMMIT = $(shell git rev-parse --verify HEAD)
BUILD_DATE = $(shell date +%Y.%m.%d.%H%M%S)
BUILD_DATE = $(shell date +%Y.%m.%d.%H%M%S)
GOSERVICES = $(sort $(notdir $(realpath $(dir $(wildcard ./cmd/*/main.go)))))
+6 -1
View File
@@ -38,7 +38,12 @@ Create a `.env` file in the root of your project with the following keys:
- `CONSPIRACY_PROBABILITY`: Probability (from 0.0 to 1.0) that a conspiracy message is sent after a praise. Eg, 0.4 =
40% chance.
You can view the [.env-sample](./.env-sample) as an example completed template.
Optional:
- `PRAISE_INDEX`: Index of the [praises.json](./cmd/bot/praises.json) to start from, useful when resuming bot.
- `CONSPIRACY_INDEX`: Index of the [conspiracies.json](./cmd/bot/conspiracies.json) to start from, useful when resuming
bot.
You can view the [.env.sample](./.env.sample) as an example completed template.
### Install + Run
+77 -1
View File
@@ -16,6 +16,14 @@ import (
"github.com/joho/godotenv"
)
var (
// CommitHash and BuildData get replaced during build with the commit hash and time of build.
CommitHash string
BuildDate string
// StartTime is reset every time the application is restarted
StartTime = time.Now()
)
// Embed JSON files at build time
//go:embed praises.json
@@ -63,13 +71,31 @@ func main() {
log.Fatalf("[x] Error creating Discord session: %v", err)
}
// Open WebSocket connection
dg.AddHandler(readyHandler)
interactionHandlers := make(map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate))
for _, interaction := range interactions {
interactionHandlers[interaction.command.Name] = interaction.handler
}
dg.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
if h, ok := interactionHandlers[i.ApplicationCommandData().Name]; ok {
h(s, i)
}
})
// Open WebSocket connection
if err := dg.Open(); err != nil {
log.Fatalf("[x] Error opening connection: %v", err)
}
defer dg.Close()
for _, entry := range interactions {
created, err := dg.ApplicationCommandCreate(dg.State.User.ID, "", entry.command)
if err != nil {
log.Fatalf("Cannot create '%s' command: %v", entry.command.Name, err)
}
interactionHandlers[created.Name] = entry.handler
}
// Start the message scheduler
go startScheduler(dg, channelID)
@@ -128,6 +154,25 @@ func loadEnvConfig() error {
return fmt.Errorf("CONSPIRACY_PROBABILITY: %w", err)
}
// Get values in case of resuming at an index
praiseIndex = 0
if valStr := os.Getenv("PRAISE_INDEX"); valStr != "" {
praiseIndex, err = strconv.Atoi(valStr)
if err != nil {
log.Printf("[!] Warning: %s is not a valid int, using default %d", "PRAISE_INDEX", 0)
praiseIndex = 0
}
}
conspiracyIndex = 0
if valStr := os.Getenv("CONSPIRACY_INDEX"); valStr != "" {
conspiracyIndex, err = strconv.Atoi(valStr)
if err != nil {
log.Printf("[!] Warning: %s is not a valid int, using default %d", "CONSPIRACY_INDEX", 0)
conspiracyIndex = 0
}
}
return nil
}
@@ -161,6 +206,37 @@ func readyHandler(s *discordgo.Session, r *discordgo.Ready) {
log.Println("[✓] Swiftspiracy Bot is online and ready!")
}
var interactions = []struct {
command *discordgo.ApplicationCommand
handler func(s *discordgo.Session, i *discordgo.InteractionCreate)
}{
{
command: &discordgo.ApplicationCommand{
Name: "buildinfo",
Description: "Get the bot's build info and uptime",
},
handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
uptime := time.Since(StartTime).Round(time.Second)
response := fmt.Sprintf(
":tools: Build Info:\n- Commit Hash: `%s`\n- Build Date: `%s`\n- Uptime: `%s`",
CommitHash,
BuildDate,
uptime,
)
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Flags: discordgo.MessageFlagsEphemeral,
Content: response,
},
})
if err != nil {
log.Printf("[x] Failed to respond to interaction: %v", err)
}
},
},
}
// startScheduler handles sending messages at intervals
func startScheduler(s *discordgo.Session, channelID string) {
randomDuration := 0 * time.Second