package commands import ( "encoding/json" "fmt" "net/http" "github.com/bwmarrin/discordgo" ) func newListCommand() *Cmd { return &Cmd{ Command: &discordgo.ApplicationCommand{ Name: "list", Description: "List your Thoughtful ideas", }, Handler: handleList, } } type ideaListResponse struct { Success bool `json:"success"` Ideas []Idea `json:"ideas"` } type Idea struct { ID string `json:"id"` Title string `json:"title"` Description string `json:"description"` Tags []string `json:"tags,omitempty"` Icon string `json:"icon,omitempty"` StatusId string `json:"statusId,omitempty"` Todos []Todo `json:"todos,omitempty"` Resources []Resource `json:"resources,omitempty"` } type Todo struct { ID string `json:"id"` Title string `json:"title"` Items []TodoItem `json:"items"` } type TodoItem struct { ID string `json:"id"` Text string `json:"text"` Completed bool `json:"completed"` } type Resource struct { Name string `json:"name"` Link string `json:"link"` } func handleList(s *discordgo.Session, ic *discordgo.InteractionCreate) { user := ic.User if user == nil { user = ic.Member.User } cfg, ok, err := GetUserConfig(user.ID) if err != nil { respondError(s, ic, "Error retrieving configuration.") return } if !ok { respondError(s, ic, "You are not logged in. Use `/setup` first.") return } client := &http.Client{} req, _ := http.NewRequest("GET", cfg.InstanceURL+"/api/ideas/list", nil) req.Header.Set("API-Authentication", cfg.APIKey) resp, err := client.Do(req) if err != nil { respondError(s, ic, "Failed to connect to Thoughtful instance: "+err.Error()) return } defer resp.Body.Close() if resp.StatusCode == 401 { respondError(s, ic, "Unauthorized. Check your API Key.") return } if resp.StatusCode != 200 { respondError(s, ic, fmt.Sprintf("API Error: %d", resp.StatusCode)) return } var result ideaListResponse if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { respondError(s, ic, "Failed to parse API response.") return } if !result.Success { respondError(s, ic, "API reported failure.") return } if len(result.Ideas) == 0 { s.InteractionRespond(ic.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource, Data: &discordgo.InteractionResponseData{ Content: "No ideas found.", }, }) return } // Format output (simple list for now) var content = "**Your Ideas:**\n" for _, idea := range result.Ideas { content += fmt.Sprintf("• **%s** (ID: `%s`)\n", idea.Title, idea.ID) } // Discord message limit check (simplified) if len(content) > 2000 { content = content[:1997] + "..." } s.InteractionRespond(ic.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource, Data: &discordgo.InteractionResponseData{ Content: content, }, }) } func respondError(s *discordgo.Session, ic *discordgo.InteractionCreate, msg string) { s.InteractionRespond(ic.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource, Data: &discordgo.InteractionResponseData{ Content: msg, Flags: discordgo.MessageFlagsEphemeral, }, }) }