diff --git a/commands/dataLength.go b/commands/dataLength.go index 6ee92eb..8abbe46 100644 --- a/commands/dataLength.go +++ b/commands/dataLength.go @@ -29,7 +29,7 @@ const ( userLearn ) -var dataLengthCh chan chStruct = make(chan chStruct) +// var dataLengthCh chan chStruct = make(chan chStruct) var dataLengthWg sync.WaitGroup var DataLengthCommand *Command = &Command{ @@ -44,14 +44,15 @@ var DataLengthCommand *Command = &Command{ }, Category: General, MessageRun: func(ctx *MsgContext) { - dataLengthRun(ctx.Session, ctx.Msg) + dataLengthRun(ctx.Msg, ctx.Msg.Author.Username, ctx.Msg.Author.ID) }, ChatInputRun: func(ctx *ChatInputContext) { - dataLengthRun(ctx.Session, ctx.Inter) + ctx.Inter.DeferReply(true) + dataLengthRun(ctx.Inter, ctx.Inter.Member.User.Username, ctx.Inter.Member.User.ID) }, } -func getLength(dType dataType, coll *mongo.Collection, filter bson.D) { +func getLength(ch chan chStruct, dType dataType, coll *mongo.Collection, filter bson.D) { defer dataLengthWg.Done() var err error var cur *mongo.Cursor @@ -65,33 +66,21 @@ func getLength(dType dataType, coll *mongo.Collection, filter bson.D) { defer cur.Close(context.TODO()) cur.All(context.TODO(), &data) - dataLengthCh <- chStruct{name: dType, length: len(data)} + ch <- chStruct{name: dType, length: len(data)} } -func dataLengthRun(s *discordgo.Session, m any) { - var username, userId, channelId string +func dataLengthRun(m any, username, userId string) { + ch := make(chan chStruct) var textLength, muffinLength, nsfwLength, learnLength, userLearnLength int - switch m := m.(type) { - case *discordgo.MessageCreate: - username = m.Author.Username - userId = m.Author.ID - channelId = m.ChannelID - case *utils.InteractionCreate: - m.DeferReply(true) - username = m.Member.User.Username - userId = m.Member.User.ID - channelId = m.ChannelID - } - dataLengthWg.Add(5) - go getLength(text, databases.Database.Texts, bson.D{{}}) - go getLength(muffin, databases.Database.Texts, bson.D{{Key: "persona", Value: "muffin"}}) - go getLength(nsfw, databases.Database.Texts, bson.D{ + go getLength(ch, text, databases.Database.Texts, bson.D{{}}) + go getLength(ch, muffin, databases.Database.Texts, bson.D{{Key: "persona", Value: "muffin"}}) + go getLength(ch, nsfw, databases.Database.Texts, bson.D{ { Key: "persona", Value: bson.M{ @@ -99,15 +88,15 @@ func dataLengthRun(s *discordgo.Session, m any) { }, }, }) - go getLength(learn, databases.Database.Learns, bson.D{{}}) - go getLength(userLearn, databases.Database.Learns, bson.D{{Key: "user_id", Value: userId}}) + go getLength(ch, learn, databases.Database.Learns, bson.D{{}}) + go getLength(ch, userLearn, databases.Database.Learns, bson.D{{Key: "user_id", Value: userId}}) go func() { dataLengthWg.Wait() - close(dataLengthCh) + close(ch) }() - for resp := range dataLengthCh { + for resp := range ch { switch dataType(resp.name) { case text: textLength = resp.length @@ -126,44 +115,38 @@ func dataLengthRun(s *discordgo.Session, m any) { // 나중에 djs처럼 Embed 만들어 주는 함수 만들어야겠다 // 지금은 임시방편 - embed := &discordgo.MessageEmbed{ - Title: "저장된 데이터량", - Description: fmt.Sprintf("총합: %s개", utils.InlineCode(strconv.Itoa(sum))), - Color: utils.EmbedDefault, - Fields: []*discordgo.MessageEmbedField{ - { - Name: "총 채팅 데이터량", - Value: utils.InlineCode(strconv.Itoa(textLength)) + "개", - Inline: true, + utils.NewMessageSender(m). + AddEmbed(&discordgo.MessageEmbed{ + Title: "저장된 데이터량", + Description: fmt.Sprintf("총합: %s개", utils.InlineCode(strconv.Itoa(sum))), + Color: utils.EmbedDefault, + Fields: []*discordgo.MessageEmbedField{ + { + Name: "총 채팅 데이터량", + Value: utils.InlineCode(strconv.Itoa(textLength)) + "개", + Inline: true, + }, + { + Name: "총 지식 데이터량", + Value: utils.InlineCode(strconv.Itoa(learnLength)) + "개", + Inline: true, + }, + { + Name: "머핀 데이터량", + Value: utils.InlineCode(strconv.Itoa(muffinLength)) + "개", + }, + { + Name: "nsfw 데이터량", + Value: utils.InlineCode(strconv.Itoa(nsfwLength)) + "개", + Inline: true, + }, + { + Name: fmt.Sprintf("%s님이 가르쳐준 데이터량", username), + Value: utils.InlineCode(strconv.Itoa(userLearnLength)) + "개", + Inline: true, + }, }, - { - Name: "총 지식 데이터량", - Value: utils.InlineCode(strconv.Itoa(learnLength)) + "개", - Inline: true, - }, - { - Name: "머핀 데이터량", - Value: utils.InlineCode(strconv.Itoa(muffinLength)) + "개", - }, - { - Name: "nsfw 데이터량", - Value: utils.InlineCode(strconv.Itoa(nsfwLength)) + "개", - Inline: true, - }, - { - Name: fmt.Sprintf("%s님이 가르쳐준 데이터량", username), - Value: utils.InlineCode(strconv.Itoa(userLearnLength)) + "개", - Inline: true, - }, - }, - } - - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendEmbedReply(channelId, embed, m.Reference()) - case *utils.InteractionCreate: - m.EditReply(&discordgo.WebhookEdit{ - Embeds: &[]*discordgo.MessageEmbed{embed}, - }) - } + }). + SetReply(true). + Send() } diff --git a/commands/deleteLearnedData.go b/commands/deleteLearnedData.go index 3ce337d..a43137e 100644 --- a/commands/deleteLearnedData.go +++ b/commands/deleteLearnedData.go @@ -31,85 +31,71 @@ var DeleteLearnedDataCommand *Command = &Command{ }, Category: Chatting, MessageRun: func(ctx *MsgContext) { - deleteLearnedDataRun(ctx.Command, ctx.Session, ctx.Msg, ctx.Args) + command := strings.Join(*ctx.Args, " ") + if command == "" { + utils.NewMessageSender(ctx.Msg). + AddEmbed(&discordgo.MessageEmbed{ + Title: "❌ 오류", + Description: "올바르지 않ㅇ은 용법이에요.", + Fields: []*discordgo.MessageEmbedField{ + { + Name: "사용법", + Value: utils.InlineCode(ctx.Command.DetailedDescription.Usage), + }, + { + Name: "예시", + Value: utils.CodeBlock("md", strings.Join(addPrefix(ctx.Command.DetailedDescription.Examples), "\n")), + }, + }, + Color: utils.EmbedFail, + }). + SetReply(true). + Send() + } + deleteLearnedDataRun(ctx.Msg, strings.Join(*ctx.Args, " "), ctx.Msg.Author.ID) }, ChatInputRun: func(ctx *ChatInputContext) { - deleteLearnedDataRun(ctx.Command, ctx.Session, ctx.Inter, nil) + ctx.Inter.DeferReply(true) + + var command string + + if opt, ok := ctx.Inter.Options["단어"]; ok { + command = opt.StringValue() + } + + deleteLearnedDataRun(ctx.Inter, command, ctx.Inter.Member.User.ID) }, } -func deleteLearnedDataRun(c *Command, s *discordgo.Session, m any, args *[]string) { - var command, userId, description string +func deleteLearnedDataRun(m any, command, userId string) { + var description string var data []databases.Learn var options []discordgo.SelectMenuOption - switch m := m.(type) { - case *discordgo.MessageCreate: - command = strings.Join(*args, " ") - userId = m.Author.ID - - if command == "" { - s.ChannelMessageSendEmbedReply(m.ChannelID, &discordgo.MessageEmbed{ - Title: "❌ 오류", - Description: "올바르지 않ㅇ은 용법이에요.", - Fields: []*discordgo.MessageEmbedField{ - { - Name: "사용법", - Value: utils.InlineCode(c.DetailedDescription.Usage), - }, - { - Name: "예시", - Value: utils.CodeBlock("md", strings.Join(addPrefix(c.DetailedDescription.Examples), "\n")), - }, - }, - Color: utils.EmbedFail, - }, m.Reference()) - } - case *utils.InteractionCreate: - m.DeferReply(true) - - if opt, ok := m.Options["단어"]; ok { - command = opt.StringValue() - } - userId = m.Member.User.ID - } - cur, err := databases.Database.Learns.Find(context.TODO(), bson.M{"user_id": userId, "command": command}) if err != nil { - embed := &discordgo.MessageEmbed{ - Title: "❌ 오류", - Description: "데이터를 가져오는데 실패했어요.", - Color: utils.EmbedFail, - } - - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference()) - case *utils.InteractionCreate: - m.EditReply(&discordgo.WebhookEdit{ - Embeds: &[]*discordgo.MessageEmbed{embed}, - }) - } + utils.NewMessageSender(m). + AddEmbed(&discordgo.MessageEmbed{ + Title: "❌ 오류", + Description: "데이터를 가져오는데 실패했어요.", + Color: utils.EmbedFail, + }). + SetReply(true). + Send() return } cur.All(context.TODO(), &data) if len(data) < 1 { - embed := &discordgo.MessageEmbed{ - Title: "❌ 오류", - Description: "해당 하는 지식ㅇ을 찾을 수 없어요.", - Color: utils.EmbedFail, - } - - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference()) - case *utils.InteractionCreate: - m.EditReply(&discordgo.WebhookEdit{ - Embeds: &[]*discordgo.MessageEmbed{embed}, - }) - } + utils.NewMessageSender(m). + AddEmbed(&discordgo.MessageEmbed{ + Title: "❌ 오류", + Description: "해당 하는 지식ㅇ을 찾을 수 없어요.", + Color: utils.EmbedFail, + }). + SetReply(true). + Send() return } @@ -124,14 +110,13 @@ func deleteLearnedDataRun(c *Command, s *discordgo.Session, m any, args *[]strin description += fmt.Sprintf("%d. %s\n", i+1, data.Result) } - embed := &discordgo.MessageEmbed{ - Title: fmt.Sprintf("%s 삭제", command), - Description: utils.CodeBlock("md", fmt.Sprintf("# %s에 대한 대답 중 하나를 선ㅌ택하여 삭제해주세요.\n%s", command, description)), - Color: utils.EmbedDefault, - } - - components := []discordgo.MessageComponent{ - discordgo.ActionsRow{ + utils.NewMessageSender(m). + AddEmbed(&discordgo.MessageEmbed{ + Title: fmt.Sprintf("%s 삭제", command), + Description: utils.CodeBlock("md", fmt.Sprintf("# %s에 대한 대답 중 하나를 선ㅌ택하여 삭제해주세요.\n%s", command, description)), + Color: utils.EmbedDefault, + }). + AddComponent(discordgo.ActionsRow{ Components: []discordgo.MessageComponent{ discordgo.SelectMenu{ MenuType: discordgo.StringSelectMenu, @@ -140,8 +125,8 @@ func deleteLearnedDataRun(c *Command, s *discordgo.Session, m any, args *[]strin Placeholder: "ㅈ지울 응답을 선택해주세요.", }, }, - }, - discordgo.ActionsRow{ + }). + AddComponent(discordgo.ActionsRow{ Components: []discordgo.MessageComponent{ discordgo.Button{ CustomID: utils.MakeDeleteLearnedDataCancel(userId), @@ -150,20 +135,6 @@ func deleteLearnedDataRun(c *Command, s *discordgo.Session, m any, args *[]strin Disabled: false, }, }, - }, - } - - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendComplex(m.ChannelID, &discordgo.MessageSend{ - Embeds: []*discordgo.MessageEmbed{embed}, - Components: components, - Reference: m.Reference(), - }) - case *utils.InteractionCreate: - m.EditReply(&discordgo.WebhookEdit{ - Embeds: &[]*discordgo.MessageEmbed{embed}, - Components: &components, - }) - } + }). + Send() } diff --git a/commands/discommand.go b/commands/discommand.go index 53bafba..ff23b12 100644 --- a/commands/discommand.go +++ b/commands/discommand.go @@ -39,20 +39,17 @@ type DiscommandStruct struct { } type MsgContext struct { - Session *discordgo.Session - Msg *discordgo.MessageCreate + Msg *utils.MessageCreate Args *[]string Command *Command } type ChatInputContext struct { - Session *discordgo.Session Inter *utils.InteractionCreate Command *Command } type ComponentContext struct { - Session *discordgo.Session Inter *utils.InteractionCreate Component *Component } @@ -118,13 +115,16 @@ func (d *DiscommandStruct) LoadModal(m *Modal) { func (d *DiscommandStruct) MessageRun(name string, s *discordgo.Session, m *discordgo.MessageCreate, args []string) { if command, ok := d.Commands[name]; ok { - command.MessageRun(&MsgContext{s, m, &args, command}) + command.MessageRun(&MsgContext{&utils.MessageCreate{ + MessageCreate: m, + Session: s, + }, &args, command}) } } func (d *DiscommandStruct) ChatInputRun(name string, s *discordgo.Session, i *discordgo.InteractionCreate) { if command, ok := d.Commands[name]; ok { - command.ChatInputRun(&ChatInputContext{s, &utils.InteractionCreate{ + command.ChatInputRun(&ChatInputContext{&utils.InteractionCreate{ InteractionCreate: i, Session: s, Options: utils.GetInteractionOptions(i), @@ -134,7 +134,6 @@ func (d *DiscommandStruct) ChatInputRun(name string, s *discordgo.Session, i *di func (d *DiscommandStruct) ComponentRun(s *discordgo.Session, i *discordgo.InteractionCreate) { data := &ComponentContext{ - Session: s, Inter: &utils.InteractionCreate{ InteractionCreate: i, Session: s, diff --git a/commands/help.go b/commands/help.go index 7de4052..5d71151 100644 --- a/commands/help.go +++ b/commands/help.go @@ -30,10 +30,16 @@ var HelpCommand *Command = &Command{ }, Category: General, MessageRun: func(ctx *MsgContext) { - helpRun(ctx.Session, ctx.Msg, ctx.Args) + helpRun(ctx.Msg.Session, ctx.Msg, strings.Join(*ctx.Args, " ")) }, ChatInputRun: func(ctx *ChatInputContext) { - helpRun(ctx.Session, ctx.Inter, nil) + var command string + + if opt, ok := ctx.Inter.Options["명령어"]; ok { + command = opt.StringValue() + } + + helpRun(ctx.Inter.Session, ctx.Inter, command) }, } @@ -47,8 +53,7 @@ func getCommandsByCategory(d *DiscommandStruct, category Category) []string { return commands } -func helpRun(s *discordgo.Session, m any, args *[]string) { - var commandName string +func helpRun(s *discordgo.Session, m any, commandName string) { embed := &discordgo.MessageEmbed{ Color: utils.EmbedDefault, Footer: &discordgo.MessageEmbedFooter{ @@ -59,16 +64,7 @@ func helpRun(s *discordgo.Session, m any, args *[]string) { }, } - switch m := m.(type) { - case *discordgo.MessageCreate: - commandName = Discommand.Aliases[strings.Join(*args, " ")] - case *utils.InteractionCreate: - if opt, ok := m.Options["명령어"]; ok { - commandName = opt.StringValue() - } else { - commandName = "" - } - } + commandName = Discommand.Aliases[commandName] if commandName == "" || Discommand.Commands[commandName] == nil { embed.Title = fmt.Sprintf("%s의 도움말", s.State.User.Username) @@ -79,14 +75,7 @@ func helpRun(s *discordgo.Session, m any, args *[]string) { strings.Join(getCommandsByCategory(Discommand, Chatting), "\n")), ) - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference()) - case *utils.InteractionCreate: - m.Reply(&discordgo.InteractionResponseData{ - Embeds: []*discordgo.MessageEmbed{embed}, - }) - } + utils.NewMessageSender(m).AddEmbed(embed).SetReply(true).Send() return } @@ -137,12 +126,5 @@ func helpRun(s *discordgo.Session, m any, args *[]string) { }) } - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference()) - case *utils.InteractionCreate: - m.Reply(&discordgo.InteractionResponseData{ - Embeds: []*discordgo.MessageEmbed{embed}, - }) - } + utils.NewMessageSender(m).AddEmbed(embed).SetReply(true).Send() } diff --git a/commands/information.go b/commands/information.go index 479b4d7..72ced24 100644 --- a/commands/information.go +++ b/commands/information.go @@ -19,53 +19,56 @@ var InformationCommand *Command = &Command{ }, Category: General, MessageRun: func(ctx *MsgContext) { - informationRun(ctx.Session, ctx.Msg) + informationRun(ctx.Msg.Session, ctx.Msg) }, ChatInputRun: func(ctx *ChatInputContext) { - informationRun(ctx.Session, ctx.Inter) + informationRun(ctx.Inter.Session, ctx.Inter) }, } func informationRun(s *discordgo.Session, m any) { owner, _ := s.User(configs.Config.Bot.OwnerId) - embed := &discordgo.MessageEmbed{ - Title: fmt.Sprintf("%s의 정보", s.State.User.Username), - Fields: []*discordgo.MessageEmbedField{ - { - Name: "운영 체제", - Value: utils.InlineCode(fmt.Sprintf("%s %s", runtime.GOARCH, runtime.GOOS)), + utils.NewMessageSender(m). + AddEmbed(&discordgo.MessageEmbed{ + Title: fmt.Sprintf("%s의 정보", s.State.User.Username), + Fields: []*discordgo.MessageEmbedField{ + { + Name: "운영 체제", + Value: utils.InlineCode(fmt.Sprintf("%s %s", runtime.GOARCH, runtime.GOOS)), + }, + { + Name: "제작자", + Value: utils.InlineCode(owner.Username), + }, + { + Name: "버전", + Value: utils.InlineCode(configs.MUFFIN_VERSION), + }, + { + Name: "최근에 업데이트된 날짜", + Value: utils.Time(configs.UpdatedAt, utils.RelativeTime), + Inline: true, + }, + { + Name: "시작한 시각", + Value: utils.Time(configs.StartedAt, utils.RelativeTime), + Inline: true, + }, }, - { - Name: "제작자", - Value: utils.InlineCode(owner.Username), + Color: utils.EmbedDefault, + Thumbnail: &discordgo.MessageEmbedThumbnail{ + URL: s.State.User.AvatarURL("512"), }, - { - Name: "버전", - Value: utils.InlineCode(configs.MUFFIN_VERSION), - }, - { - Name: "최근에 업데이트된 날짜", - Value: utils.Time(configs.UpdatedAt, utils.RelativeTime), - Inline: true, - }, - { - Name: "시작한 시각", - Value: utils.Time(configs.StartedAt, utils.RelativeTime), - Inline: true, - }, - }, - Color: utils.EmbedDefault, - Thumbnail: &discordgo.MessageEmbedThumbnail{ - URL: s.State.User.AvatarURL("512"), - }, - } + }). + SetReply(true). + Send() - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference()) - case *utils.InteractionCreate: - m.Reply(&discordgo.InteractionResponseData{ - Embeds: []*discordgo.MessageEmbed{embed}, - }) - } + // switch m := m.(type) { + // case *discordgo.MessageCreate: + // s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference()) + // case *utils.InteractionCreate: + // m.Reply(&discordgo.InteractionResponseData{ + // Embeds: []*discordgo.MessageEmbed{embed}, + // }) + // } } diff --git a/commands/learn.go b/commands/learn.go index d3bf3bc..ce38f10 100644 --- a/commands/learn.go +++ b/commands/learn.go @@ -3,6 +3,7 @@ package commands import ( "context" "fmt" + "log" "strings" "time" @@ -57,10 +58,50 @@ var LearnCommand *Command = &Command{ }, Category: Chatting, MessageRun: func(ctx *MsgContext) { - learnRun(ctx.Command, ctx.Session, ctx.Msg, ctx.Args) + if len(*ctx.Args) < 2 { + utils.NewMessageSender(ctx.Msg). + AddEmbed(&discordgo.MessageEmbed{ + Title: "❌ 오류", + Description: "올바르지 않ㅇ은 용법이에요.", + Fields: []*discordgo.MessageEmbedField{ + { + Name: "사용법", + Value: utils.InlineCode(ctx.Command.DetailedDescription.Usage), + Inline: true, + }, + { + Name: "사용 가능한 인자", + Value: learnArguments, + Inline: true, + }, + { + Name: "예시", + Value: utils.CodeBlock("md", strings.Join(addPrefix(ctx.Command.DetailedDescription.Examples), "\n")), + }, + }, + Color: utils.EmbedFail, + }). + SetReply(true). + Send() + return + } + + learnRun(ctx.Msg, ctx.Msg.Author.ID, strings.ReplaceAll((*ctx.Args)[0], "_", " "), strings.ReplaceAll((*ctx.Args)[1], "_", " ")) }, ChatInputRun: func(ctx *ChatInputContext) { - learnRun(ctx.Command, ctx.Session, ctx.Inter, nil) + ctx.Inter.DeferReply(true) + + var command, result string + + if opt, ok := ctx.Inter.Options["단어"]; ok { + command = opt.StringValue() + } + + if opt, ok := ctx.Inter.Options["대답"]; ok { + result = opt.StringValue() + } + + learnRun(ctx.Inter, ctx.Inter.Member.User.ID, command, result) }, } @@ -71,54 +112,8 @@ func addPrefix(arr []string) (newArr []string) { return } -func learnRun(c *Command, s *discordgo.Session, m any, args *[]string) { - var userId, command, result string - +func learnRun(m any, userId, command, result string) { igCommands := []string{} - switch m := m.(type) { - case *discordgo.MessageCreate: - userId = m.Author.ID - - if len(*args) < 2 { - s.ChannelMessageSendEmbedReply(m.ChannelID, &discordgo.MessageEmbed{ - Title: "❌ 오류", - Description: "올바르지 않ㅇ은 용법이에요.", - Fields: []*discordgo.MessageEmbedField{ - { - Name: "사용법", - Value: utils.InlineCode(c.DetailedDescription.Usage), - Inline: true, - }, - { - Name: "사용 가능한 인자", - Value: learnArguments, - Inline: true, - }, - { - Name: "예시", - Value: utils.CodeBlock("md", strings.Join(addPrefix(c.DetailedDescription.Examples), "\n")), - }, - }, - Color: utils.EmbedFail, - }, m.Reference()) - return - } - - command = strings.ReplaceAll((*args)[0], "_", " ") - result = strings.ReplaceAll((*args)[1], "_", " ") - case *utils.InteractionCreate: - m.DeferReply(true) - - userId = m.Member.User.ID - - if opt, ok := m.Options["단어"]; ok { - command = opt.StringValue() - } - - if opt, ok := m.Options["대답"]; ok { - result = opt.StringValue() - } - } for _, command := range Discommand.Commands { igCommands = append(igCommands, command.Name) @@ -136,40 +131,31 @@ func learnRun(c *Command, s *discordgo.Session, m any, args *[]string) { for _, ig := range ignores { if strings.Contains(command, ig) { - embed := &discordgo.MessageEmbed{ - Title: "❌ 오류", - Description: "해ㄷ당 단어는 배우기 껄끄ㄹ럽네요.", - Color: utils.EmbedFail, - } - - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference()) - case *utils.InteractionCreate: - m.EditReply(&discordgo.WebhookEdit{ - Embeds: &[]*discordgo.MessageEmbed{embed}, - }) - } + utils.NewMessageSender(m). + AddEmbed( + &discordgo.MessageEmbed{ + Title: "❌ 오류", + Description: "해ㄷ당 단어는 배우기 껄끄ㄹ럽네요.", + Color: utils.EmbedFail, + }). + SetReply(true). + Send() return } } for _, di := range disallows { if strings.Contains(result, di) { - embed := &discordgo.MessageEmbed{ - Title: "❌ 오류", - Description: "해당 단ㅇ어의 대답으로 하기 좀 그렇ㄴ네요.", - Color: utils.EmbedFail, - } - - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference()) - case *utils.InteractionCreate: - m.EditReply(&discordgo.WebhookEdit{ - Embeds: &[]*discordgo.MessageEmbed{embed}, - }) - } + utils.NewMessageSender(m). + AddEmbed( + &discordgo.MessageEmbed{ + Title: "❌ 오류", + Description: "해당 단ㅇ어의 대답으로 하기 좀 그렇ㄴ네요.", + Color: utils.EmbedFail, + }). + SetReply(true). + Send() + return } } @@ -180,36 +166,25 @@ func learnRun(c *Command, s *discordgo.Session, m any, args *[]string) { CreatedAt: time.Now(), }) if err != nil { - fmt.Println(err) - embed := &discordgo.MessageEmbed{ - Title: "❌ 오류", - Description: "단어를 배우는데 오류가 생겼어요.", - Color: utils.EmbedFail, - } + log.Println(err) - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference()) - case *utils.InteractionCreate: - m.EditReply(&discordgo.WebhookEdit{ - Embeds: &[]*discordgo.MessageEmbed{embed}, - }) - } + utils.NewMessageSender(m). + AddEmbed(&discordgo.MessageEmbed{ + Title: "❌ 오류", + Description: "단어를 배우는데 오류가 생겼어요.", + Color: utils.EmbedFail, + }). + SetReply(true). + Send() return } - embed := &discordgo.MessageEmbed{ - Title: "✅ 성공", - Description: fmt.Sprintf("%s 배웠어요.", hangul.GetJosa(command, hangul.EUL_REUL)), - Color: utils.EmbedSuccess, - } - - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference()) - case *utils.InteractionCreate: - m.EditReply(&discordgo.WebhookEdit{ - Embeds: &[]*discordgo.MessageEmbed{embed}, - }) - } + utils.NewMessageSender(m). + AddEmbed(&discordgo.MessageEmbed{ + Title: "✅ 성공", + Description: fmt.Sprintf("%s 배웠어요.", hangul.GetJosa(command, hangul.EUL_REUL)), + Color: utils.EmbedSuccess, + }). + SetReply(true). + Send() } diff --git a/commands/learnedDataList.go b/commands/learnedDataList.go index 7647859..b863570 100644 --- a/commands/learnedDataList.go +++ b/commands/learnedDataList.go @@ -58,10 +58,100 @@ var LearnedDataListCommand *Command = &Command{ }, Category: Chatting, MessageRun: func(ctx *MsgContext) { - learnedDataListRun(ctx.Session, ctx.Msg, ctx.Args) + var length int + + filter := bson.D{{Key: "user_id", Value: ctx.Msg.Author.ID}} + query := strings.Join(*ctx.Args, " ") + + if match := utils.RegexpLearnQueryCommand.FindStringSubmatch(query); match != nil { + filter = append(filter, bson.E{ + Key: "command", + Value: bson.M{ + "$regex": match[1], + }, + }) + } + + if match := utils.RegexpLearnQueryResult.FindStringSubmatch(query); match != nil { + filter = append(filter, bson.E{ + Key: "result", + Value: bson.M{ + "$regex": match[1], + }, + }) + } + + if match := utils.RegexpLearnQueryLength.FindStringSubmatch(query); match != nil { + var err error + length, err := strconv.Atoi(match[1]) + + if err != nil { + utils.NewMessageSender(ctx.Msg). + AddEmbed(&discordgo.MessageEmbed{ + Title: "❌ 오류", + Description: "개수의 값은 숫자여야해요.", + Color: utils.EmbedFail, + }). + SetReply(true). + Send() + return + } + + if float64(length) < LIST_MIN_VALUE { + utils.NewMessageSender(ctx.Msg). + AddEmbed(&discordgo.MessageEmbed{ + Title: "❌ 오류", + Description: fmt.Sprintf("개수의 값은 %d보다 커야해요.", int(LIST_MIN_VALUE)), + Color: utils.EmbedFail, + }). + SetReply(true). + Send() + return + } + + if float64(length) > LIST_MAX_VALUE { + utils.NewMessageSender(ctx.Msg). + AddEmbed(&discordgo.MessageEmbed{ + Title: "❌ 오류", + Description: fmt.Sprintf("개수의 값은 %d보다 작아야해요.", int(LIST_MAX_VALUE)), + Color: utils.EmbedFail, + }). + SetReply(true). + Send() + return + } + } + learnedDataListRun(ctx.Msg.Session, ctx.Msg, ctx.Msg.Author.GlobalName, ctx.Msg.Author.AvatarURL("512"), filter, length) }, ChatInputRun: func(ctx *ChatInputContext) { - learnedDataListRun(ctx.Session, ctx.Inter, nil) + ctx.Inter.DeferReply(true) + + var length int + + filter := bson.D{{Key: "user_id", Value: ctx.Inter.Member.User.ID}} + + if opt, ok := ctx.Inter.Options["단어"]; ok { + filter = append(filter, bson.E{ + Key: "command", + Value: bson.M{ + "$regex": opt.StringValue(), + }, + }) + } + + if opt, ok := ctx.Inter.Options["대답"]; ok { + filter = append(filter, bson.E{ + Key: "result", + Value: bson.M{ + "$regex": opt.StringValue(), + }, + }) + } + + if opt, ok := ctx.Inter.Options["개수"]; ok { + length = int(opt.IntValue()) + } + learnedDataListRun(ctx.Inter.Session, ctx.Inter, ctx.Inter.Member.User.GlobalName, ctx.Inter.Member.User.AvatarURL("512"), filter, length) }, } @@ -105,134 +195,33 @@ func getDescriptions(data *[]databases.Learn, length int) (descriptions []string return } -func learnedDataListRun(s *discordgo.Session, m any, args *[]string) { - var globalName, avatarUrl string +func learnedDataListRun(s *discordgo.Session, m any, globalName, avatarUrl string, filter bson.D, length int) { var data []databases.Learn - var filter bson.D - var length int - - switch m := m.(type) { - case *discordgo.MessageCreate: - filter = bson.D{{Key: "user_id", Value: m.Author.ID}} - globalName = m.Author.GlobalName - avatarUrl = m.Author.AvatarURL("512") - - query := strings.Join(*args, " ") - - if match := utils.RegexpLearnQueryCommand.FindStringSubmatch(query); match != nil { - filter = append(filter, bson.E{ - Key: "command", - Value: bson.M{ - "$regex": match[1], - }, - }) - } - - if match := utils.RegexpLearnQueryResult.FindStringSubmatch(query); match != nil { - filter = append(filter, bson.E{ - Key: "result", - Value: bson.M{ - "$regex": match[1], - }, - }) - } - - if match := utils.RegexpLearnQueryLength.FindStringSubmatch(query); match != nil { - var err error - length, err = strconv.Atoi(match[1]) - - if err != nil { - s.ChannelMessageSendEmbedReply(m.ChannelID, &discordgo.MessageEmbed{ - Title: "❌ 오류", - Description: "개수의 값은 숫자여야해요.", - Color: utils.EmbedFail, - }, m.Reference()) - return - } - - if float64(length) < LIST_MIN_VALUE { - s.ChannelMessageSendEmbedReply(m.ChannelID, &discordgo.MessageEmbed{ - Title: "❌ 오류", - Description: fmt.Sprintf("개수의 값은 %d보다 커야해요.", int(LIST_MIN_VALUE)), - Color: utils.EmbedFail, - }, m.Reference()) - return - } - - if float64(length) > LIST_MAX_VALUE { - s.ChannelMessageSendEmbedReply(m.ChannelID, &discordgo.MessageEmbed{ - Title: "❌ 오류", - Description: fmt.Sprintf("개수의 값은 %d보다 작아야해요.", int(LIST_MAX_VALUE)), - Color: utils.EmbedFail, - }, m.Reference()) - return - } - } - case *utils.InteractionCreate: - m.DeferReply(true) - - filter = bson.D{{Key: "user_id", Value: m.Member.User.ID}} - globalName = m.Member.User.GlobalName - avatarUrl = m.Member.User.AvatarURL("512") - - if opt, ok := m.Options["단어"]; ok { - filter = append(filter, bson.E{ - Key: "command", - Value: bson.M{ - "$regex": opt.StringValue(), - }, - }) - } - - if opt, ok := m.Options["대답"]; ok { - filter = append(filter, bson.E{ - Key: "result", - Value: bson.M{ - "$regex": opt.StringValue(), - }, - }) - } - - if opt, ok := m.Options["개수"]; ok { - length = int(opt.IntValue()) - } - } cur, err := databases.Database.Learns.Find(context.TODO(), filter) if err != nil { if err == mongo.ErrNoDocuments { - embed := &discordgo.MessageEmbed{ - Title: "❌ 오류", - Description: "당신은 지식ㅇ을 가르쳐준 적이 없어요!", - Color: utils.EmbedFail, - } - - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference()) - case *utils.InteractionCreate: - m.EditReply(&discordgo.WebhookEdit{ - Embeds: &[]*discordgo.MessageEmbed{embed}, - }) - } + utils.NewMessageSender(m). + AddEmbed(&discordgo.MessageEmbed{ + Title: "❌ 오류", + Description: "당신은 지식ㅇ을 가르쳐준 적이 없어요!", + Color: utils.EmbedFail, + }). + SetReply(true). + Send() return } fmt.Println(err) - embed := &discordgo.MessageEmbed{ - Title: "❌ 오류", - Description: "데이터를 가져오는데 실패했어요.", - Color: utils.EmbedFail, - } - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendEmbedReply(m.ChannelID, embed, m.Reference()) - case *utils.InteractionCreate: - m.EditReply(&discordgo.WebhookEdit{ - Embeds: &[]*discordgo.MessageEmbed{embed}, - }) - } + utils.NewMessageSender(m). + AddEmbed(&discordgo.MessageEmbed{ + Title: "❌ 오류", + Description: "데이터를 가져오는데 실패했어요.", + Color: utils.EmbedFail, + }). + SetReply(true). + Send() return } @@ -240,13 +229,14 @@ func learnedDataListRun(s *discordgo.Session, m any, args *[]string) { cur.All(context.TODO(), &data) - embed := &discordgo.MessageEmbed{ - Title: fmt.Sprintf("%s님이 알려주신 지식", globalName), - Color: utils.EmbedDefault, - Thumbnail: &discordgo.MessageEmbedThumbnail{ - URL: avatarUrl, - }, - } - - utils.StartPaginationEmbed(s, m, embed, getDescriptions(&data, length), utils.CodeBlock("md", fmt.Sprintf("# 총 %d개에요.\n", len(data))+"%s")) + utils.NewPaginationEmbedBuilder(m, getDescriptions(&data, length)). + SetEmbed(&discordgo.MessageEmbed{ + Title: fmt.Sprintf("%s님이 알려주신 지식", globalName), + Color: utils.EmbedDefault, + Thumbnail: &discordgo.MessageEmbedThumbnail{ + URL: avatarUrl, + }, + }). + SetDefaultDesc(utils.CodeBlock("md", fmt.Sprintf("# 총 %d개에요.\n", len(data))+"%s")). + Start() } diff --git a/configs/version.go b/configs/version.go index dc93921..2a1b104 100644 --- a/configs/version.go +++ b/configs/version.go @@ -7,7 +7,7 @@ import ( "git.wh64.net/muffin/goMuffin/utils" ) -const MUFFIN_VERSION = "5.1.0-gopher_dev.250517c" +const MUFFIN_VERSION = "0.0.0-souffle_canary.250517a-fix_the_spaghetti" var updatedString string = utils.RegexpDecimals.FindAllStringSubmatch(MUFFIN_VERSION, -1)[3][0] diff --git a/utils/interactions.go b/utils/interactions.go index 199779e..aefb602 100644 --- a/utils/interactions.go +++ b/utils/interactions.go @@ -21,7 +21,9 @@ type InteractionCreate struct { *discordgo.InteractionCreate Session *discordgo.Session // NOTE: It's only can ApplicationCommand - Options map[string]*discordgo.ApplicationCommandInteractionDataOption + Options map[string]*discordgo.ApplicationCommandInteractionDataOption + Deferred bool + Replied bool } // Reply to this interaction. @@ -30,6 +32,8 @@ func (i *InteractionCreate) Reply(data *discordgo.InteractionResponseData) { Type: discordgo.InteractionResponseChannelMessageWithSource, Data: data, }) + + i.Replied = true } // GetInteractionOptions to this interaction. @@ -55,6 +59,8 @@ func (i *InteractionCreate) DeferReply(ephemeral bool) { Flags: flags, }, }) + + i.Deferred = true } // DeferUpdate to this interaction. @@ -62,11 +68,15 @@ func (i *InteractionCreate) DeferUpdate() { i.Session.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseDeferredMessageUpdate, }) + + i.Deferred = true } // EditReply to this interaction. func (i *InteractionCreate) EditReply(data *discordgo.WebhookEdit) { i.Session.InteractionResponseEdit(i.Interaction, data) + + i.Replied = true } // Update to this interaction. @@ -75,6 +85,8 @@ func (i *InteractionCreate) Update(data *discordgo.InteractionResponseData) { Type: discordgo.InteractionResponseUpdateMessage, Data: data, }) + + i.Replied = true } func (i *InteractionCreate) ShowModal(data *ModalData) error { @@ -115,5 +127,7 @@ func (i *InteractionCreate) ShowModal(data *ModalData) error { } defer resp.Body.Close() + + i.Replied = true return nil } diff --git a/utils/messageBuilder.go b/utils/messageBuilder.go new file mode 100644 index 0000000..1d60b78 --- /dev/null +++ b/utils/messageBuilder.go @@ -0,0 +1,97 @@ +package utils + +import "github.com/bwmarrin/discordgo" + +type MessageCreate struct { + *discordgo.MessageCreate + Session *discordgo.Session +} + +type MessageSender struct { + Embeds []*discordgo.MessageEmbed + Content string + Components []discordgo.MessageComponent + Ephemeral bool + Reply bool + m any +} + +func NewMessageSender(m any) *MessageSender { + return &MessageSender{m: m} +} + +func (s *MessageSender) AddEmbed(embed *discordgo.MessageEmbed) *MessageSender { + s.Embeds = append(s.Embeds, embed) + return s +} + +func (s *MessageSender) SetEmbeds(embeds []*discordgo.MessageEmbed) *MessageSender { + s.Embeds = embeds + return s +} + +func (s *MessageSender) AddComponent(cmp discordgo.MessageComponent) *MessageSender { + s.Components = append(s.Components, cmp) + return s +} + +func (s *MessageSender) SetComponents(components []discordgo.MessageComponent) *MessageSender { + s.Components = components + return s +} + +func (s *MessageSender) SetContent(content string) *MessageSender { + s.Content = content + return s +} + +func (s *MessageSender) SetEphemeral(ephemeral bool) *MessageSender { + s.Ephemeral = ephemeral + return s +} + +func (s *MessageSender) SetReply(reply bool) *MessageSender { + s.Reply = reply + return s +} + +func (s *MessageSender) Send() { + switch m := s.m.(type) { + case *MessageCreate: + var reference *discordgo.MessageReference = nil + + if s.Reply { + reference = m.Reference() + } + + m.Session.ChannelMessageSendComplex(m.ChannelID, &discordgo.MessageSend{ + Content: s.Content, + Embeds: s.Embeds, + Components: s.Components, + Reference: reference, + }) + return + case *InteractionCreate: + var flags discordgo.MessageFlags + + if s.Ephemeral { + flags = discordgo.MessageFlagsEphemeral + } + + if m.Replied || m.Deferred { + m.EditReply(&discordgo.WebhookEdit{ + Content: &s.Content, + Embeds: &s.Embeds, + Components: &s.Components, + }) + return + } + + m.Reply(&discordgo.InteractionResponseData{ + Content: s.Content, + Embeds: s.Embeds, + Components: s.Components, + Flags: flags, + }) + } +} diff --git a/utils/paginationEmbed.go b/utils/paginationEmbed.go index 4e9d4b0..99c444d 100644 --- a/utils/paginationEmbed.go +++ b/utils/paginationEmbed.go @@ -17,8 +17,41 @@ type PaginationEmbed struct { desc string } +type PaginationEmbedBuilder struct { + Embed *discordgo.MessageEmbed + Data []string + DefaultDesc string + m any +} + var PaginationEmbeds = make(map[string]*PaginationEmbed) +func NewPaginationEmbedBuilder(m any, data []string) *PaginationEmbedBuilder { + return &PaginationEmbedBuilder{ + m: m, + Data: data, + } +} + +func (b *PaginationEmbedBuilder) SetEmbed(embed *discordgo.MessageEmbed) *PaginationEmbedBuilder { + b.Embed = embed + return b +} + +func (b *PaginationEmbedBuilder) SetDefaultDesc(desc string) *PaginationEmbedBuilder { + b.DefaultDesc = desc + return b +} + +func (b *PaginationEmbedBuilder) Start() { + switch m := b.m.(type) { + case *MessageCreate: + startPaginationEmbed(m, m.Author.ID, b.Embed, b.Data, b.DefaultDesc) + case *InteractionCreate: + startPaginationEmbed(m, m.Member.User.ID, b.Embed, b.Data, b.DefaultDesc) + } +} + func makeComponents(id string, current, total int) *[]discordgo.MessageComponent { disabled := false @@ -63,18 +96,8 @@ func makeDesc(desc, item string) string { return newDesc } -// StartPaginationEmbed starts new PaginationEmbed struct -func StartPaginationEmbed(s *discordgo.Session, m any, e *discordgo.MessageEmbed, data []string, defaultDesc string) { - var userId string - - switch m := m.(type) { - case *discordgo.MessageCreate: - userId = m.Author.ID - case *InteractionCreate: - userId = m.Member.User.ID - } - - id := fmt.Sprintf("%s/%d", userId, rand.Intn(12)) +func startPaginationEmbed(m any, userId string, e *discordgo.MessageEmbed, data []string, defaultDesc string) { + id := fmt.Sprintf("%s/%d", userId, rand.Intn(100)) p := &PaginationEmbed{ Embed: e, Data: data, @@ -91,19 +114,12 @@ func StartPaginationEmbed(s *discordgo.Session, m any, e *discordgo.MessageEmbed p.Embed.Description = makeDesc(p.desc, data[0]) } - switch m := m.(type) { - case *discordgo.MessageCreate: - s.ChannelMessageSendComplex(m.ChannelID, &discordgo.MessageSend{ - Reference: m.Reference(), - Embeds: []*discordgo.MessageEmbed{p.Embed}, - Components: *makeComponents(id, p.Current, p.Total), - }) - case *InteractionCreate: - m.EditReply(&discordgo.WebhookEdit{ - Embeds: &[]*discordgo.MessageEmbed{p.Embed}, - Components: makeComponents(id, p.Current, p.Total), - }) - } + NewMessageSender(m). + AddEmbed(e). + SetComponents(*makeComponents(id, p.Current, p.Total)). + SetReply(true). + SetEphemeral(true). + Send() PaginationEmbeds[id] = p }