Documentation ¶
Index ¶
- Constants
- Variables
- func AddMemberMuteRole(config *Config, id int64, currentRoles []int64) (removedRoles []int64, err error)
- func AdvancedDeleteMessages(guildID, channelID int64, triggerID int64, filterUser int64, regex string, ...) (int, error)
- func BanUser(config *Config, guildID int64, channel *dstate.ChannelState, ...) error
- func BanUserWithDuration(config *Config, guildID int64, channel *dstate.ChannelState, ...) error
- func CreateLogs(guildID, channelID int64, user *discordgo.User) string
- func CreateModlogEmbed(config *Config, author *discordgo.User, action ModlogAction, ...) error
- func DeleteMessages(guildID, channelID int64, filterUser int64, deleteNum, fetchNum int) (int, error)
- func FindAuditLogEntry(guildID int64, typ discordgo.AuditLogAction, targetUser int64, ...) (author *discordgo.User, entry *discordgo.AuditLogEntry)
- func FindRole(gs *dstate.GuildSet, roleS string) *discordgo.Role
- func GenericCmdResp(action ModlogAction, target *discordgo.User, duration time.Duration, ...) string
- func HandleChannelCreateUpdate(evt *eventsystem.EventData) (retry bool, err error)
- func HandleClearServerWarnings(w http.ResponseWriter, r *http.Request) (web.TemplateData, error)
- func HandleGuildBanAddRemove(evt *eventsystem.EventData)
- func HandleGuildCreate(evt *eventsystem.EventData)
- func HandleGuildMemberRemove(evt *eventsystem.EventData) (retry bool, err error)
- func HandleGuildMemberTimeoutChange(evt *eventsystem.EventData) (retry bool, err error)
- func HandleGuildMemberUpdate(evt *eventsystem.EventData) (retry bool, err error)
- func HandleMemberJoin(evt *eventsystem.EventData) (retry bool, err error)
- func HandleModeration(w http.ResponseWriter, r *http.Request) (web.TemplateData, error)
- func HandlePostModeration(w http.ResponseWriter, r *http.Request) (web.TemplateData, error)
- func HandleRefreshMuteOverrides(evt *pubsub.Event)
- func HandleRefreshMuteOverridesCreateRole(evt *pubsub.Event)
- func KickUser(config *Config, guildID int64, channel *dstate.ChannelState, ...) error
- func LockMemberMuteMW(next eventsystem.HandlerFunc) eventsystem.HandlerFunc
- func LockMute(uID int64)
- func MBaseCmdSecond(cmdData *dcmd.Data, reason string, reasonArgOptional bool, neededPerm int64, ...) (oreason string, err error)
- func MuteUnmuteUser(config *Config, mute bool, guildID int64, channel *dstate.ChannelState, ...) error
- func PaginateWarnings(parsed *dcmd.Data) ...
- func RedisKeyBannedUser(guildID, userID int64) string
- func RedisKeyLockedMute(guildID, userID int64) string
- func RedisKeyMutedUser(guildID, userID int64) string
- func RedisKeyUnbannedUser(guildID, userID int64) string
- func RefreshMuteOverrideForChannel(config *Config, channel dstate.ChannelState)
- func RefreshMuteOverrides(guildID int64, createRole bool)
- func RegisterPlugin()
- func RemoveMemberMuteRole(config *Config, id int64, currentRoles []int64, mute MuteModel) (err error)
- func RemoveTimeout(config *Config, guildID int64, author *discordgo.User, reason string, ...) error
- func SafeArgString(data *dcmd.Data, arg int) string
- func TimeoutUser(config *Config, guildID int64, channel *dstate.ChannelState, ...) error
- func UnbanUser(config *Config, guildID int64, author *discordgo.User, reason string, ...) (bool, error)
- func UnlockMute(uID int64)
- func WarnUser(config *Config, guildID int64, channel *dstate.ChannelState, ...) error
- type Config
- type ContextKey
- type ModlogAction
- type MuteModel
- type Plugin
- func (p *Plugin) AddCommands()
- func (p *Plugin) AllFeatureFlags() []string
- func (p *Plugin) BotInit()
- func (p *Plugin) InitWeb()
- func (p *Plugin) LoadServerHomeWidget(w http.ResponseWriter, r *http.Request) (web.TemplateData, error)
- func (p *Plugin) PluginInfo() *common.PluginInfo
- func (p *Plugin) ShardMigrationReceive(evt dshardorchestrator.EventType, data interface{})
- func (p *Plugin) UpdateFeatureFlags(guildID int64) ([]string, error)
- type Punishment
- type ScheduledUnbanData
- type ScheduledUnmuteData
- type WarnRankEntry
- type WarningModel
Constants ¶
View Source
const ( ActionMuted = "Muted" ActionUnMuted = "Unmuted" ActionKicked = "Kicked" ActionBanned = "Banned" ActionUnbanned = "Unbanned" ActionWarned = "Warned" )
View Source
const DefaultDMMessage = "You have been {{.ModAction}}\n**Reason:** {{.Reason}}"
View Source
const DefaultTimeoutDuration = 10 * time.Minute
View Source
const (
ErrNoMuteRole = errors.Sentinel("No mute role")
)
View Source
const MaxTimeOutDuration = 40320 * time.Minute
View Source
const MinTimeOutDuration = time.Minute
View Source
const MuteDeniedChannelPerms = discordgo.PermissionSendMessages | discordgo.PermissionVoiceSpeak | discordgo.PermissionUsePublicThreads | discordgo.PermissionUsePrivateThreads | discordgo.PermissionSendMessagesInThreads
Variables ¶
View Source
var ( MAMute = ModlogAction{Prefix: "Muted", Emoji: "🔇", Color: 0x57728e} MAUnmute = ModlogAction{Prefix: "Unmuted", Emoji: "🔊", Color: 0x62c65f} MAKick = ModlogAction{Prefix: "Kicked", Emoji: "👢", Color: 0xf2a013} MABanned = ModlogAction{Prefix: "Banned", Emoji: "🔨", Color: 0xd64848} MAUnbanned = ModlogAction{Prefix: "Unbanned", Emoji: "🔓", Color: 0x62c65f} MAWarned = ModlogAction{Prefix: "Warned", Emoji: "⚠", Color: 0xfca253} MATimeoutAdded = ModlogAction{Prefix: "Timed out", Emoji: "⏱", Color: 0x9b59b6} MATimeoutRemoved = ModlogAction{Prefix: "Timeout removed from", Emoji: "⏱", Color: 0x9b59b6} MAGiveRole = ModlogAction{Prefix: "", Emoji: "➕", Color: 0x53fcf9} MARemoveRole = ModlogAction{Prefix: "", Emoji: "➖", Color: 0x53fcf9} )
View Source
var ActionMap = map[string]string{ MAMute.Prefix: "Mute DM", MAUnmute.Prefix: "Unmute DM", MAKick.Prefix: "Kick DM", MABanned.Prefix: "Ban DM", MAWarned.Prefix: "Warn DM", MATimeoutAdded.Prefix: "Timeout DM", }
View Source
var (
ErrFailedPerms = errors.New("Failed retrieving perms")
)
View Source
var ModerationCommands = []*commands.YAGCommand{ { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "Ban", Aliases: []string{"banid"}, Description: "Bans a member, specify number of days of messages to delete with -ddays (0 to 7)", RequiredArgs: 1, Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID}, {Name: "Duration", Type: &commands.DurationArg{}, Default: time.Duration(0)}, {Name: "Reason", Type: dcmd.String}, }, ArgSwitches: []*dcmd.ArgDef{ {Name: "ddays", Help: "Number of days of messages to delete", Type: dcmd.Int}, }, RequiredDiscordPermsHelp: "BanMembers or ManageServer", RequireBotPerms: [][]int64{{discordgo.PermissionAdministrator}, {discordgo.PermissionManageServer}, {discordgo.PermissionBanMembers}}, ArgumentCombos: [][]int{{0, 1, 2}, {0, 2, 1}, {0, 1}, {0, 2}, {0}}, SlashCommandEnabled: true, DefaultEnabled: false, IsResponseEphemeral: true, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, target, err := MBaseCmd(parsed, parsed.Args[0].Int64()) if err != nil { return nil, err } reason := SafeArgString(parsed, 2) reason, err = MBaseCmdSecond(parsed, reason, config.BanReasonOptional, discordgo.PermissionBanMembers, config.BanCmdRoles, config.BanEnabled) if err != nil { return nil, err } if utf8.RuneCountInString(reason) > 470 { return "Error: Reason too long (can be max 470 characters).", nil } err = checkHierarchy(parsed, parsed.Args[0].Int64()) if err != nil { return nil, err } ddays := int(config.DefaultBanDeleteDays.Int64) if parsed.Switches["ddays"].Value != nil { ddays = parsed.Switches["ddays"].Int() } banDuration := parsed.Args[1].Value.(time.Duration) var msg *discordgo.Message if parsed.TraditionalTriggerData != nil { msg = parsed.TraditionalTriggerData.Message } err = BanUserWithDuration(config, parsed.GuildData.GS.ID, parsed.GuildData.CS, msg, parsed.Author, reason, target, banDuration, ddays) if err != nil { return nil, err } return GenericCmdResp(MABanned, target, banDuration, true, false), nil }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "Unban", Aliases: []string{"unbanid"}, Description: "Unbans a user. Reason requirement is same as ban command setting.", RequiredArgs: 1, Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID}, {Name: "Reason", Type: dcmd.String}, }, RequiredDiscordPermsHelp: "BanMembers or ManageServer", RequireBotPerms: [][]int64{{discordgo.PermissionAdministrator}, {discordgo.PermissionManageServer}, {discordgo.PermissionBanMembers}}, SlashCommandEnabled: true, DefaultEnabled: false, IsResponseEphemeral: true, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, _, err := MBaseCmd(parsed, 0) if err != nil { return nil, err } reason := SafeArgString(parsed, 1) reason, err = MBaseCmdSecond(parsed, reason, config.BanReasonOptional, discordgo.PermissionBanMembers, config.BanCmdRoles, config.BanEnabled) if err != nil { return nil, err } targetID := parsed.Args[0].Int64() target := &discordgo.User{ Username: "unknown", Discriminator: "????", ID: targetID, } targetMem, _ := bot.GetMember(parsed.GuildData.GS.ID, targetID) if targetMem != nil { return "User is not banned!", nil } isNotBanned, err := UnbanUser(config, parsed.GuildData.GS.ID, parsed.Author, reason, target) if err != nil { return nil, err } if isNotBanned { return "User is not banned!", nil } return GenericCmdResp(MAUnbanned, target, 0, true, true), nil }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "Kick", Description: "Kicks a member", RequiredArgs: 1, Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID}, {Name: "Reason", Type: dcmd.String}, }, RequiredDiscordPermsHelp: "KickMembers or ManageServer", ArgSwitches: []*dcmd.ArgDef{ {Name: "cl", Help: "Messages to delete", Type: &dcmd.IntArg{Min: 1, Max: 100}}, }, RequireBotPerms: [][]int64{{discordgo.PermissionAdministrator}, {discordgo.PermissionManageServer}, {discordgo.PermissionKickMembers}}, SlashCommandEnabled: true, IsResponseEphemeral: true, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, target, err := MBaseCmd(parsed, parsed.Args[0].Int64()) if err != nil { return nil, err } reason := SafeArgString(parsed, 1) reason, err = MBaseCmdSecond(parsed, reason, config.KickReasonOptional, discordgo.PermissionKickMembers, config.KickCmdRoles, config.KickEnabled) if err != nil { return nil, err } member, err := bot.GetMember(parsed.GuildData.GS.ID, target.ID) if err != nil || member == nil { return "Member not found", err } if utf8.RuneCountInString(reason) > 470 { return "Error: Reason too long (can be max 470 characters).", nil } err = checkHierarchy(parsed, parsed.Args[0].Int64()) if err != nil { return nil, err } toDel := -1 if parsed.Switches["cl"].Value != nil { toDel = parsed.Switches["cl"].Int() } var msg *discordgo.Message if parsed.TraditionalTriggerData != nil { msg = parsed.TraditionalTriggerData.Message } err = KickUser(config, parsed.GuildData.GS.ID, parsed.GuildData.CS, msg, parsed.Author, reason, target, toDel) if err != nil { return nil, err } return GenericCmdResp(MAKick, target, 0, true, true), nil }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "Mute", Description: "Mutes a member", Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID}, {Name: "Duration", Type: &commands.DurationArg{}}, {Name: "Reason", Type: dcmd.String}, }, RequiredDiscordPermsHelp: "KickMembers or ManageServer", RequireBotPerms: [][]int64{{discordgo.PermissionAdministrator}, {discordgo.PermissionManageServer}, {discordgo.PermissionManageRoles}}, ArgumentCombos: [][]int{{0, 1, 2}, {0, 2, 1}, {0, 1}, {0, 2}, {0}}, SlashCommandEnabled: true, DefaultEnabled: false, IsResponseEphemeral: true, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, target, err := MBaseCmd(parsed, parsed.Args[0].Int64()) if err != nil { return nil, err } if config.MuteRole == "" { return fmt.Sprintf("No mute role selected. Select one at <%s/moderation>", web.ManageServerURL(parsed.GuildData)), nil } reason := parsed.Args[2].Str() reason, err = MBaseCmdSecond(parsed, reason, config.MuteReasonOptional, discordgo.PermissionKickMembers, config.MuteCmdRoles, config.MuteEnabled) if err != nil { return nil, err } d := time.Duration(config.DefaultMuteDuration.Int64) * time.Minute if parsed.Args[1].Value != nil { d = parsed.Args[1].Value.(time.Duration) } if d > 0 && d < time.Minute { d = time.Minute } logger.Info(d.Seconds()) member, err := bot.GetMember(parsed.GuildData.GS.ID, target.ID) if err != nil || member == nil { return "Member not found", err } var msg *discordgo.Message if parsed.TraditionalTriggerData != nil { msg = parsed.TraditionalTriggerData.Message } err = MuteUnmuteUser(config, true, parsed.GuildData.GS.ID, parsed.GuildData.CS, msg, parsed.Author, reason, member, int(d.Minutes())) if err != nil { return nil, err } common.BotSession.GuildMemberMove(parsed.GuildData.GS.ID, target.ID, 0) return GenericCmdResp(MAMute, target, d, true, false), nil }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "Unmute", Description: "Unmutes a member", RequiredArgs: 1, Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID}, {Name: "Reason", Type: dcmd.String}, }, RequiredDiscordPermsHelp: "KickMembers or ManageServer", RequireBotPerms: [][]int64{{discordgo.PermissionAdministrator}, {discordgo.PermissionManageServer}, {discordgo.PermissionManageRoles}}, SlashCommandEnabled: true, DefaultEnabled: false, IsResponseEphemeral: true, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, target, err := MBaseCmd(parsed, parsed.Args[0].Int64()) if err != nil { return nil, err } if config.MuteRole == "" { return "No mute role set up, assign a mute role in the control panel", nil } reason := parsed.Args[1].Str() reason, err = MBaseCmdSecond(parsed, reason, config.UnmuteReasonOptional, discordgo.PermissionKickMembers, config.MuteCmdRoles, config.MuteEnabled) if err != nil { return nil, err } member, err := bot.GetMember(parsed.GuildData.GS.ID, target.ID) if err != nil || member == nil { return "Member not found", err } var msg *discordgo.Message if parsed.TraditionalTriggerData != nil { msg = parsed.TraditionalTriggerData.Message } err = MuteUnmuteUser(config, false, parsed.GuildData.GS.ID, parsed.GuildData.CS, msg, parsed.Author, reason, member, 0) if err != nil { return nil, err } return GenericCmdResp(MAUnmute, target, 0, false, true), nil }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "Timeout", Description: "Timeout a member", Aliases: []string{"to"}, Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID}, {Name: "Duration", Type: &commands.DurationArg{}}, {Name: "Reason", Type: dcmd.String}, }, RequiredDiscordPermsHelp: "TimeoutMembers/ModerateMembers or ManageServer", RequireBotPerms: [][]int64{{discordgo.PermissionAdministrator}, {discordgo.PermissionManageServer}, {discordgo.PermissionModerateMembers}}, ArgumentCombos: [][]int{{0, 1, 2}, {0, 2, 1}, {0, 1}, {0, 2}, {0}}, SlashCommandEnabled: true, DefaultEnabled: false, IsResponseEphemeral: true, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, target, err := MBaseCmd(parsed, parsed.Args[0].Int64()) if err != nil { return nil, err } reason := parsed.Args[2].Str() reason, err = MBaseCmdSecond(parsed, reason, config.TimeoutReasonOptional, discordgo.PermissionModerateMembers, config.TimeoutCmdRoles, config.TimeoutEnabled) if err != nil { return nil, err } d := time.Duration(config.DefaultTimeoutDuration.Int64) * time.Minute if parsed.Args[1].Value != nil { d = parsed.Args[1].Value.(time.Duration) } if d < time.Minute { d = time.Minute } if d > MaxTimeOutDuration { return fmt.Sprintf("Error: Max duration of Timeouts can be %v days", (MaxTimeOutDuration.Hours() / 24)), nil } member, err := bot.GetMember(parsed.GuildData.GS.ID, target.ID) if err != nil || member == nil { return "Member not found", err } var msg *discordgo.Message if parsed.TraditionalTriggerData != nil { msg = parsed.TraditionalTriggerData.Message } err = TimeoutUser(config, parsed.GuildData.GS.ID, parsed.GuildData.CS, msg, parsed.Author, reason, &member.User, d) if err != nil { return nil, err } return GenericCmdResp(MATimeoutAdded, target, d, true, false), nil }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "RemoveTimeout", Aliases: []string{"untimeout", "cleartimeout", "deltimeout", "rto"}, Description: "Removes a member's timeout", RequiredArgs: 1, Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID}, {Name: "Reason", Type: dcmd.String}, }, RequiredDiscordPermsHelp: "TimeoutMember/ModerateMember or ManageServer", RequireBotPerms: [][]int64{{discordgo.PermissionAdministrator}, {discordgo.PermissionManageServer}, {discordgo.PermissionModerateMembers}}, SlashCommandEnabled: true, DefaultEnabled: false, IsResponseEphemeral: true, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, target, err := MBaseCmd(parsed, parsed.Args[0].Int64()) if err != nil { return nil, err } reason := parsed.Args[1].Str() reason, err = MBaseCmdSecond(parsed, reason, config.TimeoutReasonOptional, discordgo.PermissionModerateMembers, config.TimeoutCmdRoles, config.TimeoutEnabled) if err != nil { return nil, err } member, err := bot.GetMember(parsed.GuildData.GS.ID, target.ID) if err != nil || member == nil { return "Member not found", err } memberTimeout := member.Member.CommunicationDisabledUntil if memberTimeout == nil || memberTimeout.Before(time.Now()) { return "Member is not timed out", nil } err = RemoveTimeout(config, parsed.GuildData.GS.ID, parsed.Author, reason, &member.User) if err != nil { return nil, err } return GenericCmdResp(MATimeoutRemoved, target, 0, false, true), nil }, }, { CustomEnabled: true, Cooldown: 5, CmdCategory: commands.CategoryModeration, Name: "Report", Description: "Reports a member to the server's staff", RequiredArgs: 2, Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID}, {Name: "Reason", Type: dcmd.String}, }, SlashCommandEnabled: true, DefaultEnabled: false, IsResponseEphemeral: true, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, _, err := MBaseCmd(parsed, 0) if err != nil { return nil, err } _, err = MBaseCmdSecond(parsed, "", true, 0, nil, config.ReportEnabled) if err != nil { return nil, err } temp, err := bot.GetMember(parsed.GuildData.GS.ID, parsed.Args[0].Int64()) if err != nil || temp == nil { return nil, err } target := temp.User if target.ID == parsed.Author.ID { return "You can't report yourself, silly.", nil } logLink := CreateLogs(parsed.GuildData.GS.ID, parsed.GuildData.CS.ID, parsed.Author) channelID := config.IntReportChannel() if channelID == 0 { return "No report channel set up", nil } topContent := fmt.Sprintf("%s reported **%s#%s (ID %d)**", parsed.Author.Mention(), target.Username, target.Discriminator, target.ID) embed := &discordgo.MessageEmbed{ Author: &discordgo.MessageEmbedAuthor{ Name: fmt.Sprintf("%s#%s (ID %d)", parsed.Author.Username, parsed.Author.Discriminator, parsed.Author.ID), IconURL: discordgo.EndpointUserAvatar(parsed.Author.ID, parsed.Author.Avatar), }, Description: fmt.Sprintf("🔍**Reported** %s#%s *(ID %d)*\n📄**Reason:** %s ([Logs](%s))\n**Channel:** <#%d>", target.Username, target.Discriminator, target.ID, parsed.Args[1].Value, logLink, parsed.ChannelID), Color: 0xee82ee, Thumbnail: &discordgo.MessageEmbedThumbnail{ URL: discordgo.EndpointUserAvatar(target.ID, target.Avatar), }, } send := &discordgo.MessageSend{ Content: topContent, Embeds: []*discordgo.MessageEmbed{embed}, AllowedMentions: discordgo.AllowedMentions{ Parse: []discordgo.AllowedMentionType{discordgo.AllowedMentionTypeUsers}, }, } _, err = common.BotSession.ChannelMessageSendComplex(channelID, send) if err != nil { return "Something went wrong while sending your report!", err } if channelID != parsed.ChannelID || parsed.SlashCommandTriggerData != nil { return "User reported to the proper authorities!", nil } return nil, nil }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "Clean", Description: "Delete the last number of messages from chat, optionally filtering by user, max age and regex or ignoring pinned messages.", LongDescription: "Specify a regex with \"-r regex_here\" and max age with \"-ma 1h10m\"\nYou can invert the regex match (i.e. only clear messages that do not match the given regex) by supplying the `-im` flag\nNote: Will only look in the last 1k messages", Aliases: []string{"clear", "cl"}, RequiredArgs: 1, Arguments: []*dcmd.ArgDef{ {Name: "Num", Type: &dcmd.IntArg{Min: 1, Max: 100}}, {Name: "User", Type: dcmd.UserID, Default: 0}, }, ArgSwitches: []*dcmd.ArgDef{ {Name: "r", Help: "Regex", Type: dcmd.String}, {Name: "im", Help: "Invert regex match"}, {Name: "ma", Help: "Max age", Default: time.Duration(0), Type: &commands.DurationArg{}}, {Name: "minage", Help: "Min age", Default: time.Duration(0), Type: &commands.DurationArg{}}, {Name: "i", Help: "Regex case insensitive"}, {Name: "nopin", Help: "Ignore pinned messages"}, {Name: "a", Help: "Only remove messages with attachments"}, {Name: "to", Help: "Stop at this msg ID", Type: dcmd.BigInt}, }, RequiredDiscordPermsHelp: "ManageMessages or ManageServer", RequireBotPerms: [][]int64{{discordgo.PermissionAdministrator}, {discordgo.PermissionManageServer}, {discordgo.PermissionManageMessages}}, ArgumentCombos: [][]int{{0}, {0, 1}, {1, 0}}, SlashCommandEnabled: true, DefaultEnabled: false, IsResponseEphemeral: true, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, _, err := MBaseCmd(parsed, 0) if err != nil { return nil, err } _, err = MBaseCmdSecond(parsed, "", true, discordgo.PermissionManageMessages, nil, config.CleanEnabled) if err != nil { return nil, err } userFilter := parsed.Args[1].Int64() num := parsed.Args[0].Int() var triggerID int64 ignoreTrigger := parsed.Source != dcmd.TriggerSourceDM && parsed.Context().Value(commands.CtxKeyExecutedByCC) == nil if ignoreTrigger { if parsed.TriggerType == dcmd.TriggerTypeSlashCommands { m, err := common.BotSession.GetOriginalInteractionResponse(common.BotApplication.ID, parsed.SlashCommandTriggerData.Interaction.Token) if err != nil { return nil, err } triggerID = m.ID } else { triggerID = parsed.TraditionalTriggerData.Message.ID } } if num > 100 { num = 100 } if num < 1 { if num < 0 { return errors.New("Bot is having a stroke <https://www.youtube.com/watch?v=dQw4w9WgXcQ>"), nil } return errors.New("Can't delete nothing"), nil } filtered := false re := "" if parsed.Switches["r"].Value != nil { filtered = true re = parsed.Switches["r"].Str() if parsed.Switches["i"].Value != nil && parsed.Switches["i"].Value.(bool) { if !strings.HasPrefix(re, "(?i)") { re = "(?i)" + re } } } invertRegexMatch := parsed.Switch("im").Value != nil && parsed.Switch("im").Value.(bool) ma := parsed.Switches["ma"].Value.(time.Duration) if ma != 0 { filtered = true } minAge := parsed.Switches["minage"].Value.(time.Duration) if minAge != 0 { filtered = true } toID := int64(0) if parsed.Switches["to"].Value != nil { filtered = true toID = parsed.Switches["to"].Int64() } pe := false if parsed.Switches["nopin"].Value != nil && parsed.Switches["nopin"].Value.(bool) { pe = true filtered = true } attachments := false if parsed.Switches["a"].Value != nil && parsed.Switches["a"].Value.(bool) { attachments = true filtered = true } limitFetch := num if userFilter != 0 || filtered { limitFetch = num * 50 } if ignoreTrigger { limitFetch++ } if limitFetch > 1000 { limitFetch = 1000 } time.Sleep(time.Second) numDeleted, err := AdvancedDeleteMessages(parsed.GuildData.GS.ID, parsed.ChannelID, triggerID, userFilter, re, invertRegexMatch, toID, ma, minAge, pe, attachments, num, limitFetch) deleteMessageWord := "messages" if numDeleted == 1 { deleteMessageWord = "message" } return dcmd.NewTemporaryResponse(time.Second*5, fmt.Sprintf("Deleted %d %s! :')", numDeleted, deleteMessageWord), true), err }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "Reason", Description: "Add/Edit a modlog reason", RequiredArgs: 2, Arguments: []*dcmd.ArgDef{ {Name: "Message-ID", Type: dcmd.BigInt}, {Name: "Reason", Type: dcmd.String}, }, RequiredDiscordPermsHelp: "KickMembers or ManageServer", SlashCommandEnabled: true, DefaultEnabled: false, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, _, err := MBaseCmd(parsed, 0) if err != nil { return nil, err } _, err = MBaseCmdSecond(parsed, "", true, discordgo.PermissionKickMembers, nil, true) if err != nil { return nil, err } if config.ActionChannel == "" { return "No mod log channel set up", nil } msg, err := common.BotSession.ChannelMessage(config.IntActionChannel(), parsed.Args[0].Int64()) if err != nil { return nil, err } if msg.Author.ID != common.BotUser.ID { return "I didn't make that message", nil } if len(msg.Embeds) < 1 { return "This entry is either too old or you're trying to mess with me...", nil } embed := msg.Embeds[0] updateEmbedReason(parsed.Author, parsed.Args[1].Str(), embed) _, err = common.BotSession.ChannelMessageEditEmbed(config.IntActionChannel(), msg.ID, embed) if err != nil { return nil, err } return "👌", nil }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "Warn", Description: "Warns a user, warnings are saved using the bot. Use -warnings to view them.", RequiredArgs: 2, Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID}, {Name: "Reason", Type: dcmd.String}, }, RequiredDiscordPermsHelp: "ManageMessages or ManageServer", SlashCommandEnabled: true, DefaultEnabled: false, IsResponseEphemeral: true, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, target, err := MBaseCmd(parsed, parsed.Args[0].Int64()) if err != nil { return nil, err } _, err = MBaseCmdSecond(parsed, "", true, discordgo.PermissionManageMessages, config.WarnCmdRoles, config.WarnCommandsEnabled) if err != nil { return nil, err } member, err := bot.GetMember(parsed.GuildData.GS.ID, target.ID) if err != nil || member == nil { return "Member not found", err } var msg *discordgo.Message if parsed.TraditionalTriggerData != nil { msg = parsed.TraditionalTriggerData.Message } err = WarnUser(config, parsed.GuildData.GS.ID, parsed.GuildData.CS, msg, parsed.Author, target, parsed.Args[1].Str()) if err != nil { return nil, err } return GenericCmdResp(MAWarned, target, 0, false, true), nil }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "Warnings", Description: "Lists warning of a user.", Aliases: []string{"Warns"}, RequiredArgs: 1, Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID, Default: 0}, {Name: "Page", Type: &dcmd.IntArg{Max: 10000}, Default: 0}, }, ArgSwitches: []*dcmd.ArgDef{ {Name: "id", Help: "Warning ID", Type: dcmd.Int}, }, RequiredDiscordPermsHelp: "ManageMessages or ManageServer", SlashCommandEnabled: true, DefaultEnabled: false, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { var err error config, _, err := MBaseCmd(parsed, 0) if err != nil { return nil, err } _, err = MBaseCmdSecond(parsed, "", true, discordgo.PermissionManageMessages, config.WarnCmdRoles, true) if err != nil { return nil, err } if parsed.Switches["id"].Value != nil { var warn []*WarningModel err = common.GORM.Where("guild_id = ? AND id = ?", parsed.GuildData.GS.ID, parsed.Switches["id"].Int()).First(&warn).Error if err != nil && err != gorm.ErrRecordNotFound { return nil, err } if len(warn) == 0 { return fmt.Sprintf("Warning with given id : `%d` does not exist.", parsed.Switches["id"].Int()), nil } return &discordgo.MessageEmbed{ Title: fmt.Sprintf("Warning#%d - User : %s", warn[0].ID, warn[0].UserID), Description: fmt.Sprintf("<t:%d:f> - **Reason** : %s", warn[0].CreatedAt.Unix(), warn[0].Message), Footer: &discordgo.MessageEmbedFooter{Text: fmt.Sprintf("By: %s (%13s)", warn[0].AuthorUsernameDiscrim, warn[0].AuthorID)}, }, nil } page := parsed.Args[1].Int() if page < 1 { page = 1 } if parsed.Context().Value(paginatedmessages.CtxKeyNoPagination) != nil { return PaginateWarnings(parsed)(nil, page) } _, err = paginatedmessages.CreatePaginatedMessage(parsed.GuildData.GS.ID, parsed.GuildData.CS.ID, page, 0, PaginateWarnings(parsed)) return nil, err }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "EditWarning", Description: "Edit a warning, id is the first number of each warning from the warnings command", RequiredArgs: 2, Arguments: []*dcmd.ArgDef{ {Name: "Id", Type: dcmd.Int}, {Name: "NewMessage", Type: dcmd.String}, }, RequiredDiscordPermsHelp: "ManageMessages or ManageServer", SlashCommandEnabled: true, DefaultEnabled: false, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, _, err := MBaseCmd(parsed, 0) if err != nil { return nil, err } _, err = MBaseCmdSecond(parsed, "", true, discordgo.PermissionManageMessages, config.WarnCmdRoles, config.WarnCommandsEnabled) if err != nil { return nil, err } rows := common.GORM.Model(WarningModel{}).Where("guild_id = ? AND id = ?", parsed.GuildData.GS.ID, parsed.Args[0].Int()).Update( "message", fmt.Sprintf("%s (updated by %s#%s (%d))", parsed.Args[1].Str(), parsed.Author.Username, parsed.Author.Discriminator, parsed.Author.ID)).RowsAffected if rows < 1 { return "Failed updating, most likely couldn't find the warning", nil } return "👌", nil }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "DelWarning", Aliases: []string{"dw", "delwarn", "deletewarning"}, Description: "Deletes a warning, id is the first number of each warning from the warnings command", RequiredArgs: 1, Arguments: []*dcmd.ArgDef{ {Name: "Id", Type: dcmd.Int}, }, RequiredDiscordPermsHelp: "ManageMessages or ManageServer", SlashCommandEnabled: true, DefaultEnabled: false, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, _, err := MBaseCmd(parsed, 0) if err != nil { return nil, err } _, err = MBaseCmdSecond(parsed, "", true, discordgo.PermissionManageMessages, config.WarnCmdRoles, config.WarnCommandsEnabled) if err != nil { return nil, err } rows := common.GORM.Where("guild_id = ? AND id = ?", parsed.GuildData.GS.ID, parsed.Args[0].Int()).Delete(WarningModel{}).RowsAffected if rows < 1 { return "Failed deleting, most likely couldn't find the warning", nil } return "👌", nil }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "ClearWarnings", Aliases: []string{"clw"}, Description: "Clears the warnings of a user", RequiredArgs: 1, Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID}, }, RequiredDiscordPermsHelp: "ManageMessages or ManageServer", SlashCommandEnabled: true, DefaultEnabled: false, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, _, err := MBaseCmd(parsed, 0) if err != nil { return nil, err } _, err = MBaseCmdSecond(parsed, "", true, discordgo.PermissionManageMessages, config.WarnCmdRoles, config.WarnCommandsEnabled) if err != nil { return nil, err } userID := parsed.Args[0].Int64() rows := common.GORM.Where("guild_id = ? AND user_id = ?", parsed.GuildData.GS.ID, userID).Delete(WarningModel{}).RowsAffected return fmt.Sprintf("Deleted %d warnings.", rows), nil }, }, { CmdCategory: commands.CategoryModeration, Name: "TopWarnings", Aliases: []string{"topwarns"}, Description: "Shows ranked list of warnings on the server", Arguments: []*dcmd.ArgDef{ {Name: "Page", Type: dcmd.Int, Default: 0}, }, ArgSwitches: []*dcmd.ArgDef{ {Name: "id", Help: "List userIDs"}, }, RequiredDiscordPermsHelp: "ManageMessages or ManageServer", SlashCommandEnabled: true, DefaultEnabled: false, RunFunc: paginatedmessages.PaginatedCommand(0, func(parsed *dcmd.Data, p *paginatedmessages.PaginatedMessage, page int) (*discordgo.MessageEmbed, error) { showUserIDs := false config, _, err := MBaseCmd(parsed, 0) if err != nil { return nil, err } _, err = MBaseCmdSecond(parsed, "", true, discordgo.PermissionManageMessages, config.WarnCmdRoles, true) if err != nil { return nil, err } if parsed.Switches["id"].Value != nil && parsed.Switches["id"].Value.(bool) { showUserIDs = true } offset := (page - 1) * 15 entries, err := TopWarns(parsed.GuildData.GS.ID, offset, 15) if err != nil { return nil, err } if len(entries) < 1 && p != nil && p.LastResponse != nil { return nil, paginatedmessages.ErrNoResults } embed := &discordgo.MessageEmbed{ Title: "Ranked list of warnings", } out := "```\n# - Warns - User\n" for _, v := range entries { if !showUserIDs { user := v.Username if user == "" { user = "unknown ID:" + strconv.FormatInt(v.UserID, 10) } out += fmt.Sprintf("#%02d: %4d - %s\n", v.Rank, v.WarnCount, user) } else { out += fmt.Sprintf("#%02d: %4d - %d\n", v.Rank, v.WarnCount, v.UserID) } } var count int common.GORM.Table("moderation_warnings").Where("guild_id = ?", parsed.GuildData.GS.ID).Count(&count) out += "```\n" + fmt.Sprintf("Total Server Warnings: `%d`", count) embed.Description = out return embed, nil }), }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "GiveRole", Aliases: []string{"grole", "arole", "addrole"}, Description: "Gives a role to the specified member, with optional expiry", RequiredArgs: 2, Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID}, {Name: "Role", Type: &commands.RoleArg{}}, {Name: "Duration", Type: &commands.DurationArg{}, Default: time.Duration(0)}, }, RequiredDiscordPermsHelp: "ManageRoles or ManageServer", RequireBotPerms: [][]int64{{discordgo.PermissionAdministrator}, {discordgo.PermissionManageServer}, {discordgo.PermissionManageRoles}}, SlashCommandEnabled: true, DefaultEnabled: false, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, target, err := MBaseCmd(parsed, parsed.Args[0].Int64()) if err != nil { return nil, err } _, err = MBaseCmdSecond(parsed, "", true, discordgo.PermissionManageRoles, config.GiveRoleCmdRoles, config.GiveRoleCmdEnabled) if err != nil { return nil, err } member, err := bot.GetMember(parsed.GuildData.GS.ID, target.ID) if err != nil || member == nil { return "Member not found", err } role := parsed.Args[1].Value.(*discordgo.Role) if role == nil { return "Couldn't find the specified role", nil } if !bot.IsMemberAboveRole(parsed.GuildData.GS, parsed.GuildData.MS, role) { return "Can't give roles above you", nil } dur := parsed.Args[2].Value.(time.Duration) if common.ContainsInt64Slice(member.Member.Roles, role.ID) && dur <= 0 { return "That user already has that role", nil } err = common.AddRoleDS(member, role.ID) if err != nil { return nil, err } if dur > 0 { err := scheduledevents2.ScheduleRemoveRole(parsed.Context(), parsed.GuildData.GS.ID, target.ID, role.ID, time.Now().Add(dur)) if err != nil { return nil, err } } scheduledevents2.CancelAddRole(parsed.Context(), parsed.GuildData.GS.ID, parsed.Author.ID, role.ID) action := MAGiveRole action.Prefix = "Gave the role " + role.Name + " to " if config.GiveRoleCmdModlog && config.IntActionChannel() != 0 { if dur > 0 { action.Footer = "Duration: " + common.HumanizeDuration(common.DurationPrecisionMinutes, dur) } CreateModlogEmbed(config, parsed.Author, action, target, "", "") } return GenericCmdResp(action, target, dur, true, dur <= 0), nil }, }, { CustomEnabled: true, CmdCategory: commands.CategoryModeration, Name: "RemoveRole", Aliases: []string{"rrole", "takerole", "trole"}, Description: "Removes the specified role from the target", RequiredArgs: 2, Arguments: []*dcmd.ArgDef{ {Name: "User", Type: dcmd.UserID}, {Name: "Role", Type: &commands.RoleArg{}}, }, RequiredDiscordPermsHelp: "ManageRoles or ManageServer", RequireBotPerms: [][]int64{{discordgo.PermissionAdministrator}, {discordgo.PermissionManageServer}, {discordgo.PermissionManageRoles}}, SlashCommandEnabled: true, DefaultEnabled: false, RunFunc: func(parsed *dcmd.Data) (interface{}, error) { config, target, err := MBaseCmd(parsed, parsed.Args[0].Int64()) if err != nil { return nil, err } _, err = MBaseCmdSecond(parsed, "", true, discordgo.PermissionManageRoles, config.GiveRoleCmdRoles, config.GiveRoleCmdEnabled) if err != nil { return nil, err } member, err := bot.GetMember(parsed.GuildData.GS.ID, target.ID) if err != nil || member == nil { return "Member not found", err } role := parsed.Args[1].Value.(*discordgo.Role) if role == nil { return "Couldn't find the specified role", nil } if !bot.IsMemberAboveRole(parsed.GuildData.GS, parsed.GuildData.MS, role) { return "Can't remove roles above you", nil } err = common.RemoveRoleDS(member, role.ID) if err != nil { return nil, err } scheduledevents2.CancelRemoveRole(parsed.Context(), parsed.GuildData.GS.ID, parsed.Author.ID, role.ID) action := MARemoveRole action.Prefix = "Removed the role " + role.Name + " from " if config.GiveRoleCmdModlog && config.IntActionChannel() != 0 { CreateModlogEmbed(config, parsed.Author, action, target, "", "") } return GenericCmdResp(action, target, 0, true, true), nil }, }, }
View Source
var PageHTML string
Functions ¶
func AddMemberMuteRole ¶
func AdvancedDeleteMessages ¶
func BanUserWithDuration ¶
func CreateModlogEmbed ¶
func DeleteMessages ¶
func FindAuditLogEntry ¶
func FindAuditLogEntry(guildID int64, typ discordgo.AuditLogAction, targetUser int64, within time.Duration) (author *discordgo.User, entry *discordgo.AuditLogEntry)
func GenericCmdResp ¶
func HandleChannelCreateUpdate ¶
func HandleChannelCreateUpdate(evt *eventsystem.EventData) (retry bool, err error)
func HandleClearServerWarnings ¶
func HandleClearServerWarnings(w http.ResponseWriter, r *http.Request) (web.TemplateData, error)
Clear all server warnigns
func HandleGuildBanAddRemove ¶
func HandleGuildBanAddRemove(evt *eventsystem.EventData)
func HandleGuildCreate ¶
func HandleGuildCreate(evt *eventsystem.EventData)
func HandleGuildMemberRemove ¶
func HandleGuildMemberRemove(evt *eventsystem.EventData) (retry bool, err error)
func HandleGuildMemberTimeoutChange ¶ added in v2.4.0
func HandleGuildMemberTimeoutChange(evt *eventsystem.EventData) (retry bool, err error)
func HandleGuildMemberUpdate ¶
func HandleGuildMemberUpdate(evt *eventsystem.EventData) (retry bool, err error)
func HandleMemberJoin ¶
func HandleMemberJoin(evt *eventsystem.EventData) (retry bool, err error)
func HandleModeration ¶
func HandleModeration(w http.ResponseWriter, r *http.Request) (web.TemplateData, error)
HandleModeration servers the moderation page itself
func HandlePostModeration ¶
func HandlePostModeration(w http.ResponseWriter, r *http.Request) (web.TemplateData, error)
HandlePostModeration update the settings
func LockMemberMuteMW ¶
func LockMemberMuteMW(next eventsystem.HandlerFunc) eventsystem.HandlerFunc
Since updating mutes are now a complex operation with removing roles and whatnot, to avoid weird bugs from happening we lock it so it can only be updated one place per user
func MBaseCmdSecond ¶
func MuteUnmuteUser ¶
func MuteUnmuteUser(config *Config, mute bool, guildID int64, channel *dstate.ChannelState, message *discordgo.Message, author *discordgo.User, reason string, member *dstate.MemberState, duration int) error
Unmut or mute a user, ignore duration if unmuting TODO: i don't think we need to track mutes in its own database anymore now with the new scheduled event system
func PaginateWarnings ¶
func PaginateWarnings(parsed *dcmd.Data) func(p *paginatedmessages.PaginatedMessage, page int) (*discordgo.MessageEmbed, error)
func RedisKeyBannedUser ¶
func RedisKeyLockedMute ¶
func RedisKeyMutedUser ¶
func RedisKeyUnbannedUser ¶
func RefreshMuteOverrideForChannel ¶
func RefreshMuteOverrideForChannel(config *Config, channel dstate.ChannelState)
func RefreshMuteOverrides ¶
Refreshes the mute override on the channel, currently it only adds it.
func RegisterPlugin ¶
func RegisterPlugin()
func RemoveMemberMuteRole ¶
func RemoveTimeout ¶ added in v2.3.0
func TimeoutUser ¶ added in v2.3.0
func UnlockMute ¶
func UnlockMute(uID int64)
Types ¶
type Config ¶
type Config struct { configstore.GuildConfigModel // Kick command KickEnabled bool KickCmdRoles pq.Int64Array `gorm:"type:bigint[]" valid:"role,true"` DeleteMessagesOnKick bool KickReasonOptional bool KickMessage string `valid:"template,5000"` // Ban BanEnabled bool BanCmdRoles pq.Int64Array `gorm:"type:bigint[]" valid:"role,true"` BanReasonOptional bool BanMessage string `valid:"template,5000"` DefaultBanDeleteDays sql.NullInt64 `gorm:"default:1" valid:"0,7"` // Timeout TimeoutEnabled bool TimeoutCmdRoles pq.Int64Array `gorm:"type:bigint[]" valid:"role,true"` TimeoutReasonOptional bool TimeoutRemoveReasonOptional bool TimeoutMessage string `valid:"template,5000"` DefaultTimeoutDuration sql.NullInt64 `gorm:"default:10" valid:"1,40320"` // Mute/unmute MuteEnabled bool MuteCmdRoles pq.Int64Array `gorm:"type:bigint[]" valid:"role,true"` MuteRole string `valid:"role,true"` MuteDisallowReactionAdd bool MuteReasonOptional bool UnmuteReasonOptional bool MuteManageRole bool MuteRemoveRoles pq.Int64Array `gorm:"type:bigint[]" valid:"role,true"` MuteIgnoreChannels pq.Int64Array `gorm:"type:bigint[]" valid:"channel,true"` MuteMessage string `valid:"template,5000"` UnmuteMessage string `valid:"template,5000"` DefaultMuteDuration sql.NullInt64 `gorm:"default:10" valid:"0,"` // Warn WarnCommandsEnabled bool WarnCmdRoles pq.Int64Array `gorm:"type:bigint[]" valid:"role,true"` WarnIncludeChannelLogs bool WarnSendToModlog bool WarnMessage string `valid:"template,5000"` // Misc CleanEnabled bool ReportEnabled bool ActionChannel string `valid:"channel,true"` ReportChannel string `valid:"channel,true"` ErrorChannel string `valid:"channel,true"` LogUnbans bool LogBans bool LogKicks bool `gorm:"default:true"` LogTimeouts bool GiveRoleCmdEnabled bool GiveRoleCmdModlog bool GiveRoleCmdRoles pq.Int64Array `gorm:"type:bigint[]" valid:"role,true"` }
func (*Config) IntActionChannel ¶
func (*Config) IntErrorChannel ¶ added in v2.1.0
func (*Config) IntMuteRole ¶
func (*Config) IntReportChannel ¶
type ModlogAction ¶
func (ModlogAction) String ¶
func (m ModlogAction) String() string
type MuteModel ¶
type MuteModel struct { common.SmallModel ExpiresAt time.Time GuildID int64 `gorm:"index"` UserID int64 AuthorID int64 Reason string RemovedRoles pq.Int64Array `gorm:"type:bigint[]"` }
type Plugin ¶
type Plugin struct{}
func (*Plugin) AddCommands ¶
func (p *Plugin) AddCommands()
func (*Plugin) AllFeatureFlags ¶
func (*Plugin) LoadServerHomeWidget ¶
func (p *Plugin) LoadServerHomeWidget(w http.ResponseWriter, r *http.Request) (web.TemplateData, error)
func (*Plugin) PluginInfo ¶
func (p *Plugin) PluginInfo() *common.PluginInfo
func (*Plugin) ShardMigrationReceive ¶
func (p *Plugin) ShardMigrationReceive(evt dshardorchestrator.EventType, data interface{})
type Punishment ¶
type Punishment int
const ( PunishmentKick Punishment = iota PunishmentBan PunishmentTimeout )
type ScheduledUnbanData ¶
type ScheduledUnbanData struct {
UserID int64 `json:"user_id"`
}
type ScheduledUnmuteData ¶
type ScheduledUnmuteData struct {
UserID int64 `json:"user_id"`
}
type WarnRankEntry ¶
type WarningModel ¶
type WarningModel struct { common.SmallModel GuildID int64 `gorm:"index"` UserID string AuthorID string // Username and discrim for author incase he/she leaves AuthorUsernameDiscrim string Message string LogsLink string }
func (*WarningModel) TableName ¶
func (w *WarningModel) TableName() string
Click to show internal directories.
Click to hide internal directories.