Reorg and add services

This commit is contained in:
Dustin Pianalto
2020-10-09 21:34:47 -08:00
parent 5cd626a5a4
commit 6a33cceebb
19 changed files with 658 additions and 432 deletions
@@ -0,0 +1,73 @@
package user_management
import (
"log"
"github.com/bwmarrin/discordgo"
"github.com/dustinpianalto/goff"
"github.com/dustinpianalto/goff/internal/services"
)
func OnGuildMemberAdd(s *discordgo.Session, member *discordgo.GuildMemberAdd) {
defer func() {
if r := recover(); r != nil {
log.Println("Recovered from panic in OnGuildMemberAdd", r)
}
}()
user, err := services.UserService.User(member.User.ID)
if err != nil {
log.Println("Error getting user from database: ", err)
user = &goff.User{
ID: member.User.ID,
Banned: false,
Logging: true,
IsActive: true,
IsStaff: false,
IsAdmin: false,
}
err := services.UserService.CreateUser(user)
if err != nil {
log.Println("Error adding user to database: ", err)
}
}
if !user.IsActive {
user.IsActive = true
err = services.UserService.UpdateUser(user)
if err != nil {
log.Println("Error marking user as active: ", err)
}
}
err = services.UserService.AddUserToGuild(user, &goff.Guild{ID: member.GuildID})
if err != nil {
log.Println("Error adding user to guild: ", err)
}
}
func OnGuildMemberRemove(s *discordgo.Session, member *discordgo.GuildMemberRemove) {
defer func() {
if r := recover(); r != nil {
log.Println("Recovered from panic in OnGuildMemberRemove: ", r)
}
}()
user, err := services.UserService.User(member.User.ID)
if err != nil {
log.Println("Error getting user from database: ", err)
return
}
err = services.UserService.RemoveUserFromGuild(user, &goff.Guild{ID: member.GuildID})
if err != nil {
log.Println("Error removing user from guild: ", err)
}
for i, g := range user.Guilds {
if g == member.GuildID {
user.Guilds[len(user.Guilds)-1], user.Guilds[i] = user.Guilds[i], user.Guilds[len(user.Guilds)-1]
user.Guilds = user.Guilds[:len(user.Guilds)-1]
}
}
if len(user.Guilds) == 0 {
err = services.UserService.MarkUserInactive(user)
if err != nil {
log.Println("Error marking user as inactive: ", err)
}
}
}
@@ -0,0 +1,167 @@
package user_management
import (
"fmt"
"log"
"strconv"
"time"
"github.com/bwmarrin/discordgo"
"github.com/dustinpianalto/goff/internal/discord_utils"
"github.com/dustinpianalto/goff/internal/postgres"
)
func OnGuildMemberAddLogging(s *discordgo.Session, member *discordgo.GuildMemberAdd) {
defer func() {
if r := recover(); r != nil {
log.Println("Recovered from panic in OnGuildMemberAddLogging", r)
}
}()
var channelID string
row := postgres.DB.QueryRow("SELECT logging_channel FROM guilds where id=$1", member.GuildID)
err := row.Scan(&channelID)
if err != nil || channelID == "" {
return
}
guild, err := s.State.Guild(member.GuildID)
if err != nil {
log.Println(err)
return
}
var title string
if member.User.Bot {
title = "Bot Joined"
} else {
title = "Member Joined"
}
thumb := &discordgo.MessageEmbedThumbnail{
URL: member.User.AvatarURL(""),
}
int64ID, _ := strconv.ParseInt(member.User.ID, 10, 64)
snow := discord_utils.ParseSnowflake(int64ID)
field := &discordgo.MessageEmbedField{
Name: "User was created:",
Value: discord_utils.ParseDateString(snow.CreationTime),
Inline: false,
}
joinTime, _ := member.JoinedAt.Parse()
embed := &discordgo.MessageEmbed{
Title: title,
Description: fmt.Sprintf("%v (%v) Has Joined the Server", member.User.Mention(), member.User.ID),
Color: 0x0cc56a,
Thumbnail: thumb,
Footer: &discordgo.MessageEmbedFooter{
Text: fmt.Sprintf("Current Member Count: %v", guild.MemberCount),
IconURL: guild.IconURL(),
},
Timestamp: joinTime.Format(time.RFC3339),
Fields: []*discordgo.MessageEmbedField{field},
}
s.ChannelMessageSendEmbed(channelID, embed)
}
func OnGuildMemberRemoveLogging(s *discordgo.Session, member *discordgo.GuildMemberRemove) {
defer func() {
if r := recover(); r != nil {
log.Println("Recovered from panic in OnGuildMemberAddLogging", r)
}
}()
timeNow := time.Now()
var channelID string
row := postgres.DB.QueryRow("SELECT logging_channel FROM guilds where id=$1", member.GuildID)
err := row.Scan(&channelID)
if err != nil || channelID == "" {
return
}
guild, err := s.State.Guild(member.GuildID)
if err != nil {
log.Println(err)
return
}
var title string
if member.User.Bot {
title = "Bot Left"
} else {
title = "Member Left"
}
thumb := &discordgo.MessageEmbedThumbnail{
URL: member.User.AvatarURL(""),
}
desc := ""
al, err := s.GuildAuditLog(member.GuildID, "", "", 20, 1)
if err != nil {
log.Println(err)
} else {
for _, log := range al.AuditLogEntries {
if log.TargetID == member.User.ID {
int64ID, _ := strconv.ParseInt(log.ID, 10, 64)
logSnow := discord_utils.ParseSnowflake(int64ID)
if timeNow.Sub(logSnow.CreationTime).Seconds() <= 10 {
user, err := s.User(log.UserID)
if err == nil {
desc = fmt.Sprintf("%v (%v) was Kicked by: %v\nReason: %v", member.User.String(), member.User.ID, user.String(), log.Reason)
} else {
desc = fmt.Sprintf("%v (%v) was Kicked by: %v\nReason: %v", member.User.String(), member.User.ID, log.UserID, log.Reason)
}
break
}
}
}
}
if desc == "" {
desc = fmt.Sprintf("%v (%v) Has Left the Server", member.User.String(), member.User.ID)
}
embed := &discordgo.MessageEmbed{
Title: title,
Description: desc,
Color: 0xff9431,
Thumbnail: thumb,
Footer: &discordgo.MessageEmbedFooter{
Text: fmt.Sprintf("Current Member Count: %v", guild.MemberCount),
IconURL: guild.IconURL(),
},
Timestamp: timeNow.Format(time.RFC3339),
}
s.ChannelMessageSendEmbed(channelID, embed)
}
func AddMemberToDatabase(s *discordgo.Session, m *discordgo.GuildMemberAdd) {
defer func() {
if r := recover(); r != nil {
log.Println("Recovered from panic in AddMemberToDatabase", r)
}
}()
queryString := `INSERT INTO users (id, banned, logging, is_active, is_staff, is_admin)
VALUES ($1, false, false, true, false, false)`
_, err := postgres.DB.Exec(queryString, m.User.ID)
if err != nil {
log.Println(fmt.Errorf("error inserting %s into database: %w", m.User.ID, err))
return
}
log.Printf("New User: %s\n", m.User.ID)
}
func MarkMemberInactive(s *discordgo.Session, m *discordgo.GuildMemberRemove) {
defer func() {
if r := recover(); r != nil {
log.Println("Recovered from panic in MarkMemberInactive")
}
}()
queryString := `UPDATE users SET is_active = false WHERE id = $1`
_, err := postgres.DB.Exec(queryString, m.User.ID)
if err != nil {
log.Println(fmt.Errorf("error marking %s as inactive: %w", m.User.ID, err))
return
}
log.Println("User left: %s")
}
@@ -0,0 +1,286 @@
package user_management
import (
"errors"
"fmt"
"strings"
"time"
"github.com/bwmarrin/discordgo"
"github.com/dustinpianalto/disgoman"
"github.com/dustinpianalto/goff/internal/exts/logging"
)
var KickUserCommand = &disgoman.Command{
Name: "kick",
Aliases: nil,
Description: "Kicks the given user with the given reason",
OwnerOnly: false,
Hidden: false,
RequiredPermissions: disgoman.PermissionKickMembers,
Invoke: kickUserFunc,
}
func kickUserFunc(ctx disgoman.Context, args []string) {
var member *discordgo.Member
var err error
if len(ctx.Message.Mentions) > 0 {
member, err = ctx.Session.GuildMember(ctx.Guild.ID, ctx.Message.Mentions[0].ID)
} else if len(args) >= 1 {
idString := args[0]
if strings.HasPrefix(idString, "<@!") && strings.HasSuffix(idString, ">") {
idString = idString[3 : len(idString)-1]
}
member, err = ctx.Session.GuildMember(ctx.Guild.ID, idString)
} else {
err = errors.New("that is not a valid id")
}
if err != nil {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: "Couldn't get that member",
Error: err,
}
return
}
if higher, _ := disgoman.HasHigherRole(ctx.Session, ctx.Guild.ID, ctx.Message.Author.ID, member.User.ID); !higher {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: "You must have a higher role than the person you are trying to kick",
Error: errors.New("need higher role"),
}
return
}
if higher, _ := disgoman.HasHigherRole(ctx.Session, ctx.Guild.ID, ctx.Session.State.User.ID, member.User.ID); !higher {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: "I don't have a high enough role to kick that person",
Error: errors.New("need higher role"),
}
return
}
var reason string
if len(args) > 1 {
reason = strings.Join(args[1:], " ")
} else {
reason = "No Reason Given"
}
auditReason := fmt.Sprintf("%v#%v: %v", ctx.User.Username, ctx.User.Discriminator, reason)
err = ctx.Session.GuildMemberDeleteWithReason(ctx.Guild.ID, member.User.ID, auditReason)
if err != nil {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: fmt.Sprintf("Something went wrong kicking %v", member.User.Username),
Error: err,
}
return
}
event := &logging.LogEvent{
Embed: discordgo.MessageEmbed{
Title: "User Kicked",
Description: fmt.Sprintf(
"User %v#%v was kicked by %v.\nReason: %v",
member.User.Username,
member.User.Discriminator,
ctx.Message.Author.Username,
reason),
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
Color: 0xff8c00,
},
GuildID: ctx.Guild.ID,
Session: ctx.Session,
}
logging.LoggingChannel <- event
_, _ = ctx.Send(fmt.Sprintf("User %v#%v has been kicked.", member.User.Username, member.User.Discriminator))
}
var BanUserCommand = &disgoman.Command{
Name: "ban",
Aliases: []string{"ban-no-delete"},
Description: "Bans the given user with the given reason",
OwnerOnly: false,
Hidden: false,
RequiredPermissions: disgoman.PermissionBanMembers,
Invoke: banUserFunc,
}
func banUserFunc(ctx disgoman.Context, args []string) {
var user *discordgo.User
var err error
if len(ctx.Message.Mentions) > 0 {
user, err = ctx.Session.User(ctx.Message.Mentions[0].ID)
} else if len(args) >= 1 {
idString := args[0]
if strings.HasPrefix(idString, "<@!") && strings.HasSuffix(idString, ">") {
idString = idString[3 : len(idString)-1]
}
user, err = ctx.Session.User(idString)
} else {
err = errors.New("that is not a valid id")
}
if err != nil {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: "Couldn't get that user",
Error: err,
}
return
}
if higher, err := disgoman.HasHigherRole(ctx.Session, ctx.Guild.ID, ctx.Message.Author.ID, user.ID); err != nil {
if err.Error() == "can't find caller member" {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: "Who are you?",
Error: err,
}
return
}
} else if !higher {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: "You must have a higher role than the person you are trying to ban",
Error: errors.New("need higher role"),
}
return
}
if higher, err := disgoman.HasHigherRole(ctx.Session, ctx.Guild.ID, ctx.Session.State.User.ID, user.ID); err != nil {
if err.Error() == "can't find caller member" {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: "Who am I?",
Error: err,
}
return
}
} else if !higher {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: "I don't have a high enough role to ban that person",
Error: errors.New("need higher role"),
}
return
}
var reason string
if len(args) > 1 {
reason = strings.Join(args[1:], " ")
} else {
reason = "No Reason Given"
}
auditReason := fmt.Sprintf("%v#%v: %v", ctx.User.Username, ctx.User.Discriminator, reason)
days := 7
if ctx.Invoked == "ban-no-delete" {
days = 0
}
err = ctx.Session.GuildBanCreateWithReason(ctx.Guild.ID, user.ID, auditReason, days)
if err != nil {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: fmt.Sprintf("Something went wrong banning %v", user.Username),
Error: err,
}
return
}
event := &logging.LogEvent{
Embed: discordgo.MessageEmbed{
Title: "User Banned",
Description: fmt.Sprintf(
"User %v#%v was banned by %v.\nReason: %v",
user.Username,
user.Discriminator,
ctx.Message.Author.Username,
reason),
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
Color: 0xff0000,
},
GuildID: ctx.Guild.ID,
Session: ctx.Session,
}
logging.LoggingChannel <- event
_, _ = ctx.Send(fmt.Sprintf("User %v#%v has been banned.", user.Username, user.Discriminator))
}
var UnbanUserCommand = &disgoman.Command{
Name: "unban",
Aliases: nil,
Description: "Unbans the given user",
OwnerOnly: false,
Hidden: false,
RequiredPermissions: disgoman.PermissionBanMembers,
Invoke: unbanUserFunc,
}
func unbanUserFunc(ctx disgoman.Context, args []string) {
var user *discordgo.User
var err error
if len(ctx.Message.Mentions) > 0 {
user, err = ctx.Session.User(ctx.Message.Mentions[0].ID)
} else if len(args) >= 1 {
idString := args[0]
if strings.HasPrefix(idString, "<@!") && strings.HasSuffix(idString, ">") {
idString = idString[3 : len(idString)-1]
}
user, err = ctx.Session.User(idString)
} else {
err = errors.New("that is not a valid id")
}
if err != nil {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: "Couldn't get that user",
Error: err,
}
return
}
bans, err := ctx.Session.GuildBans(ctx.Guild.ID)
if err != nil {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: "Error processing current bans",
Error: err,
}
return
}
for _, ban := range bans {
if ban.User.ID == user.ID {
err = ctx.Session.GuildBanDelete(ctx.Guild.ID, user.ID)
if err != nil {
ctx.CommandManager.ErrorChannel <- disgoman.CommandError{
Context: ctx,
Message: fmt.Sprintf("Something went wrong unbanning %v", user.Username),
Error: err,
}
return
}
event := &logging.LogEvent{
Embed: discordgo.MessageEmbed{
Title: "User Banned",
Description: fmt.Sprintf(
"User %v#%v was unbanned by %v.\nOrignal Ban Reason: %v",
user.Username,
user.Discriminator,
ctx.Message.Author.Username,
ban.Reason),
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
Color: 0x00ff00,
},
GuildID: ctx.Guild.ID,
Session: ctx.Session,
}
logging.LoggingChannel <- event
_, _ = ctx.Send(fmt.Sprintf("User %v#%v has been unbanned.", user.Username, user.Discriminator))
return
}
}
_, _ = ctx.Send(fmt.Sprintf("%v#%v is not banned in this guild.", user.Username, user.Discriminator))
}