feat: Add command flags

This commit is contained in:
Siwoo Jeon 2025-06-11 18:53:45 +09:00
parent c34f88f5bc
commit 71fa0b506a
Signed by: migan
GPG key ID: 036E9A8C5E8E48DA
8 changed files with 109 additions and 18 deletions

View file

@ -4,6 +4,7 @@ import (
"sync" "sync"
"git.wh64.net/muffin/goMuffin/configs" "git.wh64.net/muffin/goMuffin/configs"
"git.wh64.net/muffin/goMuffin/databases"
"git.wh64.net/muffin/goMuffin/utils" "git.wh64.net/muffin/goMuffin/utils"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
@ -17,6 +18,7 @@ type modalParse func(ctx *ModalContext) bool
type componentParse func(ctx *ComponentContext) bool type componentParse func(ctx *ComponentContext) bool
type Category string type Category string
type CommandFlags uint8
type DetailedDescription struct { type DetailedDescription struct {
Usage string Usage string
@ -30,6 +32,7 @@ type Command struct {
Category Category Category Category
RegisterApplicationCommand bool RegisterApplicationCommand bool
RegisterMessageCommand bool RegisterMessageCommand bool
Flags CommandFlags
MessageRun messageRun MessageRun messageRun
ChatInputRun chatInputRun ChatInputRun chatInputRun
} }
@ -78,6 +81,11 @@ const (
DeveloperOnly Category = "개발자 전용" DeveloperOnly Category = "개발자 전용"
) )
const (
CommandFlagsIsDeveloper CommandFlags = 1 << iota
CommandFlagsIsRegistered
)
var ( var (
commandMutex sync.Mutex commandMutex sync.Mutex
componentMutex sync.Mutex componentMutex sync.Mutex
@ -118,10 +126,15 @@ func (d *DiscommandStruct) LoadModal(m *Modal) {
d.Modals = append(d.Modals, m) d.Modals = append(d.Modals, m)
} }
func (d *DiscommandStruct) MessageRun(name string, s *discordgo.Session, m *discordgo.MessageCreate, args []string) { func (d *DiscommandStruct) MessageRun(name string, s *discordgo.Session, msg *discordgo.MessageCreate, args []string) {
if command, ok := d.Commands[name]; ok { m := &utils.MessageCreate{
if command.Category == DeveloperOnly && m.Author.ID != configs.Config.Bot.OwnerId { MessageCreate: msg,
utils.NewMessageSender(&utils.MessageCreate{MessageCreate: m, Session: s}). Session: s,
}
if command, ok := d.Commands[name]; ok && command.RegisterMessageCommand {
if command.Flags&CommandFlagsIsDeveloper != 0 && m.Author.ID != configs.Config.Bot.OwnerId {
utils.NewMessageSender(m).
AddComponents(utils.GetErrorContainer(discordgo.TextDisplay{Content: "해당 명령어는 개발자만 사용 가능해요."})). AddComponents(utils.GetErrorContainer(discordgo.TextDisplay{Content: "해당 명령어는 개발자만 사용 가능해요."})).
SetComponentsV2(true). SetComponentsV2(true).
SetReply(true). SetReply(true).
@ -129,24 +142,48 @@ func (d *DiscommandStruct) MessageRun(name string, s *discordgo.Session, m *disc
return return
} }
if !command.RegisterMessageCommand { if command.Flags&CommandFlagsIsRegistered != 0 && !databases.Database.IsUser(m.Author.ID) {
utils.NewMessageSender(m).
AddComponents(utils.GetUserIsNotRegisteredErrContainer(configs.Config.Bot.Prefix)).
SetComponentsV2(true).
SetReply(true).
Send()
return return
} }
command.MessageRun(&MsgContext{&utils.MessageCreate{ command.MessageRun(&MsgContext{m, &args, command})
MessageCreate: m,
Session: s,
}, &args, command})
} }
} }
func (d *DiscommandStruct) ChatInputRun(name string, s *discordgo.Session, i *discordgo.InteractionCreate) { func (d *DiscommandStruct) ChatInputRun(name string, s *discordgo.Session, inter *discordgo.InteractionCreate) {
i := &utils.InteractionCreate{
InteractionCreate: inter,
Session: s,
Options: utils.GetInteractionOptions(inter),
}
i.InteractionCreate.User = utils.GetInteractionUser(inter)
if command, ok := d.Commands[name]; ok && command.RegisterApplicationCommand { if command, ok := d.Commands[name]; ok && command.RegisterApplicationCommand {
command.ChatInputRun(&ChatInputContext{&utils.InteractionCreate{ if command.Flags&CommandFlagsIsDeveloper != 0 && i.User.ID != configs.Config.Bot.OwnerId {
InteractionCreate: i, utils.NewMessageSender(i).
Session: s, AddComponents(utils.GetErrorContainer(discordgo.TextDisplay{Content: "해당 명령어는 개발자만 사용 가능해요."})).
Options: utils.GetInteractionOptions(i), SetComponentsV2(true).
}, command}) SetReply(true).
Send()
return
}
if command.Flags&CommandFlagsIsRegistered != 0 && !databases.Database.IsUser(i.User.ID) {
utils.NewMessageSender(i).
AddComponents(utils.GetUserIsNotRegisteredErrContainer(configs.Config.Bot.Prefix)).
SetComponentsV2(true).
SetReply(true).
Send()
return
}
command.ChatInputRun(&ChatInputContext{i, command})
} }
} }

View file

@ -21,6 +21,7 @@ var ReloadPromptCommand *Command = &Command{
Category: DeveloperOnly, Category: DeveloperOnly,
RegisterApplicationCommand: false, RegisterApplicationCommand: false,
RegisterMessageCommand: true, RegisterMessageCommand: true,
Flags: CommandFlagsIsDeveloper,
MessageRun: func(ctx *MsgContext) { MessageRun: func(ctx *MsgContext) {
err := chatbot.ChatBot.ReloadPrompt() err := chatbot.ChatBot.ReloadPrompt()
if err != nil { if err != nil {

View file

@ -20,6 +20,7 @@ var SwitchModeCommand *Command = &Command{
Category: DeveloperOnly, Category: DeveloperOnly,
RegisterApplicationCommand: false, RegisterApplicationCommand: false,
RegisterMessageCommand: true, RegisterMessageCommand: true,
Flags: CommandFlagsIsDeveloper,
MessageRun: func(ctx *MsgContext) { MessageRun: func(ctx *MsgContext) {
chatbot.ChatBot.SwitchMode() chatbot.ChatBot.SwitchMode()

29
databases/User.go Normal file
View file

@ -0,0 +1,29 @@
package databases
import (
"context"
"time"
"go.mongodb.org/mongo-driver/v2/bson"
)
type InsertUser struct {
UserId string `bson:"user_id"`
CreatedAt time.Time `bson:"created_at"`
}
type User struct {
Id bson.ObjectID `bson:"_id"`
UserId string `bson:"user_id"`
CreatedAt time.Time `bson:"created_at"`
}
func (d *MuffinDatabase) IsUser(userId string) bool {
var user *User
d.Users.FindOne(context.TODO(), bson.D{{Key: "user_id", Value: userId}}).Decode(&user)
if user != nil {
return true
}
return false
}

View file

@ -13,6 +13,7 @@ type MuffinDatabase struct {
Learns *mongo.Collection Learns *mongo.Collection
Texts *mongo.Collection Texts *mongo.Collection
Memory *mongo.Collection Memory *mongo.Collection
Users *mongo.Collection
} }
var Database *MuffinDatabase var Database *MuffinDatabase
@ -36,5 +37,6 @@ func Connect() (*MuffinDatabase, error) {
Learns: client.Database(configs.Config.Database.Name).Collection("learn"), Learns: client.Database(configs.Config.Database.Name).Collection("learn"),
Texts: client.Database(configs.Config.Database.Name).Collection("text"), Texts: client.Database(configs.Config.Database.Name).Collection("text"),
Memory: client.Database(configs.Config.Database.Name).Collection("memory"), Memory: client.Database(configs.Config.Database.Name).Collection("memory"),
Users: client.Database(configs.Config.Database.Name).Collection("user"),
}, nil }, nil
} }

View file

@ -1,6 +1,10 @@
package utils package utils
import "github.com/bwmarrin/discordgo" import (
"fmt"
"github.com/bwmarrin/discordgo"
)
const ( const (
EmbedDefault int = 0xaddb87 EmbedDefault int = 0xaddb87
@ -33,3 +37,9 @@ func GetSuccessContainer(components ...discordgo.MessageComponent) *discordgo.Co
c.Components = append(c.Components, components...) c.Components = append(c.Components, components...)
return c return c
} }
func GetUserIsNotRegisteredErrContainer(prefix string) *discordgo.Container {
return GetErrorContainer(discordgo.TextDisplay{
Content: fmt.Sprintf("해당 기능은 등록된 사용자만 쓸 수 있어요. `%s가입`으로 가입해주새요.", prefix),
})
}

View file

@ -53,6 +53,17 @@ func GetInteractionOptions(i *discordgo.InteractionCreate) map[string]*discordgo
return optsMap return optsMap
} }
func GetInteractionUser(i *discordgo.InteractionCreate) *discordgo.User {
if i.Member != nil {
return i.Member.User
}
if i.User != nil {
return i.User
}
return nil
}
// DeferReply to this interaction. // DeferReply to this interaction.
func (i *InteractionCreate) DeferReply(data *discordgo.InteractionResponseData) error { func (i *InteractionCreate) DeferReply(data *discordgo.InteractionResponseData) error {
err := i.Session.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ err := i.Session.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{

View file

@ -63,7 +63,7 @@ func (s *MessageSender) Send() error {
var flags discordgo.MessageFlags var flags discordgo.MessageFlags
if s.ComponentsV2 { if s.ComponentsV2 {
flags = flags | discordgo.MessageFlagsIsComponentsV2 flags |= discordgo.MessageFlagsIsComponentsV2
} }
switch m := s.m.(type) { switch m := s.m.(type) {
@ -85,7 +85,7 @@ func (s *MessageSender) Send() error {
return err return err
case *InteractionCreate: case *InteractionCreate:
if s.Ephemeral { if s.Ephemeral {
flags = flags | discordgo.MessageFlagsEphemeral flags |= discordgo.MessageFlagsEphemeral
} }
if m.Replied || m.Deferred { if m.Replied || m.Deferred {