Better command abstraction

This commit is contained in:
Atridad Lahiji 2024-10-22 17:07:53 -06:00
parent 0130ec538c
commit 13bf11abce
Signed by: atridad
SSH key fingerprint: SHA256:LGomp8Opq0jz+7kbwNcdfTcuaLRb5Nh0k5AchDDb438
5 changed files with 65 additions and 77 deletions

View file

@ -3,40 +3,23 @@ package command
import ( import (
"fmt" "fmt"
"himbot/lib" "himbot/lib"
"time"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
func HsCommand(s *discordgo.Session, i *discordgo.InteractionCreate) { func HsCommand(s *discordgo.Session, i *discordgo.InteractionCreate) (string, error) {
if !lib.CheckAndApplyCooldown(s, i, "hs", 10*time.Second) { options := i.ApplicationCommandData().Options
return if len(options) == 0 || options[0].Type != discordgo.ApplicationCommandOptionString {
} return "", fmt.Errorf("please provide a nickname")
}
nickname := options[0].StringValue()
options := i.ApplicationCommandData().Options user, err := lib.GetUser(i)
if len(options) == 0 || options[0].Type != discordgo.ApplicationCommandOptionString { if err != nil {
lib.RespondWithError(s, i, "Please provide a nickname.") return "", fmt.Errorf("error processing command: %w", err)
return }
}
nickname := options[0].StringValue()
user, err := lib.GetUser(i) response := fmt.Sprintf("%s was %s's nickname in high school!", nickname, user.Username)
if err != nil {
lib.RespondWithError(s, i, "Error processing command: "+err.Error())
return
}
response := fmt.Sprintf("%s was %s's nickname in high school!", nickname, user.Username) return response, nil
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: response,
},
})
if err != nil {
fmt.Println("Error responding to interaction:", err)
lib.RespondWithError(s, i, "An error occurred while processing the command")
}
} }

View file

@ -1,24 +1,15 @@
package command package command
import ( import (
"himbot/lib"
"log"
"math/rand" "math/rand"
"strings" "strings"
"time"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
func MarkovCommand(s *discordgo.Session, i *discordgo.InteractionCreate) { func MarkovCommand(s *discordgo.Session, i *discordgo.InteractionCreate) (string, error) {
if !lib.CheckAndApplyCooldown(s, i, "markov", 30*time.Second) {
return
}
// Get the channel ID from the interaction
channelID := i.ChannelID channelID := i.ChannelID
// Get the number of messages to fetch from the option
numMessages := 100 // Default value numMessages := 100 // Default value
if len(i.ApplicationCommandData().Options) > 0 { if len(i.ApplicationCommandData().Options) > 0 {
if i.ApplicationCommandData().Options[0].Name == "messages" { if i.ApplicationCommandData().Options[0].Name == "messages" {
@ -34,8 +25,7 @@ func MarkovCommand(s *discordgo.Session, i *discordgo.InteractionCreate) {
// Fetch messages // Fetch messages
allMessages, err := fetchMessages(s, channelID, numMessages) allMessages, err := fetchMessages(s, channelID, numMessages)
if err != nil { if err != nil {
lib.RespondWithError(s, i, "Failed to fetch messages: "+err.Error()) return "", err
return
} }
// Build the Markov chain from the fetched messages // Build the Markov chain from the fetched messages
@ -49,18 +39,7 @@ func MarkovCommand(s *discordgo.Session, i *discordgo.InteractionCreate) {
newMessage = "I couldn't generate a message. The channel might be empty or contain no usable text." newMessage = "I couldn't generate a message. The channel might be empty or contain no usable text."
} }
// Respond to the interaction with the generated message return newMessage, nil
err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: newMessage,
},
})
if err != nil {
log.Printf("Error responding to interaction: %v", err)
lib.RespondWithError(s, i, "An error occurred while processing the command")
}
} }
func fetchMessages(s *discordgo.Session, channelID string, numMessages int) ([]*discordgo.Message, error) { func fetchMessages(s *discordgo.Session, channelID string, numMessages int) ([]*discordgo.Message, error) {

View file

@ -1,31 +1,12 @@
package command package command
import ( import (
"fmt"
"himbot/lib"
"time"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
func PingCommand(s *discordgo.Session, i *discordgo.InteractionCreate) { func PingCommand(s *discordgo.Session, i *discordgo.InteractionCreate) (string, error) {
if !lib.CheckAndApplyCooldown(s, i, "ping", 5*time.Second) {
return
}
// Customize the response based on whether it's a guild or DM // Customize the response based on whether it's a guild or DM
responseContent := "Pong!" responseContent := "Pong!"
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ return responseContent, nil
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: responseContent,
},
})
if err != nil {
fmt.Println("Error responding to interaction:", err)
// Optionally, you could try to send an error message to the user
lib.RespondWithError(s, i, "An error occurred while processing the command")
}
} }

43
lib/command.go Normal file
View file

@ -0,0 +1,43 @@
package lib
import (
"time"
"github.com/bwmarrin/discordgo"
)
type CommandFunc func(s *discordgo.Session, i *discordgo.InteractionCreate) (string, error)
func HandleCommand(commandName string, cooldownDuration time.Duration, handler CommandFunc) func(s *discordgo.Session, i *discordgo.InteractionCreate) {
return func(s *discordgo.Session, i *discordgo.InteractionCreate) {
if !CheckAndApplyCooldown(s, i, commandName, cooldownDuration) {
return
}
// Acknowledge the interaction immediately
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
})
if err != nil {
ThrowWithError(commandName, "Error deferring response: "+err.Error())
return
}
// Execute the command handler
response, err := handler(s, i)
if err != nil {
RespondWithError(s, i, "Error processing command: "+err.Error())
return
}
// Send the follow-up message with the response
_, err = s.FollowupMessageCreate(i.Interaction, true, &discordgo.WebhookParams{
Content: response,
})
if err != nil {
ThrowWithError(commandName, "Error sending follow-up message: "+err.Error())
}
}
}

View file

@ -2,10 +2,12 @@ package main
import ( import (
"himbot/command" "himbot/command"
"himbot/lib"
"log" "log"
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
"time"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
"github.com/joho/godotenv" "github.com/joho/godotenv"
@ -44,9 +46,9 @@ var (
} }
commandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){ commandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
"ping": command.PingCommand, "ping": lib.HandleCommand("ping", 5*time.Second, command.PingCommand),
"hs": command.HsCommand, "hs": lib.HandleCommand("hs", 10*time.Second, command.HsCommand),
"markov": command.MarkovCommand, "markov": lib.HandleCommand("markov", 30*time.Second, command.MarkovCommand),
} }
) )