293 lines
8.8 KiB
Go
293 lines
8.8 KiB
Go
package commands
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
|
|
"git.wh64.net/muffin/goMuffin/chatbot"
|
|
"git.wh64.net/muffin/goMuffin/configs"
|
|
"git.wh64.net/muffin/goMuffin/databases"
|
|
"git.wh64.net/muffin/goMuffin/utils"
|
|
"github.com/bwmarrin/discordgo"
|
|
)
|
|
|
|
type chatCommandType string
|
|
|
|
var (
|
|
chatCommandChatting chatCommandType = "하기"
|
|
chatCommandList chatCommandType = "목록"
|
|
chatCommandCreate chatCommandType = "생성"
|
|
chatCommandDelete chatCommandType = "삭제"
|
|
)
|
|
|
|
var ChatCommand *Command = &Command{
|
|
ApplicationCommand: &discordgo.ApplicationCommand{
|
|
Name: "대화",
|
|
Description: "이 봇이랑 대화해요.",
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Name: string(chatCommandList),
|
|
Description: "채팅 목록을 나열해요.",
|
|
},
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Name: string(chatCommandCreate),
|
|
Description: "새로운 채팅을 생성해요.",
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionString,
|
|
Name: "이름",
|
|
Description: "채팅의 이름을 정해요. (25자 이내)",
|
|
MaxLength: 25,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Name: string(chatCommandChatting),
|
|
Description: "이 봇이랑 대화해요.",
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionString,
|
|
Name: "내용",
|
|
Description: "대화할 내용",
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionSubCommand,
|
|
Name: string(chatCommandDelete),
|
|
Description: "채팅을 삭제해요.",
|
|
Options: []*discordgo.ApplicationCommandOption{
|
|
{
|
|
Type: discordgo.ApplicationCommandOptionString,
|
|
Name: "제목",
|
|
Description: "채팅의 제목",
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Aliases: []string{"채팅"},
|
|
DetailedDescription: &DetailedDescription{
|
|
Usage: fmt.Sprintf("%s대화 (목록/생성) [채팅 이름]", configs.Config.Bot.Prefix),
|
|
Examples: []string{
|
|
fmt.Sprintf("%s대화 목록", configs.Config.Bot.Prefix),
|
|
fmt.Sprintf("%s대화 생성 머핀 냠냠", configs.Config.Bot.Prefix),
|
|
},
|
|
},
|
|
Category: Chatting,
|
|
RegisterApplicationCommand: true,
|
|
RegisterMessageCommand: true,
|
|
Flags: CommandFlagsIsRegistered | CommandFlagsIsBlocked,
|
|
ChatInputRun: func(ctx *ChatInputContext) error {
|
|
ctx.Inter.DeferReply(nil)
|
|
|
|
var cType chatCommandType
|
|
var str string
|
|
|
|
if opt, ok := ctx.Inter.Options[string(chatCommandChatting)]; ok {
|
|
ctx.Inter.DeferReply(nil)
|
|
cType = chatCommandChatting
|
|
str = opt.Options[0].StringValue()
|
|
} else if opt, ok := ctx.Inter.Options[string(chatCommandCreate)]; ok {
|
|
ctx.Inter.DeferReply(&discordgo.InteractionResponseData{
|
|
Flags: discordgo.MessageFlagsEphemeral,
|
|
})
|
|
cType = chatCommandCreate
|
|
str = opt.Options[0].StringValue()
|
|
} else if _, ok := ctx.Inter.Options[string(chatCommandList)]; ok {
|
|
ctx.Inter.DeferReply(nil)
|
|
cType = chatCommandList
|
|
} else if _, ok := ctx.Inter.Options[string(chatCommandDelete)]; ok {
|
|
ctx.Inter.DeferReply(nil)
|
|
cType = chatCommandDelete
|
|
str = opt.Options[0].StringValue()
|
|
}
|
|
return chatCommandRun(cType, ctx.Inter, ctx.Inter.User, str)
|
|
},
|
|
MessageRun: func(ctx *MsgContext) error {
|
|
if len((*ctx.Args)) < 1 {
|
|
goto RequiredValue
|
|
}
|
|
|
|
switch (*ctx.Args)[0] {
|
|
case string(chatCommandCreate):
|
|
if len((*ctx.Args)) < 2 {
|
|
return utils.NewMessageSender(ctx.Msg).
|
|
AddComponents(utils.GetErrorContainer(discordgo.TextDisplay{Content: "채팅방의 이름을 정해야해요."})).
|
|
SetComponentsV2(true).
|
|
SetReply(true).
|
|
Send()
|
|
}
|
|
return chatCommandRun(chatCommandCreate, ctx.Msg, ctx.Msg.Author, string([]rune(strings.Join((*ctx.Args)[1:], " "))[:25]))
|
|
case string(chatCommandList):
|
|
return chatCommandRun(chatCommandList, ctx.Msg, ctx.Msg.Author, "")
|
|
case string(chatCommandDelete):
|
|
if len((*ctx.Args)) < 2 {
|
|
return utils.NewMessageSender(ctx.Msg).
|
|
AddComponents(utils.GetErrorContainer(discordgo.TextDisplay{Content: "채팅방의 이름을 적어야해요."})).
|
|
SetComponentsV2(true).
|
|
SetReply(true).
|
|
Send()
|
|
}
|
|
return chatCommandRun(chatCommandCreate, ctx.Msg, ctx.Msg.Author, strings.Join((*ctx.Args)[1:], " "))
|
|
default:
|
|
goto RequiredValue
|
|
}
|
|
|
|
RequiredValue:
|
|
return utils.NewMessageSender(ctx.Msg).
|
|
AddComponents(utils.GetErrorContainer(discordgo.TextDisplay{Content: "명령어의 첫번째 인자는 `생성`, `목록`중에 하나여야 해요."})).
|
|
SetComponentsV2(true).
|
|
SetReply(true).
|
|
Send()
|
|
},
|
|
}
|
|
|
|
func chatCommandRun(cType chatCommandType, m any, user *discordgo.User, contentOrName string) error {
|
|
switch cType {
|
|
// 채팅하기는 슬래시 커맨드만 가능
|
|
case chatCommandChatting:
|
|
i := m.(*utils.InteractionCreate)
|
|
|
|
str, err := chatbot.ChatBot.GetResponse(user, contentOrName)
|
|
if err != nil {
|
|
log.Println(err)
|
|
i.EditReply(&utils.InteractionEdit{
|
|
Content: &str,
|
|
})
|
|
return nil
|
|
}
|
|
|
|
result := chatbot.ParseResult(str, i.Session, i)
|
|
return i.EditReply(&utils.InteractionEdit{
|
|
Content: &result,
|
|
})
|
|
case chatCommandCreate:
|
|
_, err := databases.CreateChat(user.ID, contentOrName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return utils.NewMessageSender(m).
|
|
AddComponents(utils.GetSuccessContainer(discordgo.TextDisplay{Content: fmt.Sprintf("%s를 생성했어요. 이제 현재 채팅은 %s에요.", contentOrName, contentOrName)})).
|
|
SetComponentsV2(true).
|
|
SetReply(true).
|
|
Send()
|
|
case chatCommandList:
|
|
var data []databases.Chat
|
|
var sections []discordgo.Section
|
|
var containers []*discordgo.Container
|
|
|
|
cur, err := databases.Database.Chats.Find(context.TODO(), databases.Chat{UserId: user.ID})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = cur.All(context.TODO(), &data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(data) == 0 {
|
|
return utils.NewMessageSender(m).
|
|
AddComponents(utils.GetErrorContainer(discordgo.TextDisplay{Content: "채팅이 단 하나도 없어요. 새로운 채팅을 만들거나, 대화를 시작해 채팅을 만들어주세요."})).
|
|
SetComponentsV2(true).
|
|
SetReply(true).
|
|
SetEphemeral(true).
|
|
Send()
|
|
}
|
|
|
|
for i, data := range data {
|
|
sections = append(sections, discordgo.Section{
|
|
Accessory: discordgo.Button{
|
|
Label: "선택",
|
|
Style: discordgo.SuccessButton,
|
|
CustomID: utils.MakeSelectChat(data.Id.Hex(), i+1, user.ID),
|
|
},
|
|
Components: []discordgo.MessageComponent{
|
|
discordgo.TextDisplay{
|
|
Content: fmt.Sprintf("%d. %s\n", i+1, data.Name),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
textDisplay := discordgo.TextDisplay{Content: fmt.Sprintf("### %s님의 채팅목록", user.GlobalName)}
|
|
container := &discordgo.Container{Components: []discordgo.MessageComponent{textDisplay}}
|
|
for i, section := range sections {
|
|
container.Components = append(container.Components, section, discordgo.Separator{})
|
|
|
|
if (i+1)%10 == 0 {
|
|
containers = append(containers, container)
|
|
container = &discordgo.Container{Components: []discordgo.MessageComponent{textDisplay}}
|
|
continue
|
|
}
|
|
}
|
|
|
|
if len(container.Components) > 1 {
|
|
containers = append(containers, container)
|
|
}
|
|
|
|
return utils.PaginationEmbedBuilder(m).
|
|
AddContainers(containers...).
|
|
Start()
|
|
case chatCommandDelete:
|
|
var data []databases.Chat
|
|
|
|
cur, err := databases.Database.Chats.Find(context.TODO(), databases.Chat{Name: contentOrName})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = cur.All(context.TODO(), &data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(data) == 0 {
|
|
return utils.NewMessageSender(m).
|
|
AddComponents(utils.GetErrorContainer(discordgo.TextDisplay{Content: "해당하는 채팅을 찾을 수 없어요."})).
|
|
SetComponentsV2(true).
|
|
SetReply(true).
|
|
Send()
|
|
}
|
|
|
|
if len(data) > 1 {
|
|
//TODO: 이름이 같은 채팅이 여러개일때
|
|
return nil
|
|
}
|
|
|
|
return utils.NewMessageSender(m).
|
|
AddComponents(discordgo.Container{
|
|
Components: []discordgo.MessageComponent{
|
|
discordgo.TextDisplay{Content: fmt.Sprintf("### 채팅 %s 삭제", contentOrName)},
|
|
discordgo.TextDisplay{Content: "이 채팅방을 삭제하면 이 채팅방의 내역을 다시는 못 써요."},
|
|
discordgo.ActionsRow{
|
|
Components: []discordgo.MessageComponent{
|
|
discordgo.Button{
|
|
Label: "삭제",
|
|
Style: discordgo.DangerButton,
|
|
CustomID: utils.MakeDeleteChat(data[0].Id.Hex(), 0, user.ID),
|
|
},
|
|
discordgo.Button{
|
|
Label: "취소",
|
|
Style: discordgo.PrimaryButton,
|
|
CustomID: utils.MakeDeleteChatCancel(user.ID),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}).
|
|
SetComponentsV2(true).
|
|
SetReply(true).
|
|
Send()
|
|
}
|
|
return nil
|
|
}
|