package commands import ( "encoding/json" "fmt" "io" "log" "net/http" "os" "strings" "time" helpers "ion606_bot/Bot/Helpers" "github.com/bwmarrin/discordgo" ) var SuggestCommand = &discordgo.ApplicationCommand{ Name: "suggest", Description: "Submit a suggestion to the server", } var timeToWait = time.Minute * time.Duration(5) func HandleSuggest(s *discordgo.Session, i *discordgo.InteractionCreate) { userID := i.Member.User.ID // Check cooldown from DB lastSubmission, err := helpers.GetLastSubmission(userID) if err != nil { helpers.HandleError(s, i, fmt.Errorf("failed to check cooldown: %w", err)) return } if time.Since(lastSubmission) < (timeToWait) { remaining := time.Until(lastSubmission.Add(timeToWait)).Round(time.Minute) s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource, Data: &discordgo.InteractionResponseData{ Content: fmt.Sprintf("⏳ You can submit another suggestion in %d minutes!", int(remaining.Minutes())), Flags: discordgo.MessageFlagsEphemeral, }, }) return } err = helpers.RemoveUserSubmittions(userID); if err != nil { log.Default().Println(fmt.Sprintf("%s", err.Error())) } // Store new submission time if err := helpers.SetLastSubmission(userID); err != nil { helpers.HandleError(s, i, fmt.Errorf("failed to update cooldown: %w", err)) return } // Create modal with suggestion input err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseModal, Data: &discordgo.InteractionResponseData{ CustomID: "suggestion_modal", Title: "Submit Suggestion", Components: []discordgo.MessageComponent{ discordgo.ActionsRow{ Components: []discordgo.MessageComponent{ discordgo.TextInput{ CustomID: "suggestion_content", Label: "Your suggestion", Style: discordgo.TextInputParagraph, Placeholder: "Type your suggestion here...", Required: true, MaxLength: 1000, }, }, }, }, }, }) if err != nil { helpers.HandleError(s, i, fmt.Errorf("failed to create modal: %w", err)) } } func HandleSuggestModal(s *discordgo.Session, i *discordgo.InteractionCreate) { // Extract suggestion from modal data := i.ModalSubmitData() content := data.Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value // Get webhook URL from environment webhookURL := os.Getenv("WEBHOOK_URL") if webhookURL == "" { helpers.HandleError(s, i, fmt.Errorf("WEBHOOK_URL environment variable not set")) return } // Create payload payload := map[string]string{ "content": fmt.Sprintf("**New Suggestion from <@%s> (%s)**\n```\n%s\n```", i.Member.User.ID, i.Member.User.Username, content), } jsonData, err := json.Marshal(payload) if err != nil { helpers.HandleError(s, i, fmt.Errorf("failed to marshal payload: %w", err)) return } // Send to webhook resp, err := http.Post(webhookURL, "application/json", strings.NewReader(string(jsonData))) if err != nil { helpers.HandleError(s, i, fmt.Errorf("webhook request failed: %w", err)) return } defer resp.Body.Close() // Verify successful response if resp.StatusCode < 200 || resp.StatusCode >= 300 { body, _ := io.ReadAll(resp.Body) helpers.HandleError(s, i, fmt.Errorf("webhook returned %d: %s", resp.StatusCode, string(body))) return } // Send confirmation to user s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource, Data: &discordgo.InteractionResponseData{ Content: "✅ Your suggestion has been submitted!", Flags: discordgo.MessageFlagsEphemeral, }, }) }