feat: implement server logging functionality

- Added a logging service to manage server event logs including message edits, deletions, member joins/leaves, and moderation actions.
- Introduced commands to configure logging settings, including setting the log channel and enabling/disabling logging.
- Updated the README to document the new logging features and commands.
- Enhanced moderation commands to log actions taken on members.
This commit is contained in:
2026-03-18 13:18:12 +00:00
parent 2b14079e50
commit 035e383db2
13 changed files with 883 additions and 3 deletions
@@ -5,6 +5,9 @@ import (
"strings"
"time"
"velox-bot/internal/db/services"
"velox-bot/internal/modlog"
"github.com/bwmarrin/discordgo"
)
@@ -238,6 +241,7 @@ func handlePurge(s *discordgo.Session, i *discordgo.InteractionCreate) {
return
}
respondEphemeral(s, i, "Deleted 1 message.")
sendModerationActionLog(s, i, "Purge", fmt.Sprintf("Deleted 1 message in <#%s>.", i.ChannelID), "")
return
}
@@ -247,6 +251,7 @@ func handlePurge(s *discordgo.Session, i *discordgo.InteractionCreate) {
}
respondEphemeral(s, i, fmt.Sprintf("Deleted %d messages.", len(ids)))
sendModerationActionLog(s, i, "Purge", fmt.Sprintf("Deleted %d messages in <#%s>.", len(ids), i.ChannelID), "")
}
func handleTimeout(s *discordgo.Session, i *discordgo.InteractionCreate) {
@@ -298,9 +303,11 @@ func handleTimeout(s *discordgo.Session, i *discordgo.InteractionCreate) {
if reason == "" {
respondEphemeral(s, i, fmt.Sprintf("Timed out %s for `%s`.", target.Mention(), dur.String()))
sendModerationActionLog(s, i, "Timeout", fmt.Sprintf("Target: %s\nDuration: `%s`", target.Mention(), dur.String()), "")
return
}
respondEphemeral(s, i, fmt.Sprintf("Timed out %s for `%s`. Reason: %s", target.Mention(), dur.String(), reason))
sendModerationActionLog(s, i, "Timeout", fmt.Sprintf("Target: %s\nDuration: `%s`", target.Mention(), dur.String()), reason)
}
func handleKick(s *discordgo.Session, i *discordgo.InteractionCreate) {
@@ -345,9 +352,11 @@ func handleKick(s *discordgo.Session, i *discordgo.InteractionCreate) {
if reason == "" {
respondEphemeral(s, i, "Kicked "+target.Mention()+".")
sendModerationActionLog(s, i, "Kick", "Target: "+target.Mention(), "")
return
}
respondEphemeral(s, i, "Kicked "+target.Mention()+". Reason: "+reason)
sendModerationActionLog(s, i, "Kick", "Target: "+target.Mention(), reason)
}
func handleBan(s *discordgo.Session, i *discordgo.InteractionCreate) {
@@ -399,9 +408,11 @@ func handleBan(s *discordgo.Session, i *discordgo.InteractionCreate) {
if reason == "" {
respondEphemeral(s, i, fmt.Sprintf("Banned %s (deleted %d days of messages).", target.Mention(), deleteDays))
sendModerationActionLog(s, i, "Ban", fmt.Sprintf("Target: %s\nDeleted message days: %d", target.Mention(), deleteDays), "")
return
}
respondEphemeral(s, i, fmt.Sprintf("Banned %s (deleted %d days of messages). Reason: %s", target.Mention(), deleteDays, reason))
sendModerationActionLog(s, i, "Ban", fmt.Sprintf("Target: %s\nDeleted message days: %d", target.Mention(), deleteDays), reason)
}
func handleUnban(s *discordgo.Session, i *discordgo.InteractionCreate) {
@@ -433,9 +444,11 @@ func handleUnban(s *discordgo.Session, i *discordgo.InteractionCreate) {
if reason == "" {
respondEphemeral(s, i, "Unbanned user ID `"+userID+"`.")
sendModerationActionLog(s, i, "Unban", "Target user ID: `"+userID+"`", "")
return
}
respondEphemeral(s, i, "Unbanned user ID `"+userID+"`. Reason: "+reason)
sendModerationActionLog(s, i, "Unban", "Target user ID: `"+userID+"`", reason)
}
func handleUntimeout(s *discordgo.Session, i *discordgo.InteractionCreate) {
@@ -472,9 +485,11 @@ func handleUntimeout(s *discordgo.Session, i *discordgo.InteractionCreate) {
if reason == "" {
respondEphemeral(s, i, "Removed timeout from "+target.Mention()+".")
sendModerationActionLog(s, i, "Timeout Removed", "Target: "+target.Mention(), "")
return
}
respondEphemeral(s, i, "Removed timeout from "+target.Mention()+". Reason: "+reason)
sendModerationActionLog(s, i, "Timeout Removed", "Target: "+target.Mention(), reason)
}
func handleSlowmode(s *discordgo.Session, i *discordgo.InteractionCreate) {
@@ -519,9 +534,11 @@ func handleSlowmode(s *discordgo.Session, i *discordgo.InteractionCreate) {
if seconds == 0 {
respondEphemeral(s, i, "Disabled slowmode in "+ch.Mention()+".")
sendModerationActionLog(s, i, "Slowmode", "Channel: "+ch.Mention()+"\nSet to: `0s`", "")
return
}
respondEphemeral(s, i, fmt.Sprintf("Set slowmode in %s to %d seconds.", ch.Mention(), seconds))
sendModerationActionLog(s, i, "Slowmode", fmt.Sprintf("Channel: %s\nSet to: `%ds`", ch.Mention(), seconds), "")
}
func hasPerm(i *discordgo.InteractionCreate, perm int64) bool {
@@ -538,3 +555,24 @@ func respondEphemeral(s *discordgo.Session, i *discordgo.InteractionCreate, msg
})
}
func sendModerationActionLog(s *discordgo.Session, i *discordgo.InteractionCreate, action, details, reason string) {
if services.Global == nil {
return
}
moderator := "Unknown"
if i != nil && i.Member != nil && i.Member.User != nil {
moderator = i.Member.User.Mention()
}
desc := "Moderator: " + moderator + "\n" + details
if strings.TrimSpace(reason) != "" {
desc += "\nReason: " + reason
}
embed := &discordgo.MessageEmbed{
Title: "Moderation Action: " + action,
Color: 0x5865F2,
Description: desc,
Timestamp: time.Now().Format(time.RFC3339),
}
_ = modlog.Send(s, services.Global, i.GuildID, embed)
}