aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2024-11-16 21:51:29 -0500
committerBobby <[email protected]>2024-11-16 21:51:29 -0500
commitf393ac1cf42a827196318c3a119a61adf1b3d14c (patch)
treed4de5f98d9c39f00b35ca4a9daa63386a0065291
parent2cb6be7cf2c5ae6c583678c0675188fc327bc10b (diff)
downloadyuzaki-f393ac1cf42a827196318c3a119a61adf1b3d14c.tar.xz
yuzaki-f393ac1cf42a827196318c3a119a61adf1b3d14c.zip
added purge command
-rw-r--r--commands/admin/purge.go100
-rw-r--r--commands/commands.go27
-rw-r--r--config/config.go1
-rw-r--r--handlers/interactionCreateHandler.go33
-rw-r--r--utils/responder.go35
-rw-r--r--yuzaki/main.go75
6 files changed, 214 insertions, 57 deletions
diff --git a/commands/admin/purge.go b/commands/admin/purge.go
new file mode 100644
index 0000000..46b6068
--- /dev/null
+++ b/commands/admin/purge.go
@@ -0,0 +1,100 @@
+package admin
+
+import (
+ "fmt"
+ "log"
+ "time"
+
+ "yuzaki/utils"
+
+ "github.com/bwmarrin/discordgo"
+)
+
+func PurgeChat(s *discordgo.Session, i *discordgo.InteractionCreate) {
+ err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
+ Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
+ Data: &discordgo.InteractionResponseData{
+ Flags: discordgo.MessageFlagsEphemeral,
+ },
+ })
+ if err != nil {
+ log.Printf("Error responding to interaction: %s. Interaction: purge. Interaction By: %s\n", err, i.Member.DisplayName())
+ return
+ }
+
+ options := i.ApplicationCommandData().Options
+ optionMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(options))
+ for _, option := range options {
+ optionMap[option.Name] = option
+ }
+
+ option, ok := optionMap["amount"]
+ if !ok {
+ utils.SendFollowUpMessage(s, i, "You must provide an amount to purge", true)
+ return
+ }
+
+ amount := option.IntValue()
+ if amount < 1 {
+ utils.SendFollowUpMessage(s, i, "Amount must be greater than 0", true)
+ return
+ }
+
+ channel := i.ChannelID
+ remaining := amount
+ deletedCount := int64(0)
+
+ for remaining > 0 {
+ batchSize := int64(100)
+ if remaining < 100 {
+ batchSize = remaining
+ }
+
+ messages, err := s.ChannelMessages(channel, int(batchSize), "", "", "")
+ if err != nil {
+ utils.SendFollowUpMessage(s, i, "Failed to fetch messages", true)
+ return
+ }
+
+ if len(messages) == 0 {
+ break
+ }
+
+ messageIDs := make([]string, len(messages))
+ for i, message := range messages {
+ messageIDs[i] = message.ID
+ }
+
+ if len(messageIDs) > 1 {
+ err = s.ChannelMessagesBulkDelete(channel, messageIDs)
+ if err != nil {
+ for _, msgID := range messageIDs {
+ err = s.ChannelMessageDelete(channel, msgID)
+ if err != nil {
+ continue
+ }
+ deletedCount++
+ time.Sleep(time.Millisecond * 100)
+ }
+ } else {
+ deletedCount += int64(len(messageIDs))
+ }
+ } else if len(messageIDs) == 1 {
+ err = s.ChannelMessageDelete(channel, messageIDs[0])
+ if err == nil {
+ deletedCount++
+ }
+ time.Sleep(time.Millisecond * 100)
+ }
+
+ remaining -= batchSize
+ }
+
+ utils.SendFollowUpMessage(s, i, fmt.Sprintf("Successfully purged %d messages!", deletedCount), false)
+ _, err = s.ChannelMessageSend(channel, fmt.Sprintf("<@%s> has purged %d messages from this channel", i.Member.User.ID, deletedCount))
+ if err != nil {
+ log.Printf("Failed to send message after purging messages. Successfully purged %d messages from channel %s. Purged By: %s\n", deletedCount, channel, i.Member.DisplayName())
+ } else {
+ log.Printf("Successfully purged %d messages from channel %s. Purged By: %s\n", deletedCount, channel, i.Member.DisplayName())
+ }
+}
diff --git a/commands/commands.go b/commands/commands.go
new file mode 100644
index 0000000..629999f
--- /dev/null
+++ b/commands/commands.go
@@ -0,0 +1,27 @@
+package commands
+
+import (
+ "github.com/bwmarrin/discordgo"
+)
+
+var (
+ manageMessagesPermissions int64 = discordgo.PermissionManageMessages
+)
+
+var (
+ Commands = []*discordgo.ApplicationCommand{
+ {
+ Name: "purge",
+ Description: "Purge messages from the current channel",
+ DefaultMemberPermissions: &manageMessagesPermissions,
+ Options: []*discordgo.ApplicationCommandOption{
+ {
+ Type: discordgo.ApplicationCommandOptionInteger,
+ Name: "amount",
+ Description: "The amount of messages to purge",
+ Required: true,
+ },
+ },
+ },
+ }
+)
diff --git a/config/config.go b/config/config.go
index 1d78fea..44155ad 100644
--- a/config/config.go
+++ b/config/config.go
@@ -53,7 +53,6 @@ func Load() error {
return fmt.Errorf("getting POKETWO_CHANNELS: %w", err)
}
config.ConfiguredChannels.PoketwoSpawns = channels
- fmt.Println(config.ConfiguredChannels.PoketwoSpawns)
if err := validateConfig(config); err != nil {
return fmt.Errorf("validating config: %w", err)
diff --git a/handlers/interactionCreateHandler.go b/handlers/interactionCreateHandler.go
new file mode 100644
index 0000000..2d9e0e7
--- /dev/null
+++ b/handlers/interactionCreateHandler.go
@@ -0,0 +1,33 @@
+package handlers
+
+import (
+ "fmt"
+ "yuzaki/commands/admin"
+
+ "github.com/bwmarrin/discordgo"
+)
+
+var (
+ SlashCommandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
+ "purge": admin.PurgeChat,
+ }
+)
+
+func InteractionCreateHandler(s *discordgo.Session, interaction *discordgo.InteractionCreate) {
+ switch interaction.Type {
+ case discordgo.InteractionApplicationCommand:
+ if handler, ok := SlashCommandHandlers[interaction.ApplicationCommandData().Name]; ok {
+ handler(s, interaction)
+ }
+ case discordgo.InteractionMessageComponent:
+ // Detect what type of message component interaction it is.
+ switch interaction.MessageComponentData().ComponentType {
+ case discordgo.ButtonComponent:
+ fmt.Println("Button interaction detected.")
+ case discordgo.SelectMenuComponent:
+ fmt.Println("Select menu interaction detected.")
+ default:
+ fmt.Println("Unknown message component interaction detected.")
+ }
+ }
+}
diff --git a/utils/responder.go b/utils/responder.go
new file mode 100644
index 0000000..5289737
--- /dev/null
+++ b/utils/responder.go
@@ -0,0 +1,35 @@
+package utils
+
+import (
+ "log"
+
+ "github.com/bwmarrin/discordgo"
+)
+
+func SendEphemeralResponse(s *discordgo.Session, i *discordgo.InteractionCreate, message string) {
+ err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
+ Type: discordgo.InteractionResponseChannelMessageWithSource,
+ Data: &discordgo.InteractionResponseData{
+ Content: message,
+ Flags: discordgo.MessageFlagsEphemeral,
+ },
+ })
+ if err != nil {
+ log.Printf("Error sending error response: %s", err)
+ }
+}
+
+func SendFollowUpMessage(s *discordgo.Session, i *discordgo.InteractionCreate, content string, ephemeral bool) {
+ var flags discordgo.MessageFlags
+ if ephemeral {
+ flags = discordgo.MessageFlagsEphemeral
+ }
+
+ _, err := s.FollowupMessageCreate(i.Interaction, true, &discordgo.WebhookParams{
+ Content: content,
+ Flags: flags,
+ })
+ if err != nil {
+ log.Printf("Error sending followup message: %s", err)
+ }
+}
diff --git a/yuzaki/main.go b/yuzaki/main.go
index ea548b8..11e1aa3 100644
--- a/yuzaki/main.go
+++ b/yuzaki/main.go
@@ -6,6 +6,7 @@ import (
"os"
"os/signal"
"syscall"
+ "yuzaki/commands"
"yuzaki/config"
"yuzaki/handlers"
@@ -30,6 +31,7 @@ func init() {
session.Identify.Intents = discordgo.IntentsAll
session.AddHandler(ready)
session.AddHandler(handlers.MessageGatewayHandler)
+ session.AddHandler(handlers.InteractionCreateHandler)
}
func main() {
@@ -47,6 +49,9 @@ func setupAndRun(ctx context.Context) error {
}
defer session.Close()
+ log.Printf("Adding commands to %d guilds", len(session.State.Guilds))
+ addApplicationCommands(session)
+
shutdown := make(chan os.Signal, 1)
signal.Notify(shutdown, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
@@ -59,66 +64,24 @@ func setupAndRun(ctx context.Context) error {
}
}
+func addApplicationCommands(s *discordgo.Session) {
+ for _, guild := range s.State.Guilds {
+ registeredCommands, err := session.ApplicationCommandBulkOverwrite(session.State.User.ID, guild.ID, commands.Commands)
+ if err != nil {
+ log.Printf("error adding commands to guild %s: %v", guild.ID, err)
+ continue
+ }
+ log.Printf("added %d commands to guild %s", len(registeredCommands), guild.ID)
+ for _, command := range registeredCommands {
+ log.Printf("registered command %s", command.Name)
+ }
+ }
+}
+
func ready(s *discordgo.Session, event *discordgo.Ready) {
log.Printf("Logged in as %s on %d guilds", event.User.String(), len(event.Guilds))
if err := s.UpdateWatchStatus(0, "all users in Yuzaki's Canyon!"); err != nil {
log.Printf("error setting status: %v", err)
}
log.Println("Bot is now running. Press CTRL-C to exit.")
-
- // On guild 1009009522767052860, assign all users a role with role id 1307471288415162428
- // var rolesAssigned, rolesSkipped int
- // guild, err := s.Guild("1009009522767052860")
- // if err != nil {
- // log.Printf("error getting guild: %v", err)
- // return
- // }
-
- // var lastMemberID string
- // for {
- // members, err := s.GuildMembers(guild.ID, lastMemberID, 1000)
- // if err != nil {
- // log.Printf("error getting guild members: %v", err)
- // return
- // }
- // if len(members) == 0 {
- // break
- // }
-
- // for _, member := range members {
- // // skip if bot
- // if member.User.Bot {
- // continue
- // }
-
- // // Check if member already has the role
- // hasRole := false
- // for _, roleID := range member.Roles {
- // if roleID == "1307471288415162428" {
- // hasRole = true
- // break
- // }
- // }
-
- // if hasRole {
- // log.Printf("Skipping role assignment for %s (%s) - already has role", member.User.Username, member.User.ID)
- // rolesSkipped++
- // continue
- // }
-
- // if err := s.GuildMemberRoleAdd(guild.ID, member.User.ID, "1307471288415162428"); err != nil {
- // log.Printf("error adding role to %s (%s): %v", member.User.Username, member.User.ID, err)
- // continue
- // }
- // log.Printf("Assigned role to %s (%s)", member.User.Username, member.User.ID)
- // rolesAssigned++
- // }
-
- // if len(members) < 1000 {
- // break
- // }
- // lastMemberID = members[len(members)-1].User.ID
- // }
-
- // log.Printf("Operation complete: Assigned roles to %d members, skipped %d members", rolesAssigned, rolesSkipped)
}