diff --git a/internal/discord_utils/checks.go b/internal/discord_utils/checks.go new file mode 100644 index 0000000..dc53b22 --- /dev/null +++ b/internal/discord_utils/checks.go @@ -0,0 +1,49 @@ +package discord_utils + +import ( + "github.com/dustinpianalto/disgoman" + "github.com/dustinpianalto/geeksbot" + "github.com/dustinpianalto/geeksbot/pkg/services" +) + +func IsGuildMod(ctx disgoman.Context, user geeksbot.User) bool { + discordCloser, err := ctx.Session.GuildMember(ctx.Guild.ID, user.ID) + if err != nil { + return false + } + guildRoles, err := services.GuildService.GuildRoles(geeksbot.Guild{ID: ctx.Guild.ID}) + if err != nil { + return false + } + for _, role := range guildRoles { + if role.RoleType == "moderator" { + for _, rID := range discordCloser.Roles { + if rID == role.ID { + return true + } + } + } + } + return false +} + +func IsGuildAdmin(ctx disgoman.Context, user geeksbot.User) bool { + discordCloser, err := ctx.Session.GuildMember(ctx.Guild.ID, user.ID) + if err != nil { + return false + } + guildRoles, err := services.GuildService.GuildRoles(geeksbot.Guild{ID: ctx.Guild.ID}) + if err != nil { + return false + } + for _, role := range guildRoles { + if role.RoleType == "admin" { + for _, rID := range discordCloser.Roles { + if rID == role.ID { + return true + } + } + } + } + return false +} diff --git a/internal/exts/requests/requests.go b/internal/exts/requests/requests.go index a11adf2..1032461 100644 --- a/internal/exts/requests/requests.go +++ b/internal/exts/requests/requests.go @@ -114,6 +114,12 @@ var CloseCommand = &disgoman.Command{ func closeCommandFunc(ctx disgoman.Context, args []string) { var ids []int64 + var reason string + _, err := strconv.ParseInt(args[len(args)-1], 10, 64) + if err != nil { + reason = args[len(args)-1] + args = args[0 : len(args)-1] + } for _, a := range args { a = strings.Trim(a, ",") id, err := strconv.ParseInt(a, 10, 64) @@ -132,13 +138,113 @@ func closeCommandFunc(ctx disgoman.Context, args []string) { discord_utils.SendErrorMessage(ctx, "Error getting Guild from the database", err) return } - requestMsg := strings.Join(args, " ") closer, err := services.UserService.GetOrCreateUser(ctx.Message.Author.ID) if err != nil { - discord_utils.SendErrorMessage(ctx, "Error creating the request. Could not get user.", err) + discord_utils.SendErrorMessage(ctx, "Error closing the request. Could not get user.", err) return } int64ID, _ := strconv.ParseInt(ctx.Message.ID, 10, 64) s := discord_utils.ParseSnowflake(int64ID) + for _, id := range ids { + request, err := services.RequestService.Request(id) + if err != nil || request.Guild.ID != guild.ID { + discord_utils.SendErrorMessage(ctx, fmt.Sprintf("%d is not a request in this guild.", id), err) + continue + } + if request.Author != closer && !closer.IsStaff && !closer.IsAdmin { + if !discord_utils.IsGuildMod(ctx, closer) || !discord_utils.IsGuildAdmin(ctx, closer) { + discord_utils.SendErrorMessage(ctx, fmt.Sprintf("You are not authorized to close %d", id), nil) + continue + } + } + if request.Completed { + discord_utils.SendErrorMessage(ctx, fmt.Sprintf("%d is already closed", id), err) + continue + } + request.Completed = true + request.CompletedAt.Valid = true + request.CompletedAt.Time = s.CreationTime + request.CompletedBy = &closer + if reason != "" { + request.CompletedMessage.Valid = true + request.CompletedMessage.String = reason + } + request, err = services.RequestService.UpdateRequest(request) + if err != nil { + discord_utils.SendErrorMessage(ctx, fmt.Sprintf("Error closing %d", id), err) + continue + } + _, err = ctx.Send(fmt.Sprintf("%d has been closed", request.ID)) + if err != nil { + discord_utils.SendErrorMessage(ctx, "There was an error sending the message. The request was closed.", err) + } + } +} + +var ListCommand = &disgoman.Command{ + Name: "list", + Aliases: []string{"request_list", "requests_list"}, + Description: "List your open requests or all open requests if the caller is a moderator", + OwnerOnly: false, + Hidden: false, + RequiredPermissions: 0, + Invoke: listCommandFunc, +} + +func listCommandFunc(ctx disgoman.Context, args []string) { + user, err := services.UserService.GetOrCreateUser(ctx.Message.Author.ID) + if err != nil { + discord_utils.SendErrorMessage(ctx, "Error closing the request. Could not get user.", err) + return + } + guild, err := services.GuildService.GetOrCreateGuild(ctx.Guild.ID) + if err != nil { + discord_utils.SendErrorMessage(ctx, "Error getting Guild from the database", err) + return + } + + var requests []geeksbot.Request + if discord_utils.IsGuildMod(ctx, user) || discord_utils.IsGuildAdmin(ctx, user) { + requests, err = services.RequestService.GuildRequests(guild, false) + } else { + requests, err = services.RequestService.UserRequests(user, false) + } + + for _, request := range requests { + var authorName string + author, err := ctx.Session.GuildMember(guild.ID, request.Author.ID) + if err != nil { + authorName = "Unknown" + } else { + if author.Nick == "" { + authorName = author.User.Username + } else { + authorName = author.Nick + } + } + + var channelName string + channel, err := ctx.Session.Channel(request.Channel.ID) + if err != nil { + channelName = "Unknown" + } else { + channelName = channel.Name + } + + _, _ = ctx.Send(fmt.Sprintf("```md\n"+ + "< Request ID Requested By >\n"+ + "< %11s %-23s >\n"+ + "%s\n\n"+ + "Comments: Not Implemented Yet\n"+ + "Requested At: %s\n"+ + "In: %s\n"+ + "```", + request.ID, + authorName, + request.Content, + request.RequestedAt.Format("2006-01-02 15:04:05 MST"), + channelName, + )) + } }