265 lines
6.0 KiB
Go
265 lines
6.0 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/TicketsBot/GoPanel/botcontext"
|
|
dbclient "github.com/TicketsBot/GoPanel/database"
|
|
"github.com/TicketsBot/GoPanel/rpc/cache"
|
|
"github.com/TicketsBot/database"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/rxdn/gdl/objects/channel"
|
|
"github.com/rxdn/gdl/objects/interaction"
|
|
"github.com/rxdn/gdl/rest"
|
|
"golang.org/x/sync/errgroup"
|
|
)
|
|
|
|
func UpdateSettingsHandler(ctx *gin.Context) {
|
|
guildId := ctx.Keys["guildid"].(uint64)
|
|
|
|
var settings Settings
|
|
if err := ctx.BindJSON(&settings); err != nil {
|
|
ctx.AbortWithStatusJSON(400, gin.H{
|
|
"success": false,
|
|
"error": err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get a list of all channel IDs
|
|
channels := cache.Instance.GetGuildChannels(guildId)
|
|
|
|
// TODO: Errors
|
|
err := settings.updateSettings(guildId)
|
|
validPrefix := settings.updatePrefix(guildId)
|
|
validWelcomeMessage := settings.updateWelcomeMessage(guildId)
|
|
validTicketLimit := settings.updateTicketLimit(guildId)
|
|
validArchiveChannel := settings.updateArchiveChannel(channels, guildId)
|
|
validCategory := settings.updateCategory(channels, guildId)
|
|
validNamingScheme := settings.updateNamingScheme(guildId)
|
|
settings.updatePingEveryone(guildId)
|
|
settings.updateUsersCanClose(guildId)
|
|
settings.updateCloseConfirmation(guildId)
|
|
settings.updateFeedbackEnabled(guildId)
|
|
|
|
ctx.JSON(200, gin.H{
|
|
"prefix": validPrefix,
|
|
"welcome_message": validWelcomeMessage,
|
|
"ticket_limit": validTicketLimit,
|
|
"archive_channel": validArchiveChannel,
|
|
"category": validCategory,
|
|
"naming_scheme": validNamingScheme,
|
|
"error": err,
|
|
})
|
|
}
|
|
|
|
func (s *Settings) updateSettings(guildId uint64) error {
|
|
if err := s.Validate(guildId); err != nil {
|
|
return err
|
|
}
|
|
|
|
group, _ := errgroup.WithContext(context.Background())
|
|
|
|
group.Go(func() error {
|
|
return dbclient.Client.Settings.Set(guildId, s.Settings)
|
|
})
|
|
|
|
group.Go(func() error {
|
|
return setOpenCommandPermissions(guildId, s.DisableOpenCommand)
|
|
})
|
|
|
|
return group.Wait()
|
|
}
|
|
|
|
var validAutoArchive = []int{60, 1440, 4320, 10080}
|
|
|
|
func (s *Settings) Validate(guildId uint64) error {
|
|
group, _ := errgroup.WithContext(context.Background())
|
|
|
|
// Validate panel from same guild
|
|
group.Go(func() error {
|
|
if s.ContextMenuPanel != nil {
|
|
panelId := *s.ContextMenuPanel
|
|
|
|
panel, err := dbclient.Client.Panel.GetById(panelId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if guildId != panel.GuildId {
|
|
return fmt.Errorf("guild ID doesn't match")
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
group.Go(func() error {
|
|
valid := false
|
|
for _, duration := range validAutoArchive {
|
|
if duration == s.Settings.ThreadArchiveDuration {
|
|
valid = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !valid {
|
|
return fmt.Errorf("Invalid thread auto archive duration")
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
group.Go(func() error {
|
|
if s.Settings.UseThreads {
|
|
return fmt.Errorf("threads are disabled")
|
|
} else {
|
|
return nil
|
|
}
|
|
})
|
|
|
|
return group.Wait()
|
|
}
|
|
|
|
func setOpenCommandPermissions(guildId uint64, disabled bool) error {
|
|
ctx, err := botcontext.ContextForGuild(guildId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
commands, err := rest.GetGlobalCommands(ctx.Token, ctx.RateLimiter, ctx.BotId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var commandId uint64
|
|
for _, cmd := range commands {
|
|
if cmd.Name == "open" {
|
|
commandId = cmd.Id
|
|
break
|
|
}
|
|
}
|
|
|
|
if commandId == 0 {
|
|
return errors.New("open command not found")
|
|
}
|
|
|
|
data := rest.CommandWithPermissionsData{
|
|
Id: commandId,
|
|
ApplicationId: ctx.BotId,
|
|
GuildId: guildId,
|
|
Permissions: []interaction.ApplicationCommandPermissions{
|
|
{
|
|
Id: guildId,
|
|
Type: interaction.ApplicationCommandPermissionTypeRole,
|
|
Permission: !disabled,
|
|
},
|
|
},
|
|
}
|
|
|
|
_, err = rest.EditCommandPermissions(ctx.Token, ctx.RateLimiter, ctx.BotId, guildId, commandId, data)
|
|
return err
|
|
}
|
|
|
|
func (s *Settings) updatePrefix(guildId uint64) bool {
|
|
if s.Prefix == "" || len(s.Prefix) > 8 {
|
|
return false
|
|
}
|
|
|
|
go dbclient.Client.Prefix.Set(guildId, s.Prefix)
|
|
return true
|
|
}
|
|
|
|
func (s *Settings) updateWelcomeMessage(guildId uint64) bool {
|
|
if s.WelcomeMessaage == "" || len(s.WelcomeMessaage) > 1000 {
|
|
return false
|
|
}
|
|
|
|
go dbclient.Client.WelcomeMessages.Set(guildId, s.WelcomeMessaage)
|
|
return true
|
|
}
|
|
|
|
func (s *Settings) updateTicketLimit(guildId uint64) bool {
|
|
if s.TicketLimit > 10 || s.TicketLimit < 1 {
|
|
return false
|
|
}
|
|
|
|
go dbclient.Client.TicketLimit.Set(guildId, s.TicketLimit)
|
|
return true
|
|
}
|
|
|
|
func (s *Settings) updateCategory(channels []channel.Channel, guildId uint64) bool {
|
|
var valid bool
|
|
for _, ch := range channels {
|
|
if ch.Id == s.Category && ch.Type == channel.ChannelTypeGuildCategory {
|
|
valid = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !valid {
|
|
return false
|
|
}
|
|
|
|
go dbclient.Client.ChannelCategory.Set(guildId, s.Category)
|
|
return true
|
|
}
|
|
|
|
func (s *Settings) updateArchiveChannel(channels []channel.Channel, guildId uint64) bool {
|
|
if s.ArchiveChannel == nil {
|
|
go dbclient.Client.ArchiveChannel.Set(guildId, nil)
|
|
return true
|
|
}
|
|
|
|
var valid bool
|
|
for _, ch := range channels {
|
|
if ch.Id == *s.ArchiveChannel && ch.Type == channel.ChannelTypeGuildText {
|
|
valid = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !valid {
|
|
return false
|
|
}
|
|
|
|
go dbclient.Client.ArchiveChannel.Set(guildId, s.ArchiveChannel)
|
|
return true
|
|
}
|
|
|
|
var validScheme = []database.NamingScheme{database.Id, database.Username}
|
|
|
|
func (s *Settings) updateNamingScheme(guildId uint64) bool {
|
|
var valid bool
|
|
for _, scheme := range validScheme {
|
|
if scheme == s.NamingScheme {
|
|
valid = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !valid {
|
|
return false
|
|
}
|
|
|
|
go dbclient.Client.NamingScheme.Set(guildId, s.NamingScheme)
|
|
return true
|
|
}
|
|
|
|
func (s *Settings) updatePingEveryone(guildId uint64) {
|
|
go dbclient.Client.PingEveryone.Set(guildId, s.PingEveryone)
|
|
}
|
|
|
|
func (s *Settings) updateUsersCanClose(guildId uint64) {
|
|
go dbclient.Client.UsersCanClose.Set(guildId, s.UsersCanClose)
|
|
}
|
|
|
|
func (s *Settings) updateCloseConfirmation(guildId uint64) {
|
|
go dbclient.Client.CloseConfirmation.Set(guildId, s.CloseConfirmation)
|
|
}
|
|
|
|
func (s *Settings) updateFeedbackEnabled(guildId uint64) {
|
|
go dbclient.Client.FeedbackEnabled.Set(guildId, s.FeedbackEnabled)
|
|
}
|