package features import ( "fmt" "strings" "github.com/disgoorg/disgo/discord" "github.com/disgoorg/disgo/events" "github.com/disgoorg/snowflake/v2" "github.com/elisiei/unbot/db" ) type Dictionary struct { db *db.DB config DictionaryConfig } type DictionaryConfig struct { Enabled bool } func NewDictionary(database *db.DB, enabled bool) *Dictionary { return &Dictionary{db: database, config: DictionaryConfig{Enabled: enabled}} } func (d *Dictionary) Command() discord.SlashCommandCreate { return discord.SlashCommandCreate{ Name: "dict", Description: "Urban dictionary for the server", Options: []discord.ApplicationCommandOption{ discord.ApplicationCommandOptionSubCommand{ Name: "add", Description: "Add a definition", Options: []discord.ApplicationCommandOption{ discord.ApplicationCommandOptionString{ Name: "word", Description: "The word to define", Required: true, }, discord.ApplicationCommandOptionString{ Name: "definition", Description: "The definition", Required: true, }, }, }, discord.ApplicationCommandOptionSubCommand{ Name: "get", Description: "Get a definition", Options: []discord.ApplicationCommandOption{ discord.ApplicationCommandOptionString{ Name: "word", Description: "The word to look up", Required: true, Autocomplete: true, }, }, }, discord.ApplicationCommandOptionSubCommand{ Name: "remove", Description: "Remove your definition", Options: []discord.ApplicationCommandOption{ discord.ApplicationCommandOptionString{ Name: "word", Description: "The word to remove", Required: true, }, }, }, discord.ApplicationCommandOptionSubCommand{ Name: "list", Description: "List all defined words", }, }, } } func (d *Dictionary) HandleAutocomplete(e *events.AutocompleteInteractionCreate) { focused := e.Data.Focused() input := strings.ToLower(focused.String()) allWords, err := d.db.ListWords() if err != nil { return } var choices []discord.AutocompleteChoice for _, w := range allWords { if strings.HasPrefix(strings.ToLower(w.Word), input) { if len(choices) >= 25 { break } choices = append(choices, discord.AutocompleteChoiceString{ Name: w.Word, Value: w.Word, }) } } e.AutocompleteResult(choices) } func (d *Dictionary) HandleAdd(e *events.ApplicationCommandInteractionCreate) { data := e.SlashCommandInteractionData() word := strings.ToLower(strings.TrimSpace(data.String("word"))) definition := strings.TrimSpace(data.String("definition")) if word == "" || definition == "" { e.CreateMessage(discord.NewMessageCreate().WithContent("Word and definition cannot be empty.").WithEphemeral(true)) return } err := d.db.AddDefinition(word, definition, e.User().ID.String()) if err != nil { e.CreateMessage(discord.NewMessageCreate().WithContent("Failed to save definition.").WithEphemeral(true)) return } e.CreateMessage(discord.NewMessageCreate().WithContent(fmt.Sprintf("Added definition for **%s**", word))) } func (d *Dictionary) HandleGet(e *events.ApplicationCommandInteractionCreate) { data := e.SlashCommandInteractionData() word := strings.ToLower(strings.TrimSpace(data.String("word"))) entry, err := d.db.GetDefinition(word) if err != nil { e.CreateMessage(discord.NewMessageCreate().WithContent("Failed to look up definition.").WithEphemeral(true)) return } if entry == nil { e.CreateMessage(discord.NewMessageCreate().WithContent(fmt.Sprintf("No definition found for **%s**", word)).WithEphemeral(true)) return } var footerText string authorID, parseErr := snowflake.Parse(entry.AuthorID) if parseErr == nil && authorID != 0 { footerText = "Added by <@" + authorID.String() + ">" } embed := discord.Embed{ Title: entry.Word, Description: entry.Definition, Color: 0x00AE86, Fields: []discord.EmbedField{ {Name: "Rating", Value: fmt.Sprintf("👍 %d | 👎 %d", entry.Upvotes, entry.Downvotes), Inline: new(true)}, }, Footer: &discord.EmbedFooter{Text: footerText}, } e.CreateMessage(discord.NewMessageCreate().AddEmbeds(embed)) } func (d *Dictionary) HandleRemove(e *events.ApplicationCommandInteractionCreate) { data := e.SlashCommandInteractionData() word := strings.ToLower(strings.TrimSpace(data.String("word"))) entry, err := d.db.GetDefinition(word) if err != nil { e.CreateMessage(discord.NewMessageCreate().WithContent("Failed to look up definition.").WithEphemeral(true)) return } if entry == nil { e.CreateMessage(discord.NewMessageCreate().WithContent(fmt.Sprintf("No definition found for **%s**", word)).WithEphemeral(true)) return } if entry.AuthorID != e.User().ID.String() { e.CreateMessage(discord.NewMessageCreate().WithContent("You can only remove your own definitions.").WithEphemeral(true)) return } if err := d.db.RemoveDefinition(word); err != nil { e.CreateMessage(discord.NewMessageCreate().WithContent("Failed to remove definition.").WithEphemeral(true)) return } e.CreateMessage(discord.NewMessageCreate().WithContent(fmt.Sprintf("Removed definition for **%s**", word))) } func (d *Dictionary) HandleList(e *events.ApplicationCommandInteractionCreate) { words, err := d.db.ListWords() if err != nil { e.CreateMessage(discord.NewMessageCreate().WithContent("Failed to list words.").WithEphemeral(true)) return } if len(words) == 0 { e.CreateMessage(discord.NewMessageCreate().WithContent("No words defined yet.").WithEphemeral(true)) return } var sb strings.Builder for i, w := range words { if i > 0 { sb.WriteString(", ") } fmt.Fprintf(&sb, "**%s**", w.Word) if i >= 50 { sb.WriteString("...") break } } e.CreateMessage(discord.NewMessageCreate().WithContent(fmt.Sprintf("Defined words (%d): %s", len(words), sb.String()))) }