diff --git a/bot/button/handlers/addadmin.go b/bot/button/handlers/addadmin.go index 13b31c2c..1f3af1b4 100644 --- a/bot/button/handlers/addadmin.go +++ b/bot/button/handlers/addadmin.go @@ -72,7 +72,8 @@ func (h *AddAdminHandler) Execute(ctx *context.ButtonContext) { return } - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: // Guild owner doesn't need to be added guild, err := ctx.Guild() if err != nil { @@ -99,7 +100,7 @@ func (h *AddAdminHandler) Execute(ctx *context.ButtonContext) { ctx.HandleError(err) return } - } else if mentionableType == context.MentionableTypeRole { + case context.MentionableTypeRole: if id == ctx.GuildId() { ctx.Reply(customisation.Red, i18n.Error, i18n.MessageAddSupportEveryone) return @@ -114,15 +115,16 @@ func (h *AddAdminHandler) Execute(ctx *context.ButtonContext) { ctx.HandleError(err) return } - } else { + default: ctx.HandleError(fmt.Errorf("invalid mentionable type: %d", mentionableType)) return } var mention string - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: mention = fmt.Sprintf("<@%d>", id) - } else { + case context.MentionableTypeRole: mention = fmt.Sprintf("<@&%d>", id) } @@ -141,11 +143,12 @@ func (h *AddAdminHandler) Execute(ctx *context.ButtonContext) { // Get the name of the user/role being added var targetName string - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: if targetMember, err := ctx.Worker().GetGuildMember(ctx.GuildId(), id); err == nil { targetName = targetMember.User.Username } - } else if mentionableType == context.MentionableTypeRole { + case context.MentionableTypeRole: if roles, err := ctx.Worker().GetGuildRoles(ctx.GuildId()); err == nil { for _, role := range roles { if role.Id == id { @@ -160,7 +163,7 @@ func (h *AddAdminHandler) Execute(ctx *context.ButtonContext) { if settings.TicketNotificationChannel != nil { auditReason := "Added admin member/role" if hasMember && targetName != "" { - auditReason = fmt.Sprintf("Added admin %s (%s) by %s", mentionableType, targetName, member.User.Username) + auditReason = fmt.Sprintf("Added admin %d (%s) by %s", mentionableType, targetName, member.User.Username) } else if hasMember { auditReason = fmt.Sprintf("Added admin member/role by %s", member.User.Username) } @@ -214,9 +217,13 @@ func (h *AddAdminHandler) Execute(ctx *context.ButtonContext) { Deny: 0, }) + pos := 0 + if ch.Position != nil { + pos = *ch.Position + } data := rest.ModifyChannelData{ PermissionOverwrites: overwrites, - Position: ch.Position, + Position: pos, } ticketAuditReason := fmt.Sprintf("Added admin to ticket %d", ticket.Id) diff --git a/bot/button/handlers/addsupport.go b/bot/button/handlers/addsupport.go index 39b3d84d..78c3d82b 100644 --- a/bot/button/handlers/addsupport.go +++ b/bot/button/handlers/addsupport.go @@ -74,49 +74,24 @@ func (h *AddSupportHandler) Execute(ctx *context.ButtonContext) { return } - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: ctx.ReplyRaw(customisation.Red, "Error", "Users in support teams are now deprecated. Please use roles instead.") return - - /* TODO: Remove if Discord does not resolve the performance issues - - // Guild owner doesn't need to be added - guild, err := ctx.Guild() - if err != nil { - ctx.HandleError(err) - return - } - - if guild.OwnerId == id { - ctx.Reply(customisation.Red, i18n.Error, i18n.MessageOwnerIsAlreadyAdmin) - return - } - - if err := dbclient.Client.Permissions.AddSupport(ctx.GuildId(), id); err != nil { - sentry.ErrorWithContext(err, ctx.ToErrorContext()) - } - - if err := utils.ToRetriever(ctx.Worker()).Cache().SetCachedPermissionLevel(ctx.GuildId(), id, permcache.Support); err != nil { - ctx.HandleError(err) - return - } - */ - } else if mentionableType == context.MentionableTypeRole { + case context.MentionableTypeRole: if id == ctx.GuildId() { ctx.Reply(customisation.Red, i18n.Error, i18n.MessageAddSupportEveryone) return } - if err := dbclient.Client.RolePermissions.AddSupport(ctx, ctx.GuildId(), id); err != nil { ctx.HandleError(err) return } - if err := utils.ToRetriever(ctx.Worker()).Cache().SetCachedPermissionLevel(ctx, ctx.GuildId(), id, permcache.Support); err != nil { ctx.HandleError(err) return } - } else { + default: ctx.HandleError(fmt.Errorf("invalid mentionable type: %d", mentionableType)) return } @@ -142,11 +117,12 @@ func updateChannelPermissions(ctx cmdregistry.CommandContext, id uint64, mention // Get the name of the user/role being added var targetName string - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: if targetMember, err := ctx.Worker().GetGuildMember(ctx.GuildId(), id); err == nil { targetName = targetMember.User.Username } - } else if mentionableType == context.MentionableTypeRole { + case context.MentionableTypeRole: if roles, err := ctx.Worker().GetGuildRoles(ctx.GuildId()); err == nil { for _, role := range roles { if role.Id == id { @@ -161,7 +137,7 @@ func updateChannelPermissions(ctx cmdregistry.CommandContext, id uint64, mention if settings.TicketNotificationChannel != nil { auditReason := "Added support member/role" if hasMember && targetName != "" { - auditReason = fmt.Sprintf("Added support %s (%s) by %s", mentionableType, targetName, member.User.Username) + auditReason = fmt.Sprintf("Added support %d (%s) by %s", mentionableType, targetName, member.User.Username) } else if hasMember { auditReason = fmt.Sprintf("Added support member/role by %s", member.User.Username) } @@ -239,14 +215,18 @@ func updateChannelPermissions(ctx cmdregistry.CommandContext, id uint64, mention Deny: 0, }) + pos := 0 + if ch.Position != nil { + pos = *ch.Position + } data := rest.ModifyChannelData{ PermissionOverwrites: overwrites, - Position: ch.Position, + Position: pos, } ticketAuditReason := fmt.Sprintf("Added support to ticket %d", ticket.Id) if hasMember && targetName != "" { - ticketAuditReason = fmt.Sprintf("Added support %s (%s) to ticket %d by %s", mentionableType, targetName, ticket.Id, member.User.Username) + ticketAuditReason = fmt.Sprintf("Added support %d (%s) to ticket %d by %s", mentionableType, targetName, ticket.Id, member.User.Username) } else if hasMember { ticketAuditReason = fmt.Sprintf("Added support to ticket %d by %s", ticket.Id, member.User.Username) } diff --git a/bot/button/handlers/admindebug/server/modals/panelsettings.go b/bot/button/handlers/admindebug/server/modals/panelsettings.go index b7a4b8cc..44562c42 100644 --- a/bot/button/handlers/admindebug/server/modals/panelsettings.go +++ b/bot/button/handlers/admindebug/server/modals/panelsettings.go @@ -147,7 +147,7 @@ func buildPanelSettings(ctx *context.ModalContext, selectedPanel *database.Panel if selectedPanel.ChannelId != 0 { channel, err := ctx.Worker().GetChannel(selectedPanel.ChannelId) if err == nil { - settings = append(settings, fmt.Sprintf("**Panel Channel:** `#%s` (%d)", channel.Name, selectedPanel.ChannelId)) + settings = append(settings, fmt.Sprintf("**Panel Channel:** `#%s` (%d)", *channel.Name, selectedPanel.ChannelId)) } else { settings = append(settings, fmt.Sprintf("**Panel Channel:** `%d` (channel not found)", selectedPanel.ChannelId)) } @@ -157,7 +157,7 @@ func buildPanelSettings(ctx *context.ModalContext, selectedPanel *database.Panel if !selectedPanel.UseThreads && selectedPanel.TargetCategory != 0 { category, err := ctx.Worker().GetChannel(selectedPanel.TargetCategory) if err == nil { - settings = append(settings, fmt.Sprintf("**Target Category:** `%s` (%d)", category.Name, selectedPanel.TargetCategory)) + settings = append(settings, fmt.Sprintf("**Target Category:** `%s` (%d)", *category.Name, selectedPanel.TargetCategory)) } else { settings = append(settings, fmt.Sprintf("**Target Category:** `%d` (category not found)", selectedPanel.TargetCategory)) } @@ -167,7 +167,7 @@ func buildPanelSettings(ctx *context.ModalContext, selectedPanel *database.Panel if selectedPanel.TranscriptChannelId != nil { channel, err := ctx.Worker().GetChannel(*selectedPanel.TranscriptChannelId) if err == nil { - settings = append(settings, fmt.Sprintf("**Transcript Channel:** `#%s` (%d)", channel.Name, *selectedPanel.TranscriptChannelId)) + settings = append(settings, fmt.Sprintf("**Transcript Channel:** `#%s` (%d)", *channel.Name, *selectedPanel.TranscriptChannelId)) } else { settings = append(settings, fmt.Sprintf("**Transcript Channel:** `%d` (channel not found)", *selectedPanel.TranscriptChannelId)) } diff --git a/bot/button/handlers/admindebug/server/modals/permissions.go b/bot/button/handlers/admindebug/server/modals/permissions.go index 3417e56c..3f8b84b1 100644 --- a/bot/button/handlers/admindebug/server/modals/permissions.go +++ b/bot/button/handlers/admindebug/server/modals/permissions.go @@ -336,7 +336,7 @@ func checkChannelPermissions(worker *w.Context, channelId uint64, botMember memb } var result strings.Builder - result.WriteString(fmt.Sprintf("**%s** (`#%s`)\n", label, channel.Name)) + result.WriteString(fmt.Sprintf("**%s** (`#%s`)\n", label, *channel.Name)) if len(missing) > 0 { result.WriteString("**Missing Permissions:**\n") for _, p := range missing { diff --git a/bot/button/handlers/admindebug/server/modals/ticketpermissions.go b/bot/button/handlers/admindebug/server/modals/ticketpermissions.go index fe9b5f77..9e8feec1 100644 --- a/bot/button/handlers/admindebug/server/modals/ticketpermissions.go +++ b/bot/button/handlers/admindebug/server/modals/ticketpermissions.go @@ -229,7 +229,7 @@ func checkUserTicketPermissions(ctx *context.ModalContext, worker *w.Context, gu // Check support roles supportRoles, err := dbclient.Client.RolePermissions.GetSupportRoles(ctx, guildId) - if err == nil && ticketPermLevel != "**Ticket Permission:** Admin" && ticketPermLevel != "**Ticket Permission:** Server Owner" && ticketPermLevel != "**Ticket Permission:** Admin" { + if err == nil && ticketPermLevel != "**Ticket Permission:** Admin" && ticketPermLevel != "**Ticket Permission:** Server Owner" { var supportRoleNames []string for _, roleId := range member.Roles { if utils.Contains(supportRoles, roleId) { diff --git a/bot/button/handlers/form.go b/bot/button/handlers/form.go index 135a3e83..d34016a0 100644 --- a/bot/button/handlers/form.go +++ b/bot/button/handlers/form.go @@ -89,7 +89,7 @@ func parseModalComponents(actionRows []interaction.ModalSubmitInteractionActionR c := actionRow.Component var answer string switch c.Type { - case component.ComponentSelectMenu, component.ComponentCheckboxGroup: + case component.ComponentStringSelect, component.ComponentCheckboxGroup: answer = strings.Join(c.Values, ", ") case component.ComponentInputText: answer = c.Value diff --git a/bot/button/handlers/gdprmodal.go b/bot/button/handlers/gdprmodal.go index a73d0d8e..9b5d81ea 100644 --- a/bot/button/handlers/gdprmodal.go +++ b/bot/button/handlers/gdprmodal.go @@ -121,74 +121,6 @@ func getGuildsWithUserMessages(ctx *cmdcontext.ButtonContext, userId uint64) ([] return batchFetchGuildsInfo(ctx, guildIds) } -func batchFetchOwnedGuilds(ctx *cmdcontext.ButtonContext, guildIds []uint64, userId uint64) ([]guildInfo, error) { - retriever := utils.ToRetriever(ctx.Worker()) - - type result struct { - info guildInfo - ok bool - } - - resultChan := make(chan result, len(guildIds)) - var wg sync.WaitGroup - semaphore := make(chan struct{}, 10) - - for _, guildId := range guildIds { - wg.Add(1) - go func(gId uint64) { - defer wg.Done() - - semaphore <- struct{}{} - defer func() { <-semaphore }() - - ownerId, err := retriever.GetGuildOwner(ctx, gId) - if err != nil { - resultChan <- result{ok: false} - return - } - - if ownerId != userId { - resultChan <- result{ok: false} - return - } - - guild, err := ctx.Worker().GetGuild(gId) - if err != nil { - resultChan <- result{ - info: guildInfo{ - GuildID: gId, - Name: strconv.FormatUint(gId, 10), - }, - ok: true, - } - return - } - - resultChan <- result{ - info: guildInfo{ - GuildID: gId, - Name: guild.Name, - }, - ok: true, - } - }(guildId) - } - - go func() { - wg.Wait() - close(resultChan) - }() - - var guilds []guildInfo - for res := range resultChan { - if res.ok { - guilds = append(guilds, res.info) - } - } - - return guilds, nil -} - func batchFetchGuildsInfo(ctx *cmdcontext.ButtonContext, guildIds []uint64) ([]guildInfo, error) { type result struct { info guildInfo @@ -611,7 +543,7 @@ func (h *GDPRModalSpecificTranscriptsHandler) Execute(ctx *context.ModalContext) if actionRow.Component != nil { switch actionRow.Component.CustomId { case "server_id": - if actionRow.Component.Values != nil && len(actionRow.Component.Values) > 0 { + if len(actionRow.Component.Values) > 0 { serverId = actionRow.Component.Values[0] } else if actionRow.Component.Value != "" { serverId = actionRow.Component.Value @@ -623,7 +555,7 @@ func (h *GDPRModalSpecificTranscriptsHandler) Execute(ctx *context.ModalContext) for _, component := range actionRow.Components { switch component.CustomId { case "server_id": - if component.Values != nil && len(component.Values) > 0 { + if len(component.Values) > 0 { serverId = component.Values[0] } else if component.Value != "" { serverId = component.Value @@ -806,7 +738,7 @@ func (h *GDPRModalSpecificMessagesHandler) Execute(ctx *context.ModalContext) { if actionRow.Component != nil { switch actionRow.Component.CustomId { case "server_id": - if actionRow.Component.Values != nil && len(actionRow.Component.Values) > 0 { + if len(actionRow.Component.Values) > 0 { serverId = actionRow.Component.Values[0] } else if actionRow.Component.Value != "" { serverId = actionRow.Component.Value @@ -818,7 +750,7 @@ func (h *GDPRModalSpecificMessagesHandler) Execute(ctx *context.ModalContext) { for _, component := range actionRow.Components { switch component.CustomId { case "server_id": - if component.Values != nil && len(component.Values) > 0 { + if len(component.Values) > 0 { serverId = component.Values[0] } else if component.Value != "" { serverId = component.Value diff --git a/bot/button/handlers/panel.go b/bot/button/handlers/panel.go index 2b1ede45..c6f67fa6 100644 --- a/bot/button/handlers/panel.go +++ b/bot/button/handlers/panel.go @@ -117,7 +117,7 @@ func buildFormComponents(inputs []database.FormInput, inputOptions map[int][]dat switch input.Type { // String Select - case int(component.ComponentSelectMenu): + case int(component.ComponentStringSelect): opts := make([]component.SelectOption, len(options)) for j, option := range options { opts[j] = component.SelectOption{ diff --git a/bot/button/handlers/tickets/edit/editlabelsbutton.go b/bot/button/handlers/tickets/edit/editlabelsbutton.go index 62cbfd2c..1e65b897 100644 --- a/bot/button/handlers/tickets/edit/editlabelsbutton.go +++ b/bot/button/handlers/tickets/edit/editlabelsbutton.go @@ -71,7 +71,7 @@ func (h *EditLabelsButtonHandler) Execute(ctx *context.ButtonContext) { Label: labels[i].Name, Value: fmt.Sprintf("%d", labels[i].LabelId), Default: utils.Contains(ticketLabelIds, labels[i].LabelId), - Emoji: &emoji.Emoji{Name: colourEmoji}, + Emoji: &emoji.Emoji{Name: utils.Ptr(colourEmoji)}, }) } diff --git a/bot/button/handlers/unclaim.go b/bot/button/handlers/unclaim.go index 3c37347f..5bd93595 100644 --- a/bot/button/handlers/unclaim.go +++ b/bot/button/handlers/unclaim.go @@ -137,7 +137,7 @@ func (h *UnclaimHandler) Execute(ctx *context.ButtonContext) { if !claimerHasAccess { filteredOverwrites := make([]channel.PermissionOverwrite, 0, len(overwrites)) for _, ow := range overwrites { - if ow.Id != whoClaimed || ow.Type != channel.PermissionTypeMember { + if ow.Id != whoClaimed || ow.Type != channel.PermissionOverwriteTypeMember { filteredOverwrites = append(filteredOverwrites, ow) } } @@ -147,14 +147,14 @@ func (h *UnclaimHandler) Execute(ctx *context.ButtonContext) { case database.SwitchPanelKeepAccess: overwrites = append(overwrites, channel.PermissionOverwrite{ Id: whoClaimed, - Type: channel.PermissionTypeMember, + Type: channel.PermissionOverwriteTypeMember, Allow: discordpermission.BuildPermissions(logic.StandardPermissions[:]...), Deny: 0, }) case database.SwitchPanelRemoveOnUnclaim: overwrites = append(overwrites, channel.PermissionOverwrite{ Id: whoClaimed, - Type: channel.PermissionTypeMember, + Type: channel.PermissionOverwriteTypeMember, Allow: 0, Deny: discordpermission.BuildPermissions(discordpermission.ViewChannel), }) @@ -172,7 +172,7 @@ func (h *UnclaimHandler) Execute(ctx *context.ButtonContext) { // Always update the name to match the new panel's naming scheme shouldUpdateName := true claimedChannelName, _ := logic.GenerateChannelName(ctx.Context, ctx.Worker(), panel, ticket.GuildId, ticket.Id, ticket.UserId, &whoClaimed) - if ch.Name != claimedChannelName { + if ch.Name == nil || *ch.Name != claimedChannelName { shouldUpdateName = false } diff --git a/bot/button/manager/handler.go b/bot/button/manager/handler.go index 010d51ba..2cb9209e 100644 --- a/bot/button/manager/handler.go +++ b/bot/button/manager/handler.go @@ -59,7 +59,7 @@ func HandleInteraction(ctx context.Context, manager *ComponentInteractionManager switch data.Data.Type() { case component.ComponentButton: cc = cmdcontext.NewButtonContext(ctx, worker, data, premiumTier, responseCh) - case component.ComponentSelectMenu: + case component.ComponentStringSelect: cc = cmdcontext.NewSelectMenuContext(ctx, worker, data, premiumTier, responseCh) default: sentry.ErrorWithContext(fmt.Errorf("invalid message component type: %d", data.Data.ComponentType), errorcontext.WorkerErrorContext{ @@ -137,7 +137,7 @@ func HandleInteraction(ctx context.Context, manager *ComponentInteractionManager } return canEdit - case component.ComponentSelectMenu: + case component.ComponentStringSelect: handler := manager.MatchSelect(data.Data.AsSelectMenu().CustomId) if handler == nil { return false diff --git a/bot/button/responsemessage.go b/bot/button/responsemessage.go index 186837e3..e1916262 100644 --- a/bot/button/responsemessage.go +++ b/bot/button/responsemessage.go @@ -24,7 +24,7 @@ func (r ResponseMessage) Build() interface{} { } func (r ResponseMessage) HandleDeferred(interactionData interaction.InteractionMetadata, worker *worker.Context) error { - if time.Now().Sub(utils.SnowflakeToTime(interactionData.Id)) > time.Minute*14 { + if time.Since(utils.SnowflakeToTime(interactionData.Id)) > time.Minute*14 { return nil } diff --git a/bot/command/context/applicationcommandcontext.go b/bot/command/context/applicationcommandcontext.go index aff27f1f..a0f46e94 100644 --- a/bot/command/context/applicationcommandcontext.go +++ b/bot/command/context/applicationcommandcontext.go @@ -126,23 +126,6 @@ func (c *SlashCommandContext) ReplyWith(response command.MessageResponse) (messa c.responseCh <- command.ResponseMessage{Data: response.IntoApplicationCommandData()} return message.Message{}, nil - - /* - if hasReplied { - msg, err := rest.EditOriginalInteractionResponse(context.Background(), c.Interaction.Token, c.worker.RateLimiter, c.worker.BotId, response.IntoWebhookEditBody()) - - if err != nil { - sentry.LogWithContext(err, c.ToErrorContext()) - } - - return msg, err - } else { - c.responseCh <- response.IntoApplicationCommandData() - - // todo: uhm - return message.Message{}, nil - } - */ } func (c *SlashCommandContext) Modal(data interaction.ModalResponseData) { diff --git a/bot/command/context/autoclosecontext.go b/bot/command/context/autoclosecontext.go index d5cdb850..76c935da 100644 --- a/bot/command/context/autoclosecontext.go +++ b/bot/command/context/autoclosecontext.go @@ -89,10 +89,6 @@ func (c *AutoCloseContext) ToErrorContext() errorcontext.WorkerErrorContext { } } -func (c *AutoCloseContext) openDm() (uint64, bool) { - return 0, false -} - func (c *AutoCloseContext) ReplyWith(response command.MessageResponse) (message.Message, error) { return message.Message{}, nil } diff --git a/bot/command/context/buttoncontext.go b/bot/command/context/buttoncontext.go index bd7c7c20..8ba114f4 100644 --- a/bot/command/context/buttoncontext.go +++ b/bot/command/context/buttoncontext.go @@ -118,23 +118,6 @@ func (c *ButtonContext) ReplyWith(response command.MessageResponse) (msg message Data: response, } - /* - if !hasReplied { - c.responseChannel <- button.ResponseMessage{ - Data: response, - } - } else { - if time.Now().Sub(utils.SnowflakeToTime(c.interaction.Id)) > time.Minute*14 { - return - } - - msg, err = rest.CreateFollowupMessage(context.Background(), c.Interaction.Token, c.worker.RateLimiter, c.worker.BotId, response.IntoWebhookBody()) - if err != nil { - sentry.LogWithContext(err, c.ToErrorContext()) - } - } - */ - return } @@ -173,7 +156,7 @@ func (c *ButtonContext) User() (user.User, error) { func (c *ButtonContext) InteractionUser() user.User { if c.Interaction.Member != nil { - return c.Interaction.Member.User + return *c.Interaction.Member.User } else if c.Interaction.User != nil { return *c.Interaction.User } else { // Infallible diff --git a/bot/command/context/interactionextensions.go b/bot/command/context/interactionextensions.go index eea689a8..322559f6 100644 --- a/bot/command/context/interactionextensions.go +++ b/bot/command/context/interactionextensions.go @@ -21,35 +21,38 @@ func NewInteractionExtension(interaction interaction.ApplicationCommandInteracti } func (i InteractionExtension) Resolved() interaction.ResolvedData { - return i.interaction.Data.Resolved + if i.interaction.Data.Resolved == nil { + return interaction.ResolvedData{} + } + return *i.interaction.Data.Resolved } func (i InteractionExtension) ResolvedUser(id uint64) (user.User, bool) { - user, ok := i.interaction.Data.Resolved.Users[objects.Snowflake(id)] + user, ok := i.Resolved().Users[objects.Snowflake(id)] return user, ok } func (i InteractionExtension) ResolvedMember(id uint64) (member.Member, bool) { - member, ok := i.interaction.Data.Resolved.Members[objects.Snowflake(id)] + member, ok := i.Resolved().Members[objects.Snowflake(id)] return member, ok } func (i InteractionExtension) ResolvedRole(id uint64) (guild.Role, bool) { - role, ok := i.interaction.Data.Resolved.Roles[objects.Snowflake(id)] + role, ok := i.Resolved().Roles[objects.Snowflake(id)] return role, ok } func (i InteractionExtension) ResolvedChannel(id uint64) (channel.Channel, bool) { - channel, ok := i.interaction.Data.Resolved.Channels[objects.Snowflake(id)] + channel, ok := i.Resolved().Channels[objects.Snowflake(id)] return channel, ok } func (i InteractionExtension) ResolvedMessage(id uint64) (message.Message, bool) { - message, ok := i.interaction.Data.Resolved.Messages[objects.Snowflake(id)] + message, ok := i.Resolved().Messages[objects.Snowflake(id)] return message, ok } func (i InteractionExtension) ResolvedAttachment(id uint64) (channel.Attachment, bool) { - attachment, ok := i.interaction.Data.Resolved.Attachments[objects.Snowflake(id)] + attachment, ok := i.Resolved().Attachments[objects.Snowflake(id)] return attachment, ok } diff --git a/bot/command/context/mentionabletype.go b/bot/command/context/mentionabletype.go index 0b6557f0..989cf719 100644 --- a/bot/command/context/mentionabletype.go +++ b/bot/command/context/mentionabletype.go @@ -16,9 +16,9 @@ const ( func (m MentionableType) OverwriteType() channel.PermissionOverwriteType { switch m { case MentionableTypeUser: - return channel.PermissionTypeMember + return channel.PermissionOverwriteTypeMember case MentionableTypeRole: - return channel.PermissionTypeRole + return channel.PermissionOverwriteTypeRole default: return -1 } diff --git a/bot/command/context/messagecomponentextensions.go b/bot/command/context/messagecomponentextensions.go index df5c423a..1e7d3c12 100644 --- a/bot/command/context/messagecomponentextensions.go +++ b/bot/command/context/messagecomponentextensions.go @@ -60,8 +60,6 @@ func (e *MessageComponentExtensions) Edit(data command.MessageResponse) { sentry.LogWithContext(err, e.ctx.ToErrorContext()) } } - - return } func (e *MessageComponentExtensions) EditWith(colour customisation.Colour, title, content i18n.MessageId, format ...interface{}) { diff --git a/bot/command/context/modalcontext.go b/bot/command/context/modalcontext.go index 2c8de6ab..1a23821c 100644 --- a/bot/command/context/modalcontext.go +++ b/bot/command/context/modalcontext.go @@ -149,7 +149,7 @@ func (c *ModalContext) ReplyWith(response command.MessageResponse) (msg message. Data: response, } } else { - if time.Now().Sub(utils.SnowflakeToTime(c.interaction.Id)) > time.Minute*14 { + if time.Since(utils.SnowflakeToTime(c.interaction.Id)) > time.Minute*14 { return } @@ -197,7 +197,7 @@ func (c *ModalContext) User() (user.User, error) { func (c *ModalContext) InteractionUser() user.User { if c.Interaction.Member != nil { - return c.Interaction.Member.User + return *c.Interaction.Member.User } else if c.Interaction.User != nil { return *c.Interaction.User } else { // Infallible diff --git a/bot/command/context/replyable.go b/bot/command/context/replyable.go index 0e14f07f..16827f92 100644 --- a/bot/command/context/replyable.go +++ b/bot/command/context/replyable.go @@ -182,7 +182,6 @@ func (r *Replyable) SelectValidEmoji(customEmoji customisation.CustomEmoji, fall func (r *Replyable) buildErrorResponse(err error, eventId string, includeInviteLink bool) command.MessageResponse { var message string - var imageUrl *string var restError request.RestError if errors.As(err, &restError) { @@ -280,9 +279,6 @@ func (r *Replyable) buildErrorResponse(err error, eventId string, includeInviteL } embed := r.buildEmbedRaw(customisation.Red, r.GetMessage(i18n.Error), message) - if imageUrl != nil { - embed.SetImage(*imageUrl) - } res := command.NewEphemeralEmbedMessageResponse(embed) diff --git a/bot/command/context/selectmenucontext.go b/bot/command/context/selectmenucontext.go index 8336a023..ee3919c6 100644 --- a/bot/command/context/selectmenucontext.go +++ b/bot/command/context/selectmenucontext.go @@ -118,23 +118,6 @@ func (c *SelectMenuContext) ReplyWith(response command.MessageResponse) (msg mes Data: response, } - /* - if !hasReplied { - c.responseChannel <- button.ResponseMessage{ - Data: response, - } - } else { - if time.Now().Sub(utils.SnowflakeToTime(c.interaction.Id)) > time.Minute*14 { - return - } - - msg, err = rest.CreateFollowupMessage(context.Background(), c.Interaction.Token, c.worker.RateLimiter, c.worker.BotId, response.IntoWebhookBody()) - if err != nil { - sentry.LogWithContext(err, c.ToErrorContext()) - } - } - */ - return } @@ -173,7 +156,7 @@ func (c *SelectMenuContext) User() (user.User, error) { func (c *SelectMenuContext) InteractionUser() user.User { if c.Interaction.Member != nil { - return c.Interaction.Member.User + return *c.Interaction.Member.User } else if c.Interaction.User != nil { return *c.Interaction.User } else { // Infallible diff --git a/bot/command/impl/admin/adminblacklist.go b/bot/command/impl/admin/adminblacklist.go index ec168574..7bfb0239 100644 --- a/bot/command/impl/admin/adminblacklist.go +++ b/bot/command/impl/admin/adminblacklist.go @@ -30,9 +30,9 @@ func (AdminBlacklistCommand) Properties() registry.Properties { Category: command.Settings, AdminOnly: true, Arguments: command.Arguments( - command.NewRequiredArgument("guild_id", "ID of the guild to blacklist", interaction.OptionTypeString, i18n.MessageInvalidArgument), - command.NewOptionalArgument("reason", "Reason for blacklisting the guild", interaction.OptionTypeString, i18n.MessageInvalidArgument), - command.NewOptionalArgument("real_owner_id", "ID of the real owner (if different from Discord server owner)", interaction.OptionTypeString, i18n.MessageInvalidArgument), + command.NewRequiredArgument("guild_id", "ID of the guild to blacklist", interaction.ApplicationCommandOptionTypeString, i18n.MessageInvalidArgument), + command.NewOptionalArgument("reason", "Reason for blacklisting the guild", interaction.ApplicationCommandOptionTypeString, i18n.MessageInvalidArgument), + command.NewOptionalArgument("real_owner_id", "ID of the real owner (if different from Discord server owner)", interaction.ApplicationCommandOptionTypeString, i18n.MessageInvalidArgument), ), Timeout: time.Second * 10, } diff --git a/bot/command/impl/admin/admingenpremium.go b/bot/command/impl/admin/admingenpremium.go index 9907721c..48ddea16 100644 --- a/bot/command/impl/admin/admingenpremium.go +++ b/bot/command/impl/admin/admingenpremium.go @@ -30,9 +30,9 @@ func (c AdminGenPremiumCommand) Properties() registry.Properties { Category: command.Settings, AdminOnly: true, Arguments: command.Arguments( - command.NewRequiredAutocompleteableArgument("sku", "SKU for the key to grant", interaction.OptionTypeString, i18n.MessageInvalidArgument, c.AutoCompleteHandler), - command.NewRequiredArgument("length", "Length in days of the key", interaction.OptionTypeInteger, i18n.MessageInvalidArgument), - command.NewOptionalArgument("amount", "Amount of keys to generate", interaction.OptionTypeInteger, i18n.MessageInvalidArgument), + command.NewRequiredAutocompleteableArgument("sku", "SKU for the key to grant", interaction.ApplicationCommandOptionTypeString, i18n.MessageInvalidArgument, c.AutoCompleteHandler), + command.NewRequiredArgument("length", "Length in days of the key", interaction.ApplicationCommandOptionTypeInteger, i18n.MessageInvalidArgument), + command.NewOptionalArgument("amount", "Amount of keys to generate", interaction.ApplicationCommandOptionTypeInteger, i18n.MessageInvalidArgument), ), Timeout: time.Second * 10, } diff --git a/bot/command/impl/admin/adminlistuserentitlements.go b/bot/command/impl/admin/adminlistuserentitlements.go index 7792059d..ad44e87b 100644 --- a/bot/command/impl/admin/adminlistuserentitlements.go +++ b/bot/command/impl/admin/adminlistuserentitlements.go @@ -27,7 +27,7 @@ func (AdminListUserEntitlementsCommand) Properties() registry.Properties { Category: command.Settings, HelperOnly: true, Arguments: command.Arguments( - command.NewRequiredArgument("user", "User to fetch entitlements for", interaction.OptionTypeUser, i18n.MessageInvalidArgument), + command.NewRequiredArgument("user", "User to fetch entitlements for", interaction.ApplicationCommandOptionTypeUser, i18n.MessageInvalidArgument), ), Timeout: time.Second * 15, } diff --git a/bot/command/impl/admin/adminrecache.go b/bot/command/impl/admin/adminrecache.go index fd0a1244..acdfef6f 100644 --- a/bot/command/impl/admin/adminrecache.go +++ b/bot/command/impl/admin/adminrecache.go @@ -28,7 +28,7 @@ func (AdminRecacheCommand) Properties() registry.Properties { Category: command.Settings, HelperOnly: true, Arguments: command.Arguments( - command.NewOptionalArgument("guildid", "ID of the guild to recache", interaction.OptionTypeString, i18n.MessageInvalidArgument), + command.NewOptionalArgument("guildid", "ID of the guild to recache", interaction.ApplicationCommandOptionTypeString, i18n.MessageInvalidArgument), ), Timeout: time.Second * 10, } diff --git a/bot/command/impl/admin/adminwhitelabelassignguild.go b/bot/command/impl/admin/adminwhitelabelassignguild.go index 3d7b266d..e800ee87 100644 --- a/bot/command/impl/admin/adminwhitelabelassignguild.go +++ b/bot/command/impl/admin/adminwhitelabelassignguild.go @@ -28,8 +28,8 @@ func (AdminWhitelabelAssignGuildCommand) Properties() registry.Properties { Category: command.Settings, HelperOnly: true, Arguments: command.Arguments( - command.NewRequiredArgument("bot_id", "ID of the bot to assign to the guild", interaction.OptionTypeString, i18n.MessageInvalidArgument), - command.NewRequiredArgument("guild_id", "ID of the guild to assign the bot to", interaction.OptionTypeString, i18n.MessageInvalidArgument), + command.NewRequiredArgument("bot_id", "ID of the bot to assign to the guild", interaction.ApplicationCommandOptionTypeString, i18n.MessageInvalidArgument), + command.NewRequiredArgument("guild_id", "ID of the guild to assign the bot to", interaction.ApplicationCommandOptionTypeString, i18n.MessageInvalidArgument), ), Timeout: time.Second * 10, } diff --git a/bot/command/impl/admin/adminwhitelabeldata.go b/bot/command/impl/admin/adminwhitelabeldata.go index ea1f3803..81eb3317 100644 --- a/bot/command/impl/admin/adminwhitelabeldata.go +++ b/bot/command/impl/admin/adminwhitelabeldata.go @@ -31,7 +31,7 @@ func (AdminWhitelabelDataCommand) Properties() registry.Properties { Category: command.Settings, HelperOnly: true, Arguments: command.Arguments( - command.NewRequiredArgument("user_id", "ID of the user who has the whitelabel subscription", interaction.OptionTypeUser, i18n.MessageInvalidArgument), + command.NewRequiredArgument("user_id", "ID of the user who has the whitelabel subscription", interaction.ApplicationCommandOptionTypeUser, i18n.MessageInvalidArgument), ), Timeout: time.Second * 10, } diff --git a/bot/command/impl/admin/debug/debugserver.go b/bot/command/impl/admin/debug/debugserver.go index 4619f915..685663f3 100644 --- a/bot/command/impl/admin/debug/debugserver.go +++ b/bot/command/impl/admin/debug/debugserver.go @@ -39,7 +39,7 @@ func (AdminDebugServerCommand) Properties() registry.Properties { HelperOnly: true, DisableAutoDefer: true, Arguments: command.Arguments( - command.NewRequiredArgument("guild_id", "ID of the guild", interaction.OptionTypeString, i18n.MessageInvalidArgument), + command.NewRequiredArgument("guild_id", "ID of the guild", interaction.ApplicationCommandOptionTypeString, i18n.MessageInvalidArgument), ), Timeout: time.Second * 10, } @@ -197,7 +197,11 @@ func (AdminDebugServerCommand) Execute(ctx registry.CommandContext, raw string) if settings.UseThreads && settings.TicketNotificationChannel != nil { ch, err := worker.GetChannel(*settings.TicketNotificationChannel) if err == nil { - return ch.Name, strconv.FormatUint(ch.Id, 10) + name := "" + if ch.Name != nil { + name = *ch.Name + } + return name, strconv.FormatUint(ch.Id, 10) } } return "Disabled", "Disabled" @@ -248,8 +252,8 @@ func (AdminDebugServerCommand) Execute(ctx registry.CommandContext, raw string) fmt.Sprintf("Name: `%s`", guild.Name), fmt.Sprintf("Owner: `%s` - <@%s> (%s) ", owner.Username, ownerId, ownerId), } - if guild.VanityUrlCode != "" { - guildInfo = append(guildInfo, fmt.Sprintf("Vanity URL: `.gg/%s`", guild.VanityUrlCode)) + if guild.VanityUrlCode != nil && *guild.VanityUrlCode != "" { + guildInfo = append(guildInfo, fmt.Sprintf("Vanity URL: `.gg/%s`", *guild.VanityUrlCode)) } // Add blacklist information diff --git a/bot/command/impl/general/gdpr.go b/bot/command/impl/general/gdpr.go index d82a1d98..56bde14a 100644 --- a/bot/command/impl/general/gdpr.go +++ b/bot/command/impl/general/gdpr.go @@ -45,7 +45,7 @@ func (c GDPRCommand) Properties() registry.Properties { Contexts: []interaction.InteractionContextType{interaction.InteractionContextBotDM}, IgnoreBlacklist: true, Arguments: command.Arguments( - command.NewOptionalAutocompleteableArgument("lang", "Language for GDPR messages", interaction.OptionTypeString, i18n.GdprLanguageOption, c.LanguageAutoCompleteHandler), + command.NewOptionalAutocompleteableArgument("lang", "Language for GDPR messages", interaction.ApplicationCommandOptionTypeString, i18n.GdprLanguageOption, c.LanguageAutoCompleteHandler), ), } } @@ -81,10 +81,10 @@ func buildGDPRComponents(ctx registry.CommandContext, locale *i18n.Locale) []com buildTextSection(i18n.GetMessage(locale, i18n.GdprIntro)), component.BuildSeparator(component.Separator{}), buildTextSection(i18n.GetMessage(locale, i18n.GdprTranscriptSectionTitle)), - buildButtonRow(ctx, locale, transcriptButtons), + buildButtonRow(locale, transcriptButtons), component.BuildSeparator(component.Separator{}), buildTextSection(i18n.GetMessage(locale, i18n.GdprMessageSectionTitle)), - buildButtonRow(ctx, locale, messageButtons), + buildButtonRow(locale, messageButtons), component.BuildSeparator(component.Separator{}), buildTextSection(i18n.GetMessage(locale, i18n.GdprWarningText)), component.BuildSeparator(component.Separator{}), @@ -99,7 +99,7 @@ func buildTextSection(content string) component.Component { return component.BuildTextDisplay(component.TextDisplay{Content: content}) } -func buildButtonRow(ctx registry.CommandContext, locale *i18n.Locale, buttons []gdprButton) component.Component { +func buildButtonRow(locale *i18n.Locale, buttons []gdprButton) component.Component { buttonComponents := make([]component.Component, len(buttons)) for i, btn := range buttons { customId := fmt.Sprintf("%s_%s", btn.CustomID, locale.IsoShortCode) diff --git a/bot/command/impl/settings/addadmin.go b/bot/command/impl/settings/addadmin.go index 5ac1d6ee..7a62dfa9 100644 --- a/bot/command/impl/settings/addadmin.go +++ b/bot/command/impl/settings/addadmin.go @@ -27,7 +27,7 @@ func (AddAdminCommand) Properties() registry.Properties { Category: command.Settings, InteractionOnly: true, Arguments: command.Arguments( - command.NewRequiredArgument("user_or_role", "User or role to apply the administrator permission to", interaction.OptionTypeMentionable, i18n.MessageAddAdminNoMembers), + command.NewRequiredArgument("user_or_role", "User or role to apply the administrator permission to", interaction.ApplicationCommandOptionTypeMentionable, i18n.MessageAddAdminNoMembers), ), DefaultEphemeral: true, Timeout: time.Second * 3, @@ -52,11 +52,12 @@ func (c AddAdminCommand) Execute(ctx registry.CommandContext, id uint64) { } var mention string - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: mention = fmt.Sprintf("<@%d>", id) - } else if mentionableType == context.MentionableTypeRole { + case context.MentionableTypeRole: mention = fmt.Sprintf("<@&%d>", id) - } else { + default: ctx.HandleError(fmt.Errorf("unknown mentionable type: %d", mentionableType)) return } diff --git a/bot/command/impl/settings/addsupport.go b/bot/command/impl/settings/addsupport.go index 62735c90..5a46fd45 100644 --- a/bot/command/impl/settings/addsupport.go +++ b/bot/command/impl/settings/addsupport.go @@ -28,7 +28,7 @@ func (AddSupportCommand) Properties() registry.Properties { Category: command.Settings, InteractionOnly: true, Arguments: command.Arguments( - command.NewRequiredArgument("role", "Role to apply the support representative permission to", interaction.OptionTypeMentionable, i18n.MessageAddSupportNoMembers), + command.NewRequiredArgument("role", "Role to apply the support representative permission to", interaction.ApplicationCommandOptionTypeMentionable, i18n.MessageAddSupportNoMembers), ), DefaultEphemeral: true, Timeout: time.Second * 3, @@ -53,14 +53,15 @@ func (c AddSupportCommand) Execute(ctx registry.CommandContext, id uint64) { } var mention string - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: ctx.ReplyRaw(customisation.Red, "Error", "Users in support teams are now deprecated. Please use roles instead.") return //mention = fmt.Sprintf("<@%d>", id) - } else if mentionableType == context.MentionableTypeRole { + case context.MentionableTypeRole: mention = fmt.Sprintf("<@&%d>", id) - } else { + default: ctx.HandleError(fmt.Errorf("unknown mentionable type: %d", mentionableType)) return } diff --git a/bot/command/impl/settings/blacklist.go b/bot/command/impl/settings/blacklist.go index f15dc946..3c731ecd 100644 --- a/bot/command/impl/settings/blacklist.go +++ b/bot/command/impl/settings/blacklist.go @@ -29,7 +29,7 @@ func (BlacklistCommand) Properties() registry.Properties { PermissionLevel: permission.Support, Category: command.Settings, Arguments: command.Arguments( - command.NewRequiredArgument("user_or_role", "User or role to blacklist or unblacklist", interaction.OptionTypeMentionable, i18n.MessageBlacklistNoMembers), + command.NewRequiredArgument("user_or_role", "User or role to blacklist or unblacklist", interaction.ApplicationCommandOptionTypeMentionable, i18n.MessageBlacklistNoMembers), ), DefaultEphemeral: true, Timeout: time.Second * 5, @@ -53,7 +53,8 @@ func (BlacklistCommand) Execute(ctx registry.CommandContext, id uint64) { return } - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: member, err := ctx.Worker().GetGuildMember(ctx.GuildId(), id) if err != nil { ctx.HandleError(err) @@ -109,7 +110,7 @@ func (BlacklistCommand) Execute(ctx registry.CommandContext, id uint64) { ctx.Reply(customisation.Green, i18n.TitleBlacklist, i18n.MessageBlacklistAdd, member.User.Id) } - } else if mentionableType == context.MentionableTypeRole { + case context.MentionableTypeRole: // Check if role is staff isSupport, err := dbclient.Client.RolePermissions.IsSupport(ctx, id) if err != nil { @@ -167,7 +168,7 @@ func (BlacklistCommand) Execute(ctx registry.CommandContext, id uint64) { ctx.Reply(customisation.Green, i18n.TitleBlacklist, i18n.MessageBlacklistAddRole, id) } - } else { + default: ctx.HandleError(fmt.Errorf("infallible")) return } diff --git a/bot/command/impl/settings/removeadmin.go b/bot/command/impl/settings/removeadmin.go index b6636e64..ba5e6ef0 100644 --- a/bot/command/impl/settings/removeadmin.go +++ b/bot/command/impl/settings/removeadmin.go @@ -29,7 +29,7 @@ func (RemoveAdminCommand) Properties() registry.Properties { PermissionLevel: permcache.Admin, Category: command.Settings, Arguments: command.Arguments( - command.NewRequiredArgument("user_or_role", "User or role to remove the administrator permission from", interaction.OptionTypeMentionable, i18n.MessageRemoveAdminNoMembers), + command.NewRequiredArgument("user_or_role", "User or role to remove the administrator permission from", interaction.ApplicationCommandOptionTypeMentionable, i18n.MessageRemoveAdminNoMembers), ), DefaultEphemeral: true, Timeout: time.Second * 5, @@ -60,7 +60,8 @@ func (c RemoveAdminCommand) Execute(ctx registry.CommandContext, id uint64) { return } - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: // get guild object guild, err := ctx.Worker().GetGuild(ctx.GuildId()) if err != nil { @@ -87,7 +88,7 @@ func (c RemoveAdminCommand) Execute(ctx registry.CommandContext, id uint64) { ctx.HandleError(err) return } - } else if mentionableType == context.MentionableTypeRole { + case context.MentionableTypeRole: if err := dbclient.Client.RolePermissions.RemoveAdmin(ctx, ctx.GuildId(), id); err != nil { ctx.HandleError(err) return @@ -97,16 +98,20 @@ func (c RemoveAdminCommand) Execute(ctx registry.CommandContext, id uint64) { ctx.HandleError(err) return } - } else { + default: ctx.HandleError(fmt.Errorf("infallible")) return } var mention string - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: mention = fmt.Sprintf("<@%d>", id) - } else { + case context.MentionableTypeRole: mention = fmt.Sprintf("<@&%d>", id) + default: + ctx.HandleError(fmt.Errorf("infallible")) + return } ctx.ReplyWith(command.NewEphemeralEmbedMessageResponse( @@ -120,11 +125,12 @@ func (c RemoveAdminCommand) Execute(ctx registry.CommandContext, id uint64) { // Get the name of the user/role being removed var targetName string - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: if targetMember, err := ctx.Worker().GetGuildMember(ctx.GuildId(), id); err == nil { targetName = targetMember.User.Username } - } else if mentionableType == context.MentionableTypeRole { + case context.MentionableTypeRole: if roles, err := ctx.Worker().GetGuildRoles(ctx.GuildId()); err == nil { for _, role := range roles { if role.Id == id { @@ -136,7 +142,7 @@ func (c RemoveAdminCommand) Execute(ctx registry.CommandContext, id uint64) { } if err == nil && targetName != "" { - auditReason = fmt.Sprintf("Removed admin %s (%s) by %s", mentionableType, targetName, member.User.Username) + auditReason = fmt.Sprintf("Removed admin %d (%s) by %s", mentionableType, targetName, member.User.Username) } else if err == nil { auditReason = fmt.Sprintf("Removed admin member/role by %s", member.User.Username) } diff --git a/bot/command/impl/settings/removesupport.go b/bot/command/impl/settings/removesupport.go index 39b7345f..1edeea7f 100644 --- a/bot/command/impl/settings/removesupport.go +++ b/bot/command/impl/settings/removesupport.go @@ -30,7 +30,7 @@ func (RemoveSupportCommand) Properties() registry.Properties { PermissionLevel: permcache.Admin, Category: command.Settings, Arguments: command.Arguments( - command.NewRequiredArgument("user_or_role", "User or role to remove the support representative permission from", interaction.OptionTypeMentionable, i18n.MessageRemoveSupportNoMembers), + command.NewRequiredArgument("user_or_role", "User or role to remove the support representative permission from", interaction.ApplicationCommandOptionTypeMentionable, i18n.MessageRemoveSupportNoMembers), ), DefaultEphemeral: true, Timeout: time.Second * 5, @@ -61,7 +61,8 @@ func (c RemoveSupportCommand) Execute(ctx registry.CommandContext, id uint64) { return } - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: // get guild object guild, err := ctx.Worker().GetGuild(ctx.GuildId()) if err != nil { @@ -93,7 +94,7 @@ func (c RemoveSupportCommand) Execute(ctx registry.CommandContext, id uint64) { ctx.HandleError(err) return } - } else if mentionableType == context.MentionableTypeRole { + case context.MentionableTypeRole: if err := dbclient.Client.RolePermissions.RemoveSupport(ctx, ctx.GuildId(), id); err != nil { ctx.HandleError(err) return @@ -108,7 +109,7 @@ func (c RemoveSupportCommand) Execute(ctx registry.CommandContext, id uint64) { ctx.HandleError(err) return } - } else { + default: ctx.HandleError(fmt.Errorf("infallible")) return } @@ -147,7 +148,7 @@ func (c RemoveSupportCommand) Execute(ctx registry.CommandContext, id uint64) { } if err == nil && targetName != "" { - auditReason = fmt.Sprintf("Removed support %s (%s) by %s", mentionableType, targetName, member.User.Username) + auditReason = fmt.Sprintf("Removed support %d (%s) by %s", mentionableType, targetName, member.User.Username) } else if err == nil { auditReason = fmt.Sprintf("Removed support member/role by %s", member.User.Username) } diff --git a/bot/command/impl/settings/setup/auto.go b/bot/command/impl/settings/setup/auto.go index b3a890c6..25cd33c8 100644 --- a/bot/command/impl/settings/setup/auto.go +++ b/bot/command/impl/settings/setup/auto.go @@ -21,8 +21,6 @@ import ( "github.com/TicketsBot-cloud/worker/i18n" ) -const freePanelLimit = 3 - type AutoSetupCommand struct { } @@ -173,7 +171,7 @@ func getTranscriptChannelData(guildId, supportRoleId, adminRoleId uint64) rest.C overwrites := []channel.PermissionOverwrite{ { // deny everyone else access to channel Id: guildId, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: 0, Deny: allow, }, @@ -182,7 +180,7 @@ func getTranscriptChannelData(guildId, supportRoleId, adminRoleId uint64) rest.C if supportRoleId != 0 { overwrites = append(overwrites, channel.PermissionOverwrite{ Id: supportRoleId, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: allow, Deny: 0, }) @@ -191,7 +189,7 @@ func getTranscriptChannelData(guildId, supportRoleId, adminRoleId uint64) rest.C if adminRoleId != 0 { overwrites = append(overwrites, channel.PermissionOverwrite{ Id: adminRoleId, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: allow, Deny: 0, }) diff --git a/bot/command/impl/settings/setup/limit.go b/bot/command/impl/settings/setup/limit.go index 87cc61bb..82b1d7d6 100644 --- a/bot/command/impl/settings/setup/limit.go +++ b/bot/command/impl/settings/setup/limit.go @@ -22,7 +22,7 @@ func (LimitSetupCommand) Properties() registry.Properties { PermissionLevel: permission.Admin, Category: command.Settings, Arguments: command.Arguments( - command.NewRequiredArgument("limit", "The maximum amount of tickets a user can have open simultaneously", interaction.OptionTypeInteger, i18n.SetupLimitInvalid), + command.NewRequiredArgument("limit", "The maximum amount of tickets a user can have open simultaneously", interaction.ApplicationCommandOptionTypeInteger, i18n.SetupLimitInvalid), ), Timeout: time.Second * 3, } diff --git a/bot/command/impl/settings/setup/setup.go b/bot/command/impl/settings/setup/setup.go index 24c7e9ec..5cbffd10 100644 --- a/bot/command/impl/settings/setup/setup.go +++ b/bot/command/impl/settings/setup/setup.go @@ -35,48 +35,3 @@ func (c SetupCommand) Execute(ctx registry.CommandContext) { // Parent commands cannot be called //ctx.ReplyWithFieldsPermanent(customisation.Green, i18n.TitleSetup, i18n.SetupChoose, c.buildFields(ctx)) } - -/* TODO: Remove -func (SetupCommand) buildFields(ctx registry.CommandContext) []embed.EmbedField { - fields := make([]embed.EmbedField, 9) - - group, _ := errgroup.WithContext(context.Background()) - - group.Go(getFieldFunc(ctx, fields, 0, "/setup auto", i18n.SetupAutoDescription, true)) - group.Go(getFieldFunc(ctx, fields, 1, "Dashboard", i18n.SetupDashboardDescription, true)) - fields[2] = embed.EmbedField{ - Name: "\u200b", - Value: "‎", - Inline: true, - } - group.Go(getFieldFunc(ctx, fields, 3, "/setup prefix", i18n.SetupPrefixDescription, true)) - group.Go(getFieldFunc(ctx, fields, 4, "/setup limit", i18n.SetupLimitDescription, true)) - group.Go(getFieldFunc(ctx, fields, 5, "/setup welcomemessage", i18n.SetupWelcomeMessageDescription, false)) - group.Go(getFieldFunc(ctx, fields, 6, "/setup transcripts", i18n.SetupTranscriptsDescription, true)) - group.Go(getFieldFunc(ctx, fields, 7, "/setup category", i18n.SetupCategoryDescription, true)) - group.Go(getFieldFunc(ctx, fields, 8, "Reaction Panels", i18n.SetupReactionPanelsDescription, false, ctx.GuildId)) - - // should never happen - if err := group.Wait(); err != nil { - sentry.Error(err) - return nil - } - - return fields -} - -func newFieldFromTranslation(ctx registry.CommandContext, name string, value i18n.MessageId, inline bool, format ...interface{}) embed.EmbedField { - return embed.EmbedField{ - Name: name, - Value: i18n.GetMessageFromGuild(ctx.GuildId(), value, format...), - Inline: inline, - } -} - -func getFieldFunc(ctx registry.CommandContext, fields []embed.EmbedField, index int, name string, value i18n.MessageId, inline bool, format ...interface{}) func() error { - return func() error { - fields[index] = newFieldFromTranslation(ctx, name, value, inline, format...) - return nil - } -} -*/ diff --git a/bot/command/impl/settings/setup/threads.go b/bot/command/impl/settings/setup/threads.go index eaaa29ef..5baa943d 100644 --- a/bot/command/impl/settings/setup/threads.go +++ b/bot/command/impl/settings/setup/threads.go @@ -23,8 +23,8 @@ func (ThreadsSetupCommand) Properties() registry.Properties { PermissionLevel: permission.Admin, Category: command.Settings, Arguments: command.Arguments( - command.NewRequiredArgument("use_threads", "Whether or not private threads should be used for ticket", interaction.OptionTypeBoolean, "infallible"), - command.NewOptionalArgument("ticket_notification_channel", "The channel that ticket open notifications should be sent to", interaction.OptionTypeChannel, "infallible"), + command.NewRequiredArgument("use_threads", "Whether or not private threads should be used for ticket", interaction.ApplicationCommandOptionTypeBoolean, "infallible"), + command.NewOptionalArgument("ticket_notification_channel", "The channel that ticket open notifications should be sent to", interaction.ApplicationCommandOptionTypeChannel, "infallible"), ), InteractionOnly: true, Timeout: time.Second * 5, diff --git a/bot/command/impl/settings/setup/transcripts.go b/bot/command/impl/settings/setup/transcripts.go index 576e1c37..e80016ce 100644 --- a/bot/command/impl/settings/setup/transcripts.go +++ b/bot/command/impl/settings/setup/transcripts.go @@ -25,7 +25,7 @@ func (TranscriptsSetupCommand) Properties() registry.Properties { PermissionLevel: permission.Admin, Category: command.Settings, Arguments: command.Arguments( - command.NewRequiredArgument("channel", "The channel that ticket transcripts should be sent to", interaction.OptionTypeChannel, i18n.SetupTranscriptsInvalid), + command.NewRequiredArgument("channel", "The channel that ticket transcripts should be sent to", interaction.ApplicationCommandOptionTypeChannel, i18n.SetupTranscriptsInvalid), ), Timeout: time.Second * 5, } diff --git a/bot/command/impl/statistics/statsuser.go b/bot/command/impl/statistics/statsuser.go index c6689a4a..49d6c1a4 100644 --- a/bot/command/impl/statistics/statsuser.go +++ b/bot/command/impl/statistics/statsuser.go @@ -34,7 +34,7 @@ func (StatsUserCommand) Properties() registry.Properties { Category: command.Statistics, PremiumOnly: true, Arguments: command.Arguments( - command.NewRequiredArgument("user", "User whose statistics to retrieve", interaction.OptionTypeUser, i18n.MessageInvalidUser), + command.NewRequiredArgument("user", "User whose statistics to retrieve", interaction.ApplicationCommandOptionTypeUser, i18n.MessageInvalidUser), ), DefaultEphemeral: true, Timeout: time.Second * 30, diff --git a/bot/command/impl/tags/managetagsadd.go b/bot/command/impl/tags/managetagsadd.go index 340bcb93..6518558a 100644 --- a/bot/command/impl/tags/managetagsadd.go +++ b/bot/command/impl/tags/managetagsadd.go @@ -29,8 +29,8 @@ func (ManageTagsAddCommand) Properties() registry.Properties { Category: command.Tags, InteractionOnly: true, Arguments: command.Arguments( - command.NewRequiredArgument("id", "Identifier for the tag", interaction.OptionTypeString, i18n.MessageTagCreateInvalidArguments), - command.NewRequiredArgument("content", "Tag contents to be sent when /tag is used", interaction.OptionTypeString, i18n.MessageTagCreateInvalidArguments), + command.NewRequiredArgument("id", "Identifier for the tag", interaction.ApplicationCommandOptionTypeString, i18n.MessageTagCreateInvalidArguments), + command.NewRequiredArgument("content", "Tag contents to be sent when /tag is used", interaction.ApplicationCommandOptionTypeString, i18n.MessageTagCreateInvalidArguments), ), DefaultEphemeral: true, Timeout: time.Second * 3, diff --git a/bot/command/impl/tags/managetagsdelete.go b/bot/command/impl/tags/managetagsdelete.go index 4dc4e39b..ebc03529 100644 --- a/bot/command/impl/tags/managetagsdelete.go +++ b/bot/command/impl/tags/managetagsdelete.go @@ -24,7 +24,7 @@ func (ManageTagsDeleteCommand) Properties() registry.Properties { PermissionLevel: permission.Support, Category: command.Tags, Arguments: command.Arguments( - command.NewRequiredArgument("id", "ID of the tag to delete", interaction.OptionTypeString, i18n.MessageTagDeleteInvalidArguments), + command.NewRequiredArgument("id", "ID of the tag to delete", interaction.ApplicationCommandOptionTypeString, i18n.MessageTagDeleteInvalidArguments), ), DefaultEphemeral: true, Timeout: time.Second * 3, diff --git a/bot/command/impl/tags/tag.go b/bot/command/impl/tags/tag.go index 7e01eb96..09e435f8 100644 --- a/bot/command/impl/tags/tag.go +++ b/bot/command/impl/tags/tag.go @@ -35,7 +35,7 @@ func (c TagCommand) Properties() registry.Properties { Category: command.Tags, DisableAutoDefer: true, Arguments: command.Arguments( - command.NewRequiredAutocompleteableArgument("id", "The ID of the tag to be sent to the channel", interaction.OptionTypeString, i18n.MessageTagInvalidArguments, c.AutoCompleteHandler), + command.NewRequiredAutocompleteableArgument("id", "The ID of the tag to be sent to the channel", interaction.ApplicationCommandOptionTypeString, i18n.MessageTagInvalidArguments, c.AutoCompleteHandler), ), Timeout: time.Second * 5, } @@ -86,9 +86,9 @@ func (TagCommand) Execute(ctx registry.CommandContext, tagId string) { Embeds: embeds, AllowedMentions: message.AllowedMention{ Parse: []message.AllowedMentionType{ - message.EVERYONE, - message.USERS, - message.ROLES, + message.AllowedMentionTypeRoles, + message.AllowedMentionTypeUsers, + message.AllowedMentionTypeEveryone, }, }, } diff --git a/bot/command/impl/tags/tagalias.go b/bot/command/impl/tags/tagalias.go index 3ad424d0..1c14238f 100644 --- a/bot/command/impl/tags/tagalias.go +++ b/bot/command/impl/tags/tagalias.go @@ -83,9 +83,9 @@ func (c TagAliasCommand) Execute(ctx registry.CommandContext) { Embeds: embeds, AllowedMentions: message.AllowedMention{ Parse: []message.AllowedMentionType{ - message.EVERYONE, - message.USERS, - message.ROLES, + message.AllowedMentionTypeRoles, + message.AllowedMentionTypeUsers, + message.AllowedMentionTypeEveryone, }, }, } diff --git a/bot/command/impl/tickets/add.go b/bot/command/impl/tickets/add.go index f7edfdc6..be50e68c 100644 --- a/bot/command/impl/tickets/add.go +++ b/bot/command/impl/tickets/add.go @@ -27,7 +27,7 @@ func (AddCommand) Properties() registry.Properties { PermissionLevel: permcache.Everyone, Category: command.Tickets, Arguments: command.Arguments( - command.NewRequiredArgument("user_or_role", "User or role to add to the ticket", interaction.OptionTypeMentionable, i18n.MessageAddNoMembers), + command.NewRequiredArgument("user_or_role", "User or role to add to the ticket", interaction.ApplicationCommandOptionTypeMentionable, i18n.MessageAddNoMembers), ), Timeout: constants.TimeoutOpenTicket, } @@ -78,7 +78,8 @@ func (AddCommand) Execute(ctx registry.CommandContext, id uint64) { return } - if mentionableType == context.MentionableTypeUser { + switch mentionableType { + case context.MentionableTypeUser: // Add user to ticket in DB if err := dbclient.Client.TicketMembers.Add(ctx, ctx.GuildId(), ticket.Id, id); err != nil { ctx.HandleError(err) @@ -88,7 +89,7 @@ func (AddCommand) Execute(ctx registry.CommandContext, id uint64) { if ticket.IsThread { if err := ctx.Worker().AddThreadMember(*ticket.ChannelId, id); err != nil { if err, ok := err.(request.RestError); ok && (err.ApiError.Code == 50001 || err.ApiError.Code == 50013) { - ch, err := ctx.Channel() + ch, err := ctx.Worker().GetChannel(ctx.ChannelId()) if err != nil { ctx.HandleError(err) return @@ -130,7 +131,7 @@ func (AddCommand) Execute(ctx registry.CommandContext, id uint64) { return } } - } else if mentionableType == context.MentionableTypeRole { + case context.MentionableTypeRole: // Handle role addition additionalPermissions, err := dbclient.Client.TicketPermissions.Get(ctx, ctx.GuildId()) if err != nil { @@ -153,7 +154,7 @@ func (AddCommand) Execute(ctx registry.CommandContext, id uint64) { ctx.HandleError(err) return } - } else { + default: ctx.HandleError(fmt.Errorf("unknown mentionable type: %d", mentionableType)) return } diff --git a/bot/command/impl/tickets/close.go b/bot/command/impl/tickets/close.go index b7ff8ee3..7fde49eb 100644 --- a/bot/command/impl/tickets/close.go +++ b/bot/command/impl/tickets/close.go @@ -27,7 +27,7 @@ func (c CloseCommand) Properties() registry.Properties { PermissionLevel: permission.Everyone, Category: command.Tickets, Arguments: command.Arguments( - command.NewOptionalAutocompleteableArgument("reason", "The reason the ticket was closed", interaction.OptionTypeString, "infallible", c.AutoCompleteHandler), // should never fail + command.NewOptionalAutocompleteableArgument("reason", "The reason the ticket was closed", interaction.ApplicationCommandOptionTypeString, "infallible", c.AutoCompleteHandler), // should never fail ), Timeout: constants.TimeoutCloseTicket, } diff --git a/bot/command/impl/tickets/closerequest.go b/bot/command/impl/tickets/closerequest.go index 1c44679f..382bf1f6 100644 --- a/bot/command/impl/tickets/closerequest.go +++ b/bot/command/impl/tickets/closerequest.go @@ -35,8 +35,8 @@ func (c CloseRequestCommand) Properties() registry.Properties { InteractionOnly: true, DisableAutoDefer: true, Arguments: command.Arguments( - command.NewOptionalArgument("close_delay", "Hours to close the ticket in if the user does not respond", interaction.OptionTypeInteger, "infallible"), - command.NewOptionalAutocompleteableArgument("reason", "The reason the ticket was closed", interaction.OptionTypeString, "infallible", c.ReasonAutoCompleteHandler), + command.NewOptionalArgument("close_delay", "Hours to close the ticket in if the user does not respond", interaction.ApplicationCommandOptionTypeInteger, "infallible"), + command.NewOptionalAutocompleteableArgument("reason", "The reason the ticket was closed", interaction.ApplicationCommandOptionTypeString, "infallible", c.ReasonAutoCompleteHandler), ), Timeout: time.Second * 5, } diff --git a/bot/command/impl/tickets/edit.go b/bot/command/impl/tickets/edit.go index ffdeb1c2..63c07b9f 100644 --- a/bot/command/impl/tickets/edit.go +++ b/bot/command/impl/tickets/edit.go @@ -49,7 +49,7 @@ func (EditCommand) Execute(ctx registry.CommandContext) { } ctx.ReplyWith(command.MessageResponse{ - Flags: message.SumFlags(message.FlagComponentsV2), + Flags: message.SumFlags(message.FlagIsComponentsV2), Components: []component.Component{ component.BuildContainer(component.Container{ Components: []component.Component{ @@ -69,7 +69,7 @@ func (EditCommand) Execute(ctx registry.CommandContext) { }, Accessory: component.BuildButton(component.Button{ Emoji: &emoji.Emoji{ - Name: "⚙️", + Name: utils.Ptr("⚙️"), }, CustomId: "update-ticket-labels-button", Style: component.ButtonStyleSecondary, diff --git a/bot/command/impl/tickets/open.go b/bot/command/impl/tickets/open.go index 8ba0975e..b34a6b00 100644 --- a/bot/command/impl/tickets/open.go +++ b/bot/command/impl/tickets/open.go @@ -24,7 +24,7 @@ func (OpenCommand) Properties() registry.Properties { PermissionLevel: permission.Everyone, Category: command.Tickets, Arguments: command.Arguments( - command.NewOptionalArgument("subject", "The subject of the ticket", interaction.OptionTypeString, "infallible"), + command.NewOptionalArgument("subject", "The subject of the ticket", interaction.ApplicationCommandOptionTypeString, "infallible"), ), DefaultEphemeral: true, Timeout: constants.TimeoutOpenTicket, diff --git a/bot/command/impl/tickets/remove.go b/bot/command/impl/tickets/remove.go index c21fe39b..d002ade1 100644 --- a/bot/command/impl/tickets/remove.go +++ b/bot/command/impl/tickets/remove.go @@ -30,7 +30,7 @@ func (RemoveCommand) Properties() registry.Properties { PermissionLevel: permcache.Everyone, Category: command.Tickets, Arguments: command.Arguments( - command.NewRequiredArgument("user_or_role", "User or role to remove from the current ticket", interaction.OptionTypeMentionable, i18n.MessageRemoveAdminNoMembers), + command.NewRequiredArgument("user_or_role", "User or role to remove from the current ticket", interaction.ApplicationCommandOptionTypeMentionable, i18n.MessageRemoveAdminNoMembers), ), Timeout: time.Second * 8, } @@ -236,7 +236,7 @@ func (RemoveCommand) Execute(ctx registry.CommandContext, id uint64) { } else { data := channel.PermissionOverwrite{ Id: id, - Type: channel.PermissionTypeMember, + Type: channel.PermissionOverwriteTypeMember, Allow: 0, Deny: permission.BuildPermissions(logic.StandardPermissions[:]...), } @@ -320,7 +320,7 @@ func (RemoveCommand) Execute(ctx registry.CommandContext, id uint64) { // Handle role removal data := channel.PermissionOverwrite{ Id: id, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: 0, Deny: permission.BuildPermissions(logic.StandardPermissions[:]...), } diff --git a/bot/command/impl/tickets/rename.go b/bot/command/impl/tickets/rename.go index 01cfe955..ed64271e 100644 --- a/bot/command/impl/tickets/rename.go +++ b/bot/command/impl/tickets/rename.go @@ -33,7 +33,7 @@ func (RenameCommand) Properties() registry.Properties { PermissionLevel: permission.Support, Category: command.Tickets, Arguments: command.Arguments( - command.NewRequiredArgument("name", "New name for the ticket", interaction.OptionTypeString, i18n.MessageRenameMissingName), + command.NewRequiredArgument("name", "New name for the ticket", interaction.ApplicationCommandOptionTypeString, i18n.MessageRenameMissingName), ), DefaultEphemeral: true, Timeout: time.Second * 5, @@ -117,10 +117,10 @@ func (RenameCommand) Execute(ctx registry.CommandContext, name string) { // %nickname% logic.NewSubstitutor("nickname", false, true, func(user user.User, member member.Member) string { nickname := member.Nick - if len(nickname) == 0 { - nickname = member.User.Username + if len(*nickname) == 0 { + nickname = &member.User.Username } - return nickname + return *nickname }), }, []logic.ParameterizedSubstitutor{ // %date% or %date:FORMAT% diff --git a/bot/command/impl/tickets/reopen.go b/bot/command/impl/tickets/reopen.go index f7bdcf75..c7fdced7 100644 --- a/bot/command/impl/tickets/reopen.go +++ b/bot/command/impl/tickets/reopen.go @@ -26,7 +26,7 @@ func (c ReopenCommand) Properties() registry.Properties { PermissionLevel: permission.Everyone, Category: command.Tickets, Arguments: command.Arguments( - command.NewRequiredAutocompleteableArgument("ticket_id", "ID of the ticket to reopen", interaction.OptionTypeInteger, i18n.MessageInvalidArgument, c.AutoCompleteHandler), + command.NewRequiredAutocompleteableArgument("ticket_id", "ID of the ticket to reopen", interaction.ApplicationCommandOptionTypeInteger, i18n.MessageInvalidArgument, c.AutoCompleteHandler), ), DefaultEphemeral: true, Timeout: time.Second * 10, diff --git a/bot/command/impl/tickets/startticket.go b/bot/command/impl/tickets/startticket.go index b7a7c574..556c4032 100644 --- a/bot/command/impl/tickets/startticket.go +++ b/bot/command/impl/tickets/startticket.go @@ -63,10 +63,14 @@ func (StartTicketCommand) Execute(ctx registry.CommandContext) { return } - messageId := interaction.Interaction.Data.TargetId + if interaction.Interaction.Data.TargetId == nil { + ctx.HandleError(errors.New("TargetId missing from interaction data")) + return + } + messageId := *interaction.Interaction.Data.TargetId msg, ok := interaction.ResolvedMessage(messageId) - if err != nil { + if !ok { ctx.HandleError(errors.New("Message missing from resolved data")) return } @@ -193,11 +197,14 @@ func addMessageSender(ctx registry.CommandContext, ticket database.Ticket, msg m } func sendMovedMessage(ctx registry.CommandContext, ticket database.Ticket, msg message.Message) { + channelId := ctx.ChannelId() + guildId := ctx.GuildId() + failIfNotExists := false reference := &message.MessageReference{ - MessageId: msg.Id, - ChannelId: ctx.ChannelId(), - GuildId: ctx.GuildId(), - FailIfNotExists: false, + MessageId: &msg.Id, + ChannelId: &channelId, + GuildId: &guildId, + FailIfNotExists: &failIfNotExists, } msgEmbed := utils.BuildEmbed(ctx, customisation.Green, i18n.Ticket, i18n.MessageMovedToTicket, nil, *ticket.ChannelId) diff --git a/bot/command/impl/tickets/switchpanel.go b/bot/command/impl/tickets/switchpanel.go index bacc0094..1b14112b 100644 --- a/bot/command/impl/tickets/switchpanel.go +++ b/bot/command/impl/tickets/switchpanel.go @@ -38,7 +38,7 @@ func (c SwitchPanelCommand) Properties() registry.Properties { Category: command.Tickets, InteractionOnly: true, Arguments: command.Arguments( - command.NewRequiredAutocompleteableArgument("panel", "Ticket panel to switch the ticket to", interaction.OptionTypeInteger, i18n.MessageInvalidUser, c.AutoCompleteHandler), // TODO: Fix invalid message + command.NewRequiredAutocompleteableArgument("panel", "Ticket panel to switch the ticket to", interaction.ApplicationCommandOptionTypeInteger, i18n.MessageInvalidUser, c.AutoCompleteHandler), // TODO: Fix invalid message ), Timeout: constants.TimeoutOpenTicket, } @@ -164,7 +164,7 @@ func (SwitchPanelCommand) Execute(ctx *cmdcontext.SlashCommandContext, panelId i if oldPanel != nil { // But skip if the user has manually renamed the channel (doesn't match old panel's generated name) oldChannelName, _ := logic.GenerateChannelName(ctx.Context, ctx.Worker(), oldPanel, ticket.GuildId, ticket.Id, ticket.UserId, utils.NilIfZero(claimer)) - if currentChannel.Name != oldChannelName { + if currentChannel.Name == nil || *currentChannel.Name != oldChannelName { shouldUpdateName = false } } diff --git a/bot/command/impl/tickets/transfer.go b/bot/command/impl/tickets/transfer.go index 945e4be2..80e3b8d2 100644 --- a/bot/command/impl/tickets/transfer.go +++ b/bot/command/impl/tickets/transfer.go @@ -26,7 +26,7 @@ func (TransferCommand) Properties() registry.Properties { PermissionLevel: permission.Support, Category: command.Tickets, Arguments: command.Arguments( - command.NewRequiredArgument("user", "Support representative to transfer the ticket to", interaction.OptionTypeUser, i18n.MessageInvalidUser), + command.NewRequiredArgument("user", "Support representative to transfer the ticket to", interaction.ApplicationCommandOptionTypeUser, i18n.MessageInvalidUser), ), Timeout: constants.TimeoutOpenTicket, } diff --git a/bot/command/impl/tickets/unclaim.go b/bot/command/impl/tickets/unclaim.go index dd7906c6..6e52a787 100644 --- a/bot/command/impl/tickets/unclaim.go +++ b/bot/command/impl/tickets/unclaim.go @@ -133,7 +133,7 @@ func (UnclaimCommand) Execute(ctx *context.SlashCommandContext) { if !claimerHasAccess { filteredOverwrites := make([]channel.PermissionOverwrite, 0, len(overwrites)) for _, ow := range overwrites { - if ow.Id != whoClaimed || ow.Type != channel.PermissionTypeMember { + if ow.Id != whoClaimed || ow.Type != channel.PermissionOverwriteTypeMember { filteredOverwrites = append(filteredOverwrites, ow) } } @@ -143,14 +143,14 @@ func (UnclaimCommand) Execute(ctx *context.SlashCommandContext) { case database.SwitchPanelKeepAccess: overwrites = append(overwrites, channel.PermissionOverwrite{ Id: whoClaimed, - Type: channel.PermissionTypeMember, + Type: channel.PermissionOverwriteTypeMember, Allow: discordpermission.BuildPermissions(logic.StandardPermissions[:]...), Deny: 0, }) case database.SwitchPanelRemoveOnUnclaim: overwrites = append(overwrites, channel.PermissionOverwrite{ Id: whoClaimed, - Type: channel.PermissionTypeMember, + Type: channel.PermissionOverwriteTypeMember, Allow: 0, Deny: discordpermission.BuildPermissions(discordpermission.ViewChannel), }) @@ -168,7 +168,7 @@ func (UnclaimCommand) Execute(ctx *context.SlashCommandContext) { // Always update the name to match the new panel's naming scheme shouldUpdateName := true claimedChannelName, _ := logic.GenerateChannelName(ctx.Context, ctx.Worker(), panel, ticket.GuildId, ticket.Id, ticket.UserId, &whoClaimed) - if ch.Name != claimedChannelName { + if ch.Name == nil || *ch.Name != claimedChannelName { shouldUpdateName = false } diff --git a/bot/command/manager/manager.go b/bot/command/manager/manager.go index f5f4e02c..1fb7995f 100644 --- a/bot/command/manager/manager.go +++ b/bot/command/manager/manager.go @@ -148,7 +148,6 @@ func buildOption(cmd registry.Command) interaction.ApplicationCommandOption { Type: argument.Type, Name: argument.Name, Description: argument.Description, - Default: false, Required: argument.Required, Choices: nil, Autocomplete: argument.AutoCompleteHandler != nil, @@ -165,16 +164,15 @@ func buildOption(cmd registry.Command) interaction.ApplicationCommandOption { options := append(required, optional...) // Determine the correct type based on whether this command has children - optionType := interaction.OptionTypeSubCommand + optionType := interaction.ApplicationCommandOptionTypeSubCommand if len(properties.Children) > 0 { - optionType = interaction.OptionTypeSubCommandGroup + optionType = interaction.ApplicationCommandOptionTypeSubCommandGroup } return interaction.ApplicationCommandOption{ Type: optionType, Name: properties.Name, Description: i18n.GetMessage(i18n.LocaleEnglish, properties.Description), - Default: false, Required: false, Choices: nil, Options: options, diff --git a/bot/command/mentionabletype.go b/bot/command/mentionabletype.go deleted file mode 100644 index d47dcf0d..00000000 --- a/bot/command/mentionabletype.go +++ /dev/null @@ -1 +0,0 @@ -package command diff --git a/bot/command/messageresponse.go b/bot/command/messageresponse.go index ed8c3fec..a90dd2b4 100644 --- a/bot/command/messageresponse.go +++ b/bot/command/messageresponse.go @@ -46,14 +46,14 @@ func NewEmbedMessageResponseWithComponents(e *embed.Embed, components []componen func NewMessageResponseWithComponents(components []component.Component) MessageResponse { return MessageResponse{ Components: components, - Flags: message.SumFlags(message.FlagComponentsV2), + Flags: message.SumFlags(message.FlagIsComponentsV2), } } func NewEphemeralMessageResponseWithComponents(components []component.Component) MessageResponse { return MessageResponse{ Components: components, - Flags: message.SumFlags(message.FlagEphemeral, message.FlagComponentsV2), + Flags: message.SumFlags(message.FlagEphemeral, message.FlagIsComponentsV2), } } diff --git a/bot/customisation/emoji.go b/bot/customisation/emoji.go index 1ab2833b..67690c62 100644 --- a/bot/customisation/emoji.go +++ b/bot/customisation/emoji.go @@ -32,7 +32,7 @@ func (e CustomEmoji) String() string { func (e CustomEmoji) BuildEmoji() *emoji.Emoji { return &emoji.Emoji{ Id: objects.NewNullableSnowflake(e.Id), - Name: e.Name, + Name: &e.Name, Animated: e.Animated, } } @@ -55,7 +55,6 @@ var ( EmojiPatreon = NewCustomEmoji("patreon", config.Conf.Emojis.Patreon, false) EmojiDiscord = NewCustomEmoji("discord", config.Conf.Emojis.Discord, false) EmojiLogo = NewCustomEmoji("TicketsLogo", config.Conf.Emojis.Logo, false) - //EmojiTime = NewCustomEmoji("time", 974006684622159952, false) ) // PrefixWithEmoji Useful for whitelabel bots diff --git a/bot/listeners/guildcreate.go b/bot/listeners/guildcreate.go index f07eec8b..be5c03eb 100644 --- a/bot/listeners/guildcreate.go +++ b/bot/listeners/guildcreate.go @@ -3,6 +3,7 @@ package listeners import ( "context" "fmt" + "strconv" "time" "github.com/TicketsBot-cloud/common/sentry" @@ -34,7 +35,7 @@ func OnGuildCreate(worker *worker.Context, e events.GuildCreate) { return } - if time.Now().Sub(e.JoinedAt) < time.Minute { + if time.Since(e.JoinedAt) < time.Minute { statsd.Client.IncrementKey(statsd.KeyJoins) sendIntroMessage(ctx, worker, e.Guild, e.Guild.OwnerId) @@ -92,7 +93,7 @@ func sendIntroMessage(ctx context.Context, worker *worker.Context, guild guild.G func getInviter(worker *worker.Context, guildId uint64) (userId uint64) { data := rest.GetGuildAuditLogData{ - ActionType: auditlog.EventBotAdd, + ActionType: auditlog.AuditLogEventBotAdd, Limit: 50, } @@ -102,12 +103,15 @@ func getInviter(worker *worker.Context, guildId uint64) (userId uint64) { return } + botIdStr := strconv.FormatUint(worker.BotId, 10) for _, entry := range auditLog.Entries { - if entry.ActionType != auditlog.EventBotAdd || entry.TargetId != worker.BotId { + if entry.ActionType != auditlog.AuditLogEventBotAdd || entry.TargetId == nil || *entry.TargetId != botIdStr { continue } - userId = entry.UserId + if entry.UserId != nil { + userId = *entry.UserId + } break } diff --git a/bot/listeners/listeners.go b/bot/listeners/listeners.go index 40e40a4f..18fd1931 100644 --- a/bot/listeners/listeners.go +++ b/bot/listeners/listeners.go @@ -1,12 +1,11 @@ -// Code generated by /tools/cmd/generatelisteners.go; DO NOT EDIT. -//go:generate go run ../../tools/cmd/generatelisteners.go +// Code generated by /tools/cmd/listeners/main.go; DO NOT EDIT. +//go:generate go run ../../tools/cmd/listeners package listeners import ( "encoding/json" "fmt" - "github.com/TicketsBot-cloud/gdl/gateway/payloads" "github.com/TicketsBot-cloud/gdl/gateway/payloads/events" "github.com/TicketsBot-cloud/worker" @@ -14,53 +13,85 @@ import ( ) var ( - ChannelCreateListeners = []func(*worker.Context, events.ChannelCreate){} - ChannelDeleteListeners = []func(*worker.Context, events.ChannelDelete){} - ChannelPinsUpdateListeners = []func(*worker.Context, events.ChannelPinsUpdate){} - ChannelUpdateListeners = []func(*worker.Context, events.ChannelUpdate){} - EntitlementCreateListeners = []func(*worker.Context, events.EntitlementCreate){} - EntitlementDeleteListeners = []func(*worker.Context, events.EntitlementDelete){} - EntitlementUpdateListeners = []func(*worker.Context, events.EntitlementUpdate){} - GuildBanAddListeners = []func(*worker.Context, events.GuildBanAdd){} - GuildBanRemoveListeners = []func(*worker.Context, events.GuildBanRemove){} - GuildCreateListeners = []func(*worker.Context, events.GuildCreate){} - GuildDeleteListeners = []func(*worker.Context, events.GuildDelete){} - GuildEmojisUpdateListeners = []func(*worker.Context, events.GuildEmojisUpdate){} - GuildIntegrationsUpdateListeners = []func(*worker.Context, events.GuildIntegrationsUpdate){} - GuildMemberAddListeners = []func(*worker.Context, events.GuildMemberAdd){} - GuildMemberRemoveListeners = []func(*worker.Context, events.GuildMemberRemove){} - GuildMemberUpdateListeners = []func(*worker.Context, events.GuildMemberUpdate){} - GuildMembersChunkListeners = []func(*worker.Context, events.GuildMembersChunk){} - GuildRoleCreateListeners = []func(*worker.Context, events.GuildRoleCreate){} - GuildRoleDeleteListeners = []func(*worker.Context, events.GuildRoleDelete){} - GuildRoleUpdateListeners = []func(*worker.Context, events.GuildRoleUpdate){} - GuildUpdateListeners = []func(*worker.Context, events.GuildUpdate){} - InvalidSessionListeners = []func(*worker.Context, events.InvalidSession){} - InviteCreateListeners = []func(*worker.Context, events.InviteCreate){} - InviteDeleteListeners = []func(*worker.Context, events.InviteDelete){} - MessageCreateListeners = []func(*worker.Context, events.MessageCreate){} - MessageDeleteListeners = []func(*worker.Context, events.MessageDelete){} - MessageDeleteBulkListeners = []func(*worker.Context, events.MessageDeleteBulk){} - MessageReactionAddListeners = []func(*worker.Context, events.MessageReactionAdd){} - MessageReactionRemoveListeners = []func(*worker.Context, events.MessageReactionRemove){} - MessageReactionRemoveAllListeners = []func(*worker.Context, events.MessageReactionRemoveAll){} - MessageReactionRemoveEmojiListeners = []func(*worker.Context, events.MessageReactionRemoveEmoji){} - MessageUpdateListeners = []func(*worker.Context, events.MessageUpdate){} - PresenceUpdateListeners = []func(*worker.Context, events.PresenceUpdate){} - ReadyListeners = []func(*worker.Context, events.Ready){} - ReconnectListeners = []func(*worker.Context, events.Reconnect){} - ResumedListeners = []func(*worker.Context, events.Resumed){} - ThreadCreateListeners = []func(*worker.Context, events.ThreadCreate){} - ThreadDeleteListeners = []func(*worker.Context, events.ThreadDelete){} - ThreadListSyncListeners = []func(*worker.Context, events.ThreadListSync){} - ThreadMemberUpdateListeners = []func(*worker.Context, events.ThreadMemberUpdate){} - ThreadMembersUpdateListeners = []func(*worker.Context, events.ThreadMembersUpdate){} - ThreadUpdateListeners = []func(*worker.Context, events.ThreadUpdate){} - TypingStartListeners = []func(*worker.Context, events.TypingStart){} - UserUpdateListeners = []func(*worker.Context, events.UserUpdate){} - VoiceServerUpdateListeners = []func(*worker.Context, events.VoiceServerUpdate){} - VoiceStateUpdateListeners = []func(*worker.Context, events.VoiceStateUpdate){} - WebhooksUpdateListeners = []func(*worker.Context, events.WebhooksUpdate){} + ApplicationCommandPermissionsUpdateListeners = []func(*worker.Context, events.ApplicationCommandPermissionsUpdate){} + AutoModerationActionExecutionListeners = []func(*worker.Context, events.AutoModerationActionExecution){} + AutoModerationRuleCreateListeners = []func(*worker.Context, events.AutoModerationRuleCreate){} + AutoModerationRuleDeleteListeners = []func(*worker.Context, events.AutoModerationRuleDelete){} + AutoModerationRuleUpdateListeners = []func(*worker.Context, events.AutoModerationRuleUpdate){} + ChannelCreateListeners = []func(*worker.Context, events.ChannelCreate){} + ChannelDeleteListeners = []func(*worker.Context, events.ChannelDelete){} + ChannelInfoListeners = []func(*worker.Context, events.ChannelInfo){} + ChannelPinsUpdateListeners = []func(*worker.Context, events.ChannelPinsUpdate){} + ChannelUpdateListeners = []func(*worker.Context, events.ChannelUpdate){} + EntitlementCreateListeners = []func(*worker.Context, events.EntitlementCreate){} + EntitlementDeleteListeners = []func(*worker.Context, events.EntitlementDelete){} + EntitlementUpdateListeners = []func(*worker.Context, events.EntitlementUpdate){} + GuildAuditLogEntryCreateListeners = []func(*worker.Context, events.GuildAuditLogEntryCreate){} + GuildBanAddListeners = []func(*worker.Context, events.GuildBanAdd){} + GuildBanRemoveListeners = []func(*worker.Context, events.GuildBanRemove){} + GuildCreateListeners = []func(*worker.Context, events.GuildCreate){} + GuildDeleteListeners = []func(*worker.Context, events.GuildDelete){} + GuildEmojisUpdateListeners = []func(*worker.Context, events.GuildEmojisUpdate){} + GuildIntegrationsUpdateListeners = []func(*worker.Context, events.GuildIntegrationsUpdate){} + GuildMemberAddListeners = []func(*worker.Context, events.GuildMemberAdd){} + GuildMemberRemoveListeners = []func(*worker.Context, events.GuildMemberRemove){} + GuildMemberUpdateListeners = []func(*worker.Context, events.GuildMemberUpdate){} + GuildMembersChunkListeners = []func(*worker.Context, events.GuildMembersChunk){} + GuildRoleCreateListeners = []func(*worker.Context, events.GuildRoleCreate){} + GuildRoleDeleteListeners = []func(*worker.Context, events.GuildRoleDelete){} + GuildRoleUpdateListeners = []func(*worker.Context, events.GuildRoleUpdate){} + GuildScheduledEventCreateListeners = []func(*worker.Context, events.GuildScheduledEventCreate){} + GuildScheduledEventDeleteListeners = []func(*worker.Context, events.GuildScheduledEventDelete){} + GuildScheduledEventUpdateListeners = []func(*worker.Context, events.GuildScheduledEventUpdate){} + GuildScheduledEventUserAddListeners = []func(*worker.Context, events.GuildScheduledEventUserAdd){} + GuildScheduledEventUserRemoveListeners = []func(*worker.Context, events.GuildScheduledEventUserRemove){} + GuildSoundboardSoundCreateListeners = []func(*worker.Context, events.GuildSoundboardSoundCreate){} + GuildSoundboardSoundDeleteListeners = []func(*worker.Context, events.GuildSoundboardSoundDelete){} + GuildSoundboardSoundUpdateListeners = []func(*worker.Context, events.GuildSoundboardSoundUpdate){} + GuildSoundboardSoundsUpdateListeners = []func(*worker.Context, events.GuildSoundboardSoundsUpdate){} + GuildStickersUpdateListeners = []func(*worker.Context, events.GuildStickersUpdate){} + GuildUpdateListeners = []func(*worker.Context, events.GuildUpdate){} + IntegrationCreateListeners = []func(*worker.Context, events.IntegrationCreate){} + IntegrationDeleteListeners = []func(*worker.Context, events.IntegrationDelete){} + IntegrationUpdateListeners = []func(*worker.Context, events.IntegrationUpdate){} + InvalidSessionListeners = []func(*worker.Context, events.InvalidSession){} + InviteCreateListeners = []func(*worker.Context, events.InviteCreate){} + InviteDeleteListeners = []func(*worker.Context, events.InviteDelete){} + MessageCreateListeners = []func(*worker.Context, events.MessageCreate){} + MessageDeleteListeners = []func(*worker.Context, events.MessageDelete){} + MessageDeleteBulkListeners = []func(*worker.Context, events.MessageDeleteBulk){} + MessagePollVoteAddListeners = []func(*worker.Context, events.MessagePollVoteAdd){} + MessagePollVoteRemoveListeners = []func(*worker.Context, events.MessagePollVoteRemove){} + MessageReactionAddListeners = []func(*worker.Context, events.MessageReactionAdd){} + MessageReactionRemoveListeners = []func(*worker.Context, events.MessageReactionRemove){} + MessageReactionRemoveAllListeners = []func(*worker.Context, events.MessageReactionRemoveAll){} + MessageReactionRemoveEmojiListeners = []func(*worker.Context, events.MessageReactionRemoveEmoji){} + MessageUpdateListeners = []func(*worker.Context, events.MessageUpdate){} + PresenceUpdateListeners = []func(*worker.Context, events.PresenceUpdate){} + ReadyListeners = []func(*worker.Context, events.Ready){} + ReconnectListeners = []func(*worker.Context, events.Reconnect){} + ResumedListeners = []func(*worker.Context, events.Resumed){} + SoundboardSoundsListeners = []func(*worker.Context, events.SoundboardSounds){} + StageInstanceCreateListeners = []func(*worker.Context, events.StageInstanceCreate){} + StageInstanceDeleteListeners = []func(*worker.Context, events.StageInstanceDelete){} + StageInstanceUpdateListeners = []func(*worker.Context, events.StageInstanceUpdate){} + SubscriptionCreateListeners = []func(*worker.Context, events.SubscriptionCreate){} + SubscriptionDeleteListeners = []func(*worker.Context, events.SubscriptionDelete){} + SubscriptionUpdateListeners = []func(*worker.Context, events.SubscriptionUpdate){} + ThreadCreateListeners = []func(*worker.Context, events.ThreadCreate){} + ThreadDeleteListeners = []func(*worker.Context, events.ThreadDelete){} + ThreadListSyncListeners = []func(*worker.Context, events.ThreadListSync){} + ThreadMemberUpdateListeners = []func(*worker.Context, events.ThreadMemberUpdate){} + ThreadMembersUpdateListeners = []func(*worker.Context, events.ThreadMembersUpdate){} + ThreadUpdateListeners = []func(*worker.Context, events.ThreadUpdate){} + TypingStartListeners = []func(*worker.Context, events.TypingStart){} + UserUpdateListeners = []func(*worker.Context, events.UserUpdate){} + VoiceChannelEffectSendListeners = []func(*worker.Context, events.VoiceChannelEffectSend){} + VoiceChannelStartTimeUpdateListeners = []func(*worker.Context, events.VoiceChannelStartTimeUpdate){} + VoiceChannelStatusUpdateListeners = []func(*worker.Context, events.VoiceChannelStatusUpdate){} + VoiceServerUpdateListeners = []func(*worker.Context, events.VoiceServerUpdate){} + VoiceStateUpdateListeners = []func(*worker.Context, events.VoiceStateUpdate){} + WebhooksUpdateListeners = []func(*worker.Context, events.WebhooksUpdate){} ) func HandleEvent(c *worker.Context, span *sentry.Span, payload payloads.Payload) error { @@ -70,6 +101,56 @@ func HandleEvent(c *worker.Context, span *sentry.Span, payload payloads.Payload) switch events.EventType(payload.EventName) { + case events.APPLICATION_COMMAND_PERMISSIONS_UPDATE: + var event events.ApplicationCommandPermissionsUpdate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range ApplicationCommandPermissionsUpdateListeners { + listener(c, event) + } + + case events.AUTO_MODERATION_ACTION_EXECUTION: + var event events.AutoModerationActionExecution + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range AutoModerationActionExecutionListeners { + listener(c, event) + } + + case events.AUTO_MODERATION_RULE_CREATE: + var event events.AutoModerationRuleCreate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range AutoModerationRuleCreateListeners { + listener(c, event) + } + + case events.AUTO_MODERATION_RULE_DELETE: + var event events.AutoModerationRuleDelete + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range AutoModerationRuleDeleteListeners { + listener(c, event) + } + + case events.AUTO_MODERATION_RULE_UPDATE: + var event events.AutoModerationRuleUpdate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range AutoModerationRuleUpdateListeners { + listener(c, event) + } + case events.CHANNEL_CREATE: var event events.ChannelCreate if err := json.Unmarshal(payload.Data, &event); err != nil { @@ -90,6 +171,16 @@ func HandleEvent(c *worker.Context, span *sentry.Span, payload payloads.Payload) listener(c, event) } + case events.CHANNEL_INFO: + var event events.ChannelInfo + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range ChannelInfoListeners { + listener(c, event) + } + case events.CHANNEL_PINS_UPDATE: var event events.ChannelPinsUpdate if err := json.Unmarshal(payload.Data, &event); err != nil { @@ -140,6 +231,16 @@ func HandleEvent(c *worker.Context, span *sentry.Span, payload payloads.Payload) listener(c, event) } + case events.GUILD_AUDIT_LOG_ENTRY_CREATE: + var event events.GuildAuditLogEntryCreate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range GuildAuditLogEntryCreateListeners { + listener(c, event) + } + case events.GUILD_BAN_ADD: var event events.GuildBanAdd if err := json.Unmarshal(payload.Data, &event); err != nil { @@ -270,6 +371,106 @@ func HandleEvent(c *worker.Context, span *sentry.Span, payload payloads.Payload) listener(c, event) } + case events.GUILD_SCHEDULED_EVENT_CREATE: + var event events.GuildScheduledEventCreate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range GuildScheduledEventCreateListeners { + listener(c, event) + } + + case events.GUILD_SCHEDULED_EVENT_DELETE: + var event events.GuildScheduledEventDelete + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range GuildScheduledEventDeleteListeners { + listener(c, event) + } + + case events.GUILD_SCHEDULED_EVENT_UPDATE: + var event events.GuildScheduledEventUpdate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range GuildScheduledEventUpdateListeners { + listener(c, event) + } + + case events.GUILD_SCHEDULED_EVENT_USER_ADD: + var event events.GuildScheduledEventUserAdd + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range GuildScheduledEventUserAddListeners { + listener(c, event) + } + + case events.GUILD_SCHEDULED_EVENT_USER_REMOVE: + var event events.GuildScheduledEventUserRemove + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range GuildScheduledEventUserRemoveListeners { + listener(c, event) + } + + case events.GUILD_SOUNDBOARD_SOUND_CREATE: + var event events.GuildSoundboardSoundCreate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range GuildSoundboardSoundCreateListeners { + listener(c, event) + } + + case events.GUILD_SOUNDBOARD_SOUND_DELETE: + var event events.GuildSoundboardSoundDelete + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range GuildSoundboardSoundDeleteListeners { + listener(c, event) + } + + case events.GUILD_SOUNDBOARD_SOUND_UPDATE: + var event events.GuildSoundboardSoundUpdate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range GuildSoundboardSoundUpdateListeners { + listener(c, event) + } + + case events.GUILD_SOUNDBOARD_SOUNDS_UPDATE: + var event events.GuildSoundboardSoundsUpdate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range GuildSoundboardSoundsUpdateListeners { + listener(c, event) + } + + case events.GUILD_STICKERS_UPDATE: + var event events.GuildStickersUpdate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range GuildStickersUpdateListeners { + listener(c, event) + } + case events.GUILD_UPDATE: var event events.GuildUpdate if err := json.Unmarshal(payload.Data, &event); err != nil { @@ -280,6 +481,36 @@ func HandleEvent(c *worker.Context, span *sentry.Span, payload payloads.Payload) listener(c, event) } + case events.INTEGRATION_CREATE: + var event events.IntegrationCreate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range IntegrationCreateListeners { + listener(c, event) + } + + case events.INTEGRATION_DELETE: + var event events.IntegrationDelete + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range IntegrationDeleteListeners { + listener(c, event) + } + + case events.INTEGRATION_UPDATE: + var event events.IntegrationUpdate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range IntegrationUpdateListeners { + listener(c, event) + } + case events.INVALID_SESSION: var event events.InvalidSession if err := json.Unmarshal(payload.Data, &event); err != nil { @@ -340,6 +571,26 @@ func HandleEvent(c *worker.Context, span *sentry.Span, payload payloads.Payload) listener(c, event) } + case events.MESSAGE_POLL_VOTE_ADD: + var event events.MessagePollVoteAdd + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range MessagePollVoteAddListeners { + listener(c, event) + } + + case events.MESSAGE_POLL_VOTE_REMOVE: + var event events.MessagePollVoteRemove + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range MessagePollVoteRemoveListeners { + listener(c, event) + } + case events.MESSAGE_REACTION_ADD: var event events.MessageReactionAdd if err := json.Unmarshal(payload.Data, &event); err != nil { @@ -430,6 +681,76 @@ func HandleEvent(c *worker.Context, span *sentry.Span, payload payloads.Payload) listener(c, event) } + case events.SOUNDBOARD_SOUNDS: + var event events.SoundboardSounds + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range SoundboardSoundsListeners { + listener(c, event) + } + + case events.STAGE_INSTANCE_CREATE: + var event events.StageInstanceCreate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range StageInstanceCreateListeners { + listener(c, event) + } + + case events.STAGE_INSTANCE_DELETE: + var event events.StageInstanceDelete + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range StageInstanceDeleteListeners { + listener(c, event) + } + + case events.STAGE_INSTANCE_UPDATE: + var event events.StageInstanceUpdate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range StageInstanceUpdateListeners { + listener(c, event) + } + + case events.SUBSCRIPTION_CREATE: + var event events.SubscriptionCreate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range SubscriptionCreateListeners { + listener(c, event) + } + + case events.SUBSCRIPTION_DELETE: + var event events.SubscriptionDelete + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range SubscriptionDeleteListeners { + listener(c, event) + } + + case events.SUBSCRIPTION_UPDATE: + var event events.SubscriptionUpdate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range SubscriptionUpdateListeners { + listener(c, event) + } + case events.THREAD_CREATE: var event events.ThreadCreate if err := json.Unmarshal(payload.Data, &event); err != nil { @@ -510,6 +831,36 @@ func HandleEvent(c *worker.Context, span *sentry.Span, payload payloads.Payload) listener(c, event) } + case events.VOICE_CHANNEL_EFFECT_SEND: + var event events.VoiceChannelEffectSend + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range VoiceChannelEffectSendListeners { + listener(c, event) + } + + case events.VOICE_CHANNEL_START_TIME_UPDATE: + var event events.VoiceChannelStartTimeUpdate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range VoiceChannelStartTimeUpdateListeners { + listener(c, event) + } + + case events.VOICE_CHANNEL_STATUS_UPDATE: + var event events.VoiceChannelStatusUpdate + if err := json.Unmarshal(payload.Data, &event); err != nil { + return err + } + + for _, listener := range VoiceChannelStatusUpdateListeners { + listener(c, event) + } + case events.VOICE_SERVER_UPDATE: var event events.VoiceServerUpdate if err := json.Unmarshal(payload.Data, &event); err != nil { diff --git a/bot/listeners/message.go b/bot/listeners/message.go index dcd8c821..efeabb4f 100644 --- a/bot/listeners/message.go +++ b/bot/listeners/message.go @@ -29,14 +29,19 @@ func OnMessage(worker *worker.Context, e events.MessageCreate) { span := sentry.StartTransaction(ctx, "OnMessage") defer span.Finish() - if e.GuildId != 0 { - span.SetTag("guild_id", strconv.FormatUint(e.GuildId, 10)) + var guildId uint64 + if e.GuildId != nil { + guildId = *e.GuildId + } + + if guildId != 0 { + span.SetTag("guild_id", strconv.FormatUint(guildId, 10)) } statsd.Client.IncrementKey(statsd.KeyMessages) // ignore DMs - if e.GuildId == 0 { + if guildId == 0 { return } @@ -70,7 +75,7 @@ func OnMessage(worker *worker.Context, e events.MessageCreate) { if e.Author.Id != worker.BotId && !e.Author.Bot { // set participants, for logging sentry.WithSpan0(span.Context(), "Add participant", func(span *sentry.Span) { - if err := dbclient.Client.Participants.Set(ctx, e.GuildId, ticket.Id, e.Author.Id); err != nil { + if err := dbclient.Client.Participants.Set(ctx, guildId, ticket.Id, e.Author.Id); err != nil { sentry.ErrorWithContext(err, utils.MessageCreateErrorContext(e)) } }) @@ -95,7 +100,7 @@ func OnMessage(worker *worker.Context, e events.MessageCreate) { if *isStaffCached { // check the user is staff // We don't have to check for previous responses due to ON CONFLICT DO NOTHING sentry.WithSpan0(span.Context(), "Set first response time", func(span *sentry.Span) { - if err := dbclient.Client.FirstResponseTime.Set(ctx, e.GuildId, e.Author.Id, ticket.Id, time.Now().Sub(ticket.OpenTime)); err != nil { + if err := dbclient.Client.FirstResponseTime.Set(ctx, guildId, e.Author.Id, ticket.Id, time.Since(ticket.OpenTime)); err != nil { sentry.ErrorWithContext(err, utils.MessageCreateErrorContext(e)) } }) @@ -104,7 +109,7 @@ func OnMessage(worker *worker.Context, e events.MessageCreate) { } premiumTier, err := sentry.WithSpan2(span.Context(), "Get premium tier", func(span *sentry.Span) (premium.PremiumTier, error) { - return utils.PremiumClient.GetTierByGuildId(ctx, e.GuildId, true, worker.Token, worker.RateLimiter) + return utils.PremiumClient.GetTierByGuildId(ctx, guildId, true, worker.Token, worker.RateLimiter) }) if err != nil { sentry.ErrorWithContext(err, utils.MessageCreateErrorContext(e)) @@ -149,13 +154,13 @@ func OnMessage(worker *worker.Context, e events.MessageCreate) { } if ticket.Status != newStatus { - if err := dbclient.Client.Tickets.SetStatus(ctx, e.GuildId, ticket.Id, newStatus); err != nil { + if err := dbclient.Client.Tickets.SetStatus(ctx, guildId, ticket.Id, newStatus); err != nil { sentry.ErrorWithContext(err, utils.MessageCreateErrorContext(e)) } if !ticket.IsThread { if err := sentry.WithSpan1(span.Context(), "Update status update queue", func(span *sentry.Span) error { - return dbclient.Client.CategoryUpdateQueue.Add(ctx, e.GuildId, ticket.Id, newStatus) + return dbclient.Client.CategoryUpdateQueue.Add(ctx, guildId, ticket.Id, newStatus) }); err != nil { sentry.ErrorWithContext(err, utils.MessageCreateErrorContext(e)) } diff --git a/bot/listeners/threadupdate.go b/bot/listeners/threadupdate.go index 872a79c7..d24bcf06 100644 --- a/bot/listeners/threadupdate.go +++ b/bot/listeners/threadupdate.go @@ -24,19 +24,24 @@ func OnThreadUpdate(worker *worker.Context, e events.ThreadUpdate) { return } - settings, err := dbclient.Client.Settings.Get(ctx, e.GuildId) + if e.GuildId == nil { + return + } + guildId := *e.GuildId + + settings, err := dbclient.Client.Settings.Get(ctx, guildId) if err != nil { - sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: e.GuildId}) + sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: guildId}) return } - ticket, err := dbclient.Client.Tickets.GetByChannelAndGuild(ctx, e.Id, e.GuildId) + ticket, err := dbclient.Client.Tickets.GetByChannelAndGuild(ctx, e.Id, guildId) if err != nil { - sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: e.GuildId}) + sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: guildId}) return } - if ticket.Id == 0 || ticket.GuildId != e.GuildId { + if ticket.Id == 0 || ticket.GuildId != guildId { return } @@ -50,32 +55,32 @@ func OnThreadUpdate(worker *worker.Context, e events.ThreadUpdate) { if ticket.PanelId != nil { tmp, err := dbclient.Client.Panel.GetById(ctx, *ticket.PanelId) if err != nil { - sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: e.GuildId}) + sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: guildId}) return } - if tmp.PanelId != 0 && e.GuildId == tmp.GuildId { + if tmp.PanelId != 0 && guildId == tmp.GuildId { panel = &tmp } } - premiumTier, err := utils.PremiumClient.GetTierByGuildId(ctx, e.GuildId, true, worker.Token, worker.RateLimiter) + premiumTier, err := utils.PremiumClient.GetTierByGuildId(ctx, guildId, true, worker.Token, worker.RateLimiter) if err != nil { - sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: e.GuildId}) + sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: guildId}) return } // Handle thread being unarchived if !ticket.Open && !e.ThreadMetadata.Archived && !e.ThreadMetadata.Locked { if err := dbclient.Client.Tickets.SetOpen(ctx, ticket.GuildId, ticket.Id); err != nil { - sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: e.GuildId}) + sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: guildId}) return } if settings.TicketNotificationChannel != nil { staffCount, err := logic.GetStaffInThread(ctx, worker, ticket, e.Id) if err != nil { - sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: e.GuildId}) + sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: guildId}) return } @@ -83,12 +88,12 @@ func OnThreadUpdate(worker *worker.Context, e events.ThreadUpdate) { data := logic.BuildThreadReopenMessage(ctx, worker, ticket.GuildId, ticket.UserId, name, ticket.Id, panel, staffCount, premiumTier) msg, err := worker.CreateMessageComplex(*settings.TicketNotificationChannel, data.IntoCreateMessageData()) if err != nil { - sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: e.GuildId}) + sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: guildId}) return } if err := dbclient.Client.Tickets.SetJoinMessageId(ctx, ticket.GuildId, ticket.Id, &msg.Id); err != nil { - sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: e.GuildId}) + sentry.ErrorWithContext(err, errorcontext.WorkerErrorContext{Guild: guildId}) return } } diff --git a/bot/logic/claim.go b/bot/logic/claim.go index a580ad1f..98daaf92 100644 --- a/bot/logic/claim.go +++ b/bot/logic/claim.go @@ -17,6 +17,7 @@ import ( "github.com/TicketsBot-cloud/worker/bot/command/registry" "github.com/TicketsBot-cloud/worker/bot/customisation" "github.com/TicketsBot-cloud/worker/bot/dbclient" + "github.com/TicketsBot-cloud/worker/bot/utils" "github.com/TicketsBot-cloud/worker/i18n" "golang.org/x/sync/errgroup" ) @@ -72,7 +73,7 @@ func ClaimTicket(ctx context.Context, cmd registry.CommandContext, ticket databa shouldUpdateName := true // But skip if the user has manually renamed the channel (doesn't match old unclaimed name) oldChannelName, _ := GenerateChannelName(ctx, cmd.Worker(), panel, ticket.GuildId, ticket.Id, ticket.UserId, nil) - if currentChannel.Name != oldChannelName { + if currentChannel.Name == nil || *currentChannel.Name != oldChannelName { shouldUpdateName = false } @@ -193,7 +194,7 @@ func overwritesCantView(claimer, selfId, openerId, guildId uint64, adminUsers, a overwrites = append(overwrites, BuildUserOverwrite(openerId, additionalPermissions), channel.PermissionOverwrite{ // @everyone Id: guildId, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: 0, Deny: permission.BuildPermissions(permission.ViewChannel), }, @@ -218,7 +219,7 @@ func overwritesCantView(claimer, selfId, openerId, guildId uint64, adminUsers, a for _, userId := range adminUserTargets { overwrites = append(overwrites, channel.PermissionOverwrite{ Id: userId, - Type: channel.PermissionTypeMember, + Type: channel.PermissionOverwriteTypeMember, Allow: permission.BuildPermissions(StandardPermissions[:]...), Deny: 0, }) @@ -227,7 +228,7 @@ func overwritesCantView(claimer, selfId, openerId, guildId uint64, adminUsers, a for _, roleId := range adminRoleTargets { overwrites = append(overwrites, channel.PermissionOverwrite{ Id: roleId, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: permission.BuildPermissions(StandardPermissions[:]...), Deny: 0, }) @@ -244,7 +245,7 @@ func overwritesCantType(claimerId, selfId, openerId, guildId uint64, supportUser overwrites = append(overwrites, BuildUserOverwrite(openerId, additionalPermissions), channel.PermissionOverwrite{ // @everyone Id: guildId, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: 0, Deny: permission.BuildPermissions(permission.ViewChannel), }, @@ -268,7 +269,7 @@ func overwritesCantType(claimerId, selfId, openerId, guildId uint64, supportUser for _, userId := range adminUserTargets { overwrites = append(overwrites, channel.PermissionOverwrite{ Id: userId, - Type: channel.PermissionTypeMember, + Type: channel.PermissionOverwriteTypeMember, Allow: permission.BuildPermissions(StandardPermissions[:]...), Deny: 0, }) @@ -277,7 +278,7 @@ func overwritesCantType(claimerId, selfId, openerId, guildId uint64, supportUser for _, roleId := range adminRoleTargets { overwrites = append(overwrites, channel.PermissionOverwrite{ Id: roleId, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: permission.BuildPermissions(StandardPermissions[:]...), Deny: 0, }) @@ -297,7 +298,7 @@ func overwritesCantType(claimerId, selfId, openerId, guildId uint64, supportUser overwrites = append(overwrites, channel.PermissionOverwrite{ Id: userId, - Type: channel.PermissionTypeMember, + Type: channel.PermissionOverwriteTypeMember, Allow: permission.BuildPermissions(readOnlyAllowed...), Deny: permission.BuildPermissions(readOnlyDenied...), }) @@ -317,7 +318,7 @@ func overwritesCantType(claimerId, selfId, openerId, guildId uint64, supportUser overwrites = append(overwrites, channel.PermissionOverwrite{ Id: roleId, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: permission.BuildPermissions(readOnlyAllowed...), Deny: permission.BuildPermissions(readOnlyDenied...), }) @@ -360,7 +361,7 @@ func UpdateWelcomeMessageClaimButton(ctx context.Context, worker *worker.Context Label: cmd.GetMessage(i18n.TitleUnclaim), CustomId: "unclaim", Style: component.ButtonStyleSecondary, - Emoji: &emoji.Emoji{Name: "🙋‍♂️"}, + Emoji: &emoji.Emoji{Name: utils.Ptr("🙋‍♂️")}, }) updated = true break @@ -370,7 +371,7 @@ func UpdateWelcomeMessageClaimButton(ctx context.Context, worker *worker.Context Label: cmd.GetMessage(i18n.TitleClaim), CustomId: "claim", Style: component.ButtonStyleSuccess, - Emoji: &emoji.Emoji{Name: "🙋‍♂️"}, + Emoji: &emoji.Emoji{Name: utils.Ptr("🙋‍♂️")}, }) updated = true break diff --git a/bot/logic/close.go b/bot/logic/close.go index 4c40c367..9c0d6ba3 100644 --- a/bot/logic/close.go +++ b/bot/logic/close.go @@ -416,7 +416,7 @@ func sendCloseEmbed(ctx context.Context, cmd registry.CommandContext, errorConte } closeEmbed, closeComponents := BuildCloseEmbed(ctx, cmd.Worker(), ticket, member.User.Id, reason, nil, componentBuilders) - closeEmbed.SetAuthor(guild.Name, "", fmt.Sprintf("https://cdn.discordapp.com/icons/%d/%s.png", guild.Id, guild.Icon)) + closeEmbed.SetAuthor(guild.Name, "", guild.IconUrl()) // Use message content to tell users why they can't rate a ticket var content string diff --git a/bot/logic/closeembed.go b/bot/logic/closeembed.go index a43460f9..ba693268 100644 --- a/bot/logic/closeembed.go +++ b/bot/logic/closeembed.go @@ -114,7 +114,7 @@ func FeedbackRowElement(condition bool) CloseEmbedElement { CustomId: fmt.Sprintf("rate_%d_%d_%d", ticket.GuildId, ticket.Id, i), Style: style, Emoji: &emoji.Emoji{ - Name: "⭐", + Name: utils.Ptr("⭐"), }, }) } @@ -272,7 +272,12 @@ func EditDMMessageIfExists( } closeEmbed, closeComponents := BuildCloseEmbed(ctx, w, ticket, closedBy, reason, rating, componentBuilders) - closeEmbed.SetAuthor(guild.Name, "", fmt.Sprintf("https://cdn.discordapp.com/icons/%d/%s.png", guild.Id, guild.Icon)) + + guildIconUrl := "" + if guild.Icon != nil { + guildIconUrl = fmt.Sprintf("https://cdn.discordapp.com/icons/%d/%s.png", guild.Id, *guild.Icon) + } + closeEmbed.SetAuthor(guild.Name, "", guildIconUrl) _, err = w.EditMessage(dmChannel.Id, dmMessage.MessageId, rest.EditMessageData{ Embeds: utils.Slice(closeEmbed), diff --git a/bot/logic/discordpermissions.go b/bot/logic/discordpermissions.go index 619a4349..1683cd7a 100644 --- a/bot/logic/discordpermissions.go +++ b/bot/logic/discordpermissions.go @@ -85,7 +85,7 @@ func BuildUserOverwrite(userId uint64, additionalPermissions database.TicketPerm return channel.PermissionOverwrite{ Id: userId, - Type: channel.PermissionTypeMember, + Type: channel.PermissionOverwriteTypeMember, Allow: permission.BuildPermissions(allow...), Deny: permission.BuildPermissions(deny...), } @@ -139,7 +139,7 @@ func BuildRoleOverwrite(roleId uint64, additionalPermissions database.TicketPerm return channel.PermissionOverwrite{ Id: roleId, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: permission.BuildPermissions(allow...), Deny: permission.BuildPermissions(deny...), } @@ -176,7 +176,7 @@ func BuildStaffUserOverwrite(userId uint64, p database.SupportTeamPermissions) c allow, deny := buildStaffPermissions(p) return channel.PermissionOverwrite{ Id: userId, - Type: channel.PermissionTypeMember, + Type: channel.PermissionOverwriteTypeMember, Allow: permission.BuildPermissions(allow...), Deny: permission.BuildPermissions(deny...), } @@ -187,7 +187,7 @@ func BuildStaffRoleOverwrite(roleId uint64, p database.SupportTeamPermissions) c allow, deny := buildStaffPermissions(p) return channel.PermissionOverwrite{ Id: roleId, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: permission.BuildPermissions(allow...), Deny: permission.BuildPermissions(deny...), } diff --git a/bot/logic/open.go b/bot/logic/open.go index ccdb3aa5..5ce0b440 100644 --- a/bot/logic/open.go +++ b/bot/logic/open.go @@ -357,12 +357,12 @@ func OpenTicket(ctx context.Context, cmd registry.InteractionContext, panel *dat data := rest.CreateChannelData{ Name: name, Type: channel.ChannelTypeGuildText, - Topic: subject, + Topic: &subject, PermissionOverwrites: overwrites, } if useCategory { - data.ParentId = category + data.ParentId = &category } span = sentry.StartSpan(rootSpan.Context(), "Create channel") @@ -566,9 +566,9 @@ func OpenTicket(ctx context.Context, cmd registry.InteractionContext, panel *dat Content: content, AllowedMentions: message.AllowedMention{ Parse: []message.AllowedMentionType{ - message.EVERYONE, - message.USERS, - message.ROLES, + message.AllowedMentionTypeEveryone, + message.AllowedMentionTypeUsers, + message.AllowedMentionTypeRoles, }, }, }) @@ -908,7 +908,7 @@ func CreateOverwrites(ctx context.Context, cmd registry.InteractionContext, user overwrites := []channel.PermissionOverwrite{ // @everyone { Id: cmd.GuildId(), - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: 0, Deny: permission.BuildPermissions(permission.ViewChannel), }, @@ -968,14 +968,14 @@ func CreateOverwrites(ctx context.Context, cmd registry.InteractionContext, user if integrationRoleId == nil { overwrites = append(overwrites, channel.PermissionOverwrite{ Id: cmd.Worker().BotId, - Type: channel.PermissionTypeMember, + Type: channel.PermissionOverwriteTypeMember, Allow: permission.BuildPermissions(selfAllow[:]...), Deny: 0, }) } else { overwrites = append(overwrites, channel.PermissionOverwrite{ Id: *integrationRoleId, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: permission.BuildPermissions(selfAllow[:]...), Deny: 0, }) @@ -1003,7 +1003,7 @@ func CreateOverwrites(ctx context.Context, cmd registry.InteractionContext, user overwrites = append(overwrites, channel.PermissionOverwrite{ Id: member, - Type: channel.PermissionTypeMember, + Type: channel.PermissionOverwriteTypeMember, Allow: permission.BuildPermissions(allow...), Deny: 0, }) @@ -1012,7 +1012,7 @@ func CreateOverwrites(ctx context.Context, cmd registry.InteractionContext, user for _, role := range supportRoles { overwrites = append(overwrites, channel.PermissionOverwrite{ Id: role, - Type: channel.PermissionTypeRole, + Type: channel.PermissionOverwriteTypeRole, Allow: permission.BuildPermissions(StandardPermissions[:]...), Deny: 0, }) @@ -1232,12 +1232,10 @@ func GenerateChannelName(ctx context.Context, worker *worker.Context, panel *dat }), // %nickname% NewSubstitutor("nickname", false, true, func(user user.User, member member.Member) string { - nickname := member.Nick - if len(nickname) == 0 { - nickname = member.User.Username + if member.Nick != nil && len(*member.Nick) > 0 { + return *member.Nick } - - return nickname + return user.Username }), }, []ParameterizedSubstitutor{ // %date% or %date:FORMAT% (e.g., %date:yyyy-mm-dd%) @@ -1380,7 +1378,7 @@ func countRealChannels(channels []channel.Channel, parentId uint64) int { for _, ch := range channels { // Ignore threads - if ch.Type == channel.ChannelTypeGuildPublicThread || ch.Type == channel.ChannelTypeGuildPrivateThread || ch.Type == channel.ChannelTypeGuildNewsThread { + if ch.Type == channel.ChannelTypePublicThread || ch.Type == channel.ChannelTypePrivateThread || ch.Type == channel.ChannelTypeAnnouncementThread { continue } diff --git a/bot/logic/permissions.go b/bot/logic/permissions.go index 37b523ea..4e6f3102 100644 --- a/bot/logic/permissions.go +++ b/bot/logic/permissions.go @@ -284,7 +284,7 @@ func FilterStaffMembers( return err } - if excludeBots && member.User.Bot { + if excludeBots && member.User != nil && member.User.Bot { return nil } @@ -342,9 +342,11 @@ func GetStaffInThread(ctx context.Context, worker *worker.Context, ticket databa return nil, err } - memberIds := make([]uint64, len(members)) - for i, member := range members { - memberIds[i] = member.UserId + memberIds := make([]uint64, 0, len(members)) + for _, member := range members { + if member.UserId != nil { + memberIds = append(memberIds, *member.UserId) + } } staffIds, err := FilterStaffMembers(ctx, worker, ticket.GuildId, ticket, memberIds, true, true) diff --git a/bot/logic/welcomemessage.go b/bot/logic/welcomemessage.go index 7414a4ed..f88edd4e 100644 --- a/bot/logic/welcomemessage.go +++ b/bot/logic/welcomemessage.go @@ -84,7 +84,7 @@ func SendWelcomeMessage( Label: cmd.GetMessage(i18n.TitleClose), CustomId: "close", Style: component.ButtonStyleDanger, - Emoji: &emoji.Emoji{Name: "🔒"}, + Emoji: &emoji.Emoji{Name: utils.Ptr("🔒")}, })) } if !hideCloseWithReason { @@ -92,7 +92,7 @@ func SendWelcomeMessage( Label: cmd.GetMessage(i18n.TitleCloseWithReason), CustomId: "close_with_reason", Style: component.ButtonStyleDanger, - Emoji: &emoji.Emoji{Name: "🔒"}, + Emoji: &emoji.Emoji{Name: utils.Ptr("🔒")}, })) } @@ -101,7 +101,7 @@ func SendWelcomeMessage( Label: cmd.GetMessage(i18n.TitleClaim), CustomId: "claim", Style: component.ButtonStyleSuccess, - Emoji: &emoji.Emoji{Name: "🙋‍♂️"}, + Emoji: &emoji.Emoji{Name: utils.Ptr("🙋‍♂️")}, })) } @@ -468,7 +468,13 @@ var substitutions = map[string]PlaceholderSubstitutionFunc{ }, "nickname": func(ctx context.Context, worker *worker.Context, ticket database.Ticket) string { member, _ := worker.GetGuildMember(ticket.GuildId, ticket.UserId) - return member.Nick + if member.Nick != nil && len(*member.Nick) > 0 { + return *member.Nick + } + if member.User != nil { + return member.User.Username + } + return "" }, "server": func(ctx context.Context, worker *worker.Context, ticket database.Ticket) string { guild, _ := worker.GetGuild(ticket.GuildId) diff --git a/bot/metrics/statsd/statsd.go b/bot/metrics/statsd/statsd.go index c0f562bd..af3c9daa 100644 --- a/bot/metrics/statsd/statsd.go +++ b/bot/metrics/statsd/statsd.go @@ -37,12 +37,9 @@ func (c *StatsdClient) StartDaemon() { ticker := time.NewTicker(time.Second * 15) defer ticker.Stop() - for { - select { - case _ = <-ticker.C: - for key, count := range c.buffer { - c.client.Count(key.String(), count.Swap(0)) - } + for range ticker.C { + for key, count := range c.buffer { + c.client.Count(key.String(), count.Swap(0)) } } } diff --git a/bot/permissionwrapper/permission.go b/bot/permissionwrapper/permission.go index cf66095e..20df4e8f 100644 --- a/bot/permissionwrapper/permission.go +++ b/bot/permissionwrapper/permission.go @@ -55,42 +55,6 @@ func HasPermissions(ctx *worker.Context, guildId, userId uint64, permissions ... return hasPermission } -func getAllPermissionsChannel(ctx *worker.Context, guildId, userId, channelId uint64) []permission.Permission { - permissions := make([]permission.Permission, 0) - - sum, err := getEffectivePermissionsChannel(ctx, guildId, userId, channelId) - if err != nil { - sentry.Error(err) - return permissions - } - - for _, perm := range permission.AllPermissions { - if permission.HasPermissionRaw(sum, perm) { - permissions = append(permissions, perm) - } - } - - return permissions -} - -func getAllPermissions(ctx *worker.Context, guildId, userId uint64) []permission.Permission { - permissions := make([]permission.Permission, 0) - - sum, err := getEffectivePermissions(ctx, guildId, userId) - if err != nil { - sentry.Error(err) - return permissions - } - - for _, perm := range permission.AllPermissions { - if permission.HasPermissionRaw(sum, perm) { - permissions = append(permissions, perm) - } - } - - return permissions -} - func GetMissingPermissions(ctx *worker.Context, guildId, userId uint64, required ...permission.Permission) []permission.Permission { missing := make([]permission.Permission, 0) @@ -185,7 +149,7 @@ func getChannelMemberPermissions(ctx *worker.Context, userId, channelId uint64, } for _, overwrite := range ch.PermissionOverwrites { - if overwrite.Type == channel.PermissionTypeMember && overwrite.Id == userId { + if overwrite.Type == channel.PermissionOverwriteTypeMember && overwrite.Id == userId { initialPermissions &= ^overwrite.Deny initialPermissions |= overwrite.Allow } @@ -216,7 +180,7 @@ func getChannelTotalRolePermissions(ctx *worker.Context, guildId, userId, channe for _, role := range roles { if memberRole == role.Id { for _, overwrite := range ch.PermissionOverwrites { - if overwrite.Type == channel.PermissionTypeRole && overwrite.Id == role.Id { + if overwrite.Type == channel.PermissionOverwriteTypeRole && overwrite.Id == role.Id { allow |= overwrite.Allow deny |= overwrite.Deny break @@ -256,7 +220,7 @@ func getChannelBasePermissions(ctx *worker.Context, guildId, channelId uint64, i } for _, overwrite := range ch.PermissionOverwrites { - if overwrite.Type == channel.PermissionTypeRole && overwrite.Id == publicRole.Id { + if overwrite.Type == channel.PermissionOverwriteTypeRole && overwrite.Id == publicRole.Id { initialPermissions &= ^overwrite.Deny initialPermissions |= overwrite.Allow break diff --git a/bot/utils/errorutils.go b/bot/utils/errorutils.go index 497a3faf..ebf45421 100644 --- a/bot/utils/errorutils.go +++ b/bot/utils/errorutils.go @@ -6,8 +6,12 @@ import ( ) func MessageCreateErrorContext(e events.MessageCreate) errorcontext.WorkerErrorContext { + var guildId uint64 + if e.GuildId != nil { + guildId = *e.GuildId + } return errorcontext.WorkerErrorContext{ - Guild: e.GuildId, + Guild: guildId, User: e.Author.Id, Channel: e.ChannelId, } diff --git a/bot/utils/messageutils.go b/bot/utils/messageutils.go index 8ef99377..959e5d81 100644 --- a/bot/utils/messageutils.go +++ b/bot/utils/messageutils.go @@ -96,7 +96,7 @@ func EmbedField(guildId uint64, name string, value i18n.MessageId, inline bool, func BuildEmoji(emote string) *emoji.Emoji { return &emoji.Emoji{ - Name: emote, + Name: &emote, } } diff --git a/cmd/exportmessages/main.go b/cmd/exportmessages/main.go deleted file mode 100644 index 76ac47ac..00000000 --- a/cmd/exportmessages/main.go +++ /dev/null @@ -1,36 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - - "github.com/TicketsBot-cloud/worker/bot/dbclient" - "github.com/TicketsBot-cloud/worker/i18n" -) - -func main() { - dbclient.Connect() - translations, err := dbclient.Client.Translations.GetAll() - must(err) - - for lang, msgs := range translations { - newMsgs := make(map[i18n.MessageId]string) - for i, msg := range msgs { - msgId := i18n.Messages[i] - newMsgs[msgId] = msg - } - - encoded, err := json.MarshalIndent(newMsgs, "", " ") - must(err) - - path := fmt.Sprintf("./locale/%s.json", lang) - must(ioutil.WriteFile(path, encoded, 0)) - } -} - -func must(err error) { - if err != nil { - panic(err) - } -} diff --git a/cmd/registercommands/main.go b/cmd/registercommands/main.go index 3ae3f239..01fa4b4d 100644 --- a/cmd/registercommands/main.go +++ b/cmd/registercommands/main.go @@ -46,7 +46,7 @@ func main() { // Handle admin commands for a specific guild, merging if requested if *AdminCommandGuildId != 0 { if *MergeGuildCommands { - existingCmds := must(rest.GetGuildCommands(context.Background(), *Token, nil, applicationId, *AdminCommandGuildId)) + existingCmds := must(rest.GetGuildCommands(context.Background(), *Token, nil, applicationId, *AdminCommandGuildId, false)) for _, cmd := range existingCmds { var found bool for _, newCmd := range adminCommands { @@ -71,7 +71,7 @@ func main() { } // Output all global commands as JSON - cmds := must(rest.GetGlobalCommands(context.Background(), *Token, nil, applicationId)) + cmds := must(rest.GetGlobalCommands(context.Background(), *Token, nil, applicationId, false)) marshalled := must(json.MarshalIndent(cmds, "", " ")) fmt.Println(string(marshalled)) } diff --git a/cmd/worker/main.go b/cmd/worker/main.go index dd43762a..7b43dd34 100644 --- a/cmd/worker/main.go +++ b/cmd/worker/main.go @@ -32,8 +32,6 @@ import ( "github.com/TicketsBot-cloud/worker/event" "github.com/TicketsBot-cloud/worker/i18n" "go.uber.org/zap" - - _ "github.com/joho/godotenv/autoload" ) func main() { @@ -160,11 +158,12 @@ func main() { go blacklist.StartCacheRefreshLoop(logger.With(zap.String("service", "blacklist_refresh"))) - if config.Conf.WorkerMode == config.WorkerModeInteractions { + switch config.Conf.WorkerMode { + case config.WorkerModeInteractions: logger.Info("Starting HTTP server", zap.String("mode", string(config.Conf.WorkerMode))) event.HttpListen(redis.Client, &pgCache) - } else if config.Conf.WorkerMode == config.WorkerModeGateway { + case config.WorkerModeGateway: logger.Info("Starting event listeners", zap.String("mode", string(config.Conf.WorkerMode))) go event.HttpListen(redis.Client, &pgCache) @@ -216,7 +215,7 @@ func main() { if !sentry.Flush(2 * time.Second) { logger.Warn("Sentry flush timed out, some events may be lost") } - } else { + default: logger.Fatal("Invalid worker mode", zap.String("mode", string(config.Conf.WorkerMode))) } } diff --git a/event/caller.go b/event/caller.go index 50dc25bd..21fb09d7 100644 --- a/event/caller.go +++ b/event/caller.go @@ -1,12 +1,10 @@ -// Code generated by /tools/cmd/generatecmdcaller.go; DO NOT EDIT. -//go:generate go run ../tools/cmd/generatecmdcaller.go +// Code generated by /tools/cmd/cmdcaller/main.go; DO NOT EDIT. +//go:generate go run ../tools/cmd/cmdcaller package event import ( "fmt" - "strconv" - "github.com/TicketsBot-cloud/gdl/objects/interaction" "github.com/TicketsBot-cloud/worker/bot/command" cmdcontext "github.com/TicketsBot-cloud/worker/bot/command/context" @@ -20,6 +18,7 @@ import ( "github.com/TicketsBot-cloud/worker/bot/command/impl/tickets" "github.com/TicketsBot-cloud/worker/bot/command/registry" "github.com/pkg/errors" + "strconv" ) var ErrArgumentNotFound = errors.New("argument not found") diff --git a/event/errorcontext.go b/event/errorcontext.go index 3fa75fc7..b8ddcc12 100644 --- a/event/errorcontext.go +++ b/event/errorcontext.go @@ -45,14 +45,6 @@ func NewMessageComponentInteractionErrorContext(data interaction.InteractionMeta m["user_id"] = strconv.FormatUint(data.User.Id, 10) } - /* - if data.Data.Type() == component.ComponentButton { - m["custom_id"] = data.Data.AsButton().CustomId - } else if data.Data.Type() == component.ComponentSelectMenu { - m["custom_id"] = data.Data.AsSelectMenu().CustomId - } - */ - return InteractionErrorContext{ data: m, } diff --git a/event/eventexecutor.go b/event/eventexecutor.go index b92f3b3a..bf92f514 100644 --- a/event/eventexecutor.go +++ b/event/eventexecutor.go @@ -2,7 +2,6 @@ package event import ( "context" - "errors" "fmt" "github.com/TicketsBot-cloud/gdl/gateway/payloads" @@ -15,7 +14,7 @@ import ( func execute(c *worker.Context, event []byte) error { var payload payloads.Payload if err := json.Unmarshal(event, &payload); err != nil { - return errors.New(fmt.Sprintf("error whilst decoding event data: %s (data: %s)", err.Error(), string(event))) + return fmt.Errorf("error whilst decoding event data: %s (data: %s)", err.Error(), string(event)) } span := sentry.StartTransaction(context.Background(), "Handle Event") diff --git a/event/httplisten.go b/event/httplisten.go index 1db5de7f..a3263fc1 100644 --- a/event/httplisten.go +++ b/event/httplisten.go @@ -60,7 +60,7 @@ func HttpListen(redis *redis.Client, cache *cache.PgCache) { // Routes router.POST("/event", eventHandler(cache)) - router.POST("/interaction", interactionHandler(redis, cache)) + router.POST("/interaction", interactionHandler(cache)) if err := router.Run(config.Conf.Bot.HttpAddress); err != nil { panic(err) @@ -99,7 +99,7 @@ func eventHandler(cache *cache.PgCache) func(*gin.Context) { } } -func interactionHandler(redis *redis.Client, cache *cache.PgCache) func(*gin.Context) { +func interactionHandler(cache *cache.PgCache) func(*gin.Context) { commandManager := new(cmd_manager.CommandManager) commandManager.RegisterCommands() commandManager.RunSetupFuncs() @@ -249,7 +249,7 @@ func interactionHandler(redis *redis.Client, cache *cache.PgCache) func(*gin.Con var handler command.AutoCompleteHandler for _, arg := range cmd.Properties().Arguments { - if strings.ToLower(arg.Name) == strings.ToLower(focused.Name) { + if strings.EqualFold(arg.Name, focused.Name) { handler = arg.AutoCompleteHandler } } @@ -302,7 +302,7 @@ func handleApplicationCommandResponseAfterDefer(interactionData interaction.Appl return } - if time.Now().Sub(utils.SnowflakeToTime(interactionData.Id)) > time.Minute*14 || + if time.Since(utils.SnowflakeToTime(interactionData.Id)) > time.Minute*14 || deferredAt.Sub(utils.SnowflakeToTime(interactionData.Id)) > config.Conf.Discord.DeferHardTimeout { return } @@ -365,7 +365,7 @@ func handleButtonResponseAfterDefer(interactionData interaction.InteractionMetad return } - if time.Now().Sub(utils.SnowflakeToTime(interactionData.Id)) > time.Minute*14 || + if time.Since(utils.SnowflakeToTime(interactionData.Id)) > time.Minute*14 || deferredAt.Sub(utils.SnowflakeToTime(interactionData.Id)) > config.Conf.Discord.DeferHardTimeout { return } @@ -396,12 +396,12 @@ func findFocusedOption(options []interaction.ApplicationCommandInteractionDataOp func calculateTimeToReceive(interactionId uint64) time.Duration { generated := utils.SnowflakeToTime(interactionId) - return time.Now().Sub(generated) + return time.Since(generated) } func calculateTimeToDefer(interactionId uint64) time.Duration { generated := utils.SnowflakeToTime(interactionId) // Call max incase the snowflake timestamp is off - return max(generated.Add(config.Conf.Discord.CallbackTimeout).Sub(time.Now()), config.Conf.Discord.CallbackTimeout) + return max(time.Until(generated.Add(config.Conf.Discord.CallbackTimeout)), config.Conf.Discord.CallbackTimeout) } diff --git a/go.mod b/go.mod index 4afdfd2d..7cdb8f68 100644 --- a/go.mod +++ b/go.mod @@ -6,11 +6,11 @@ go 1.25.0 //replace github.com/TicketsBot-cloud/common => ../common -//replace github.com/TicketsBot-cloud/gdl => ../gdl +replace github.com/TicketsBot-cloud/gdl => ../gdl //replace github.com/TicketsBot-cloud/archiverclient => ../archiverclient -//replace github.com/TicketsBot-cloud/logarchiver => ../logarchiver +replace github.com/TicketsBot-cloud/logarchiver => ../logarchiver require ( cloud.google.com/go/profiler v0.4.2 diff --git a/restwrapper.go b/restwrapper.go index a8118a6d..ddb583fa 100644 --- a/restwrapper.go +++ b/restwrapper.go @@ -6,15 +6,22 @@ import ( "github.com/TicketsBot-cloud/gdl/cache" "github.com/TicketsBot-cloud/gdl/objects/auditlog" + "github.com/TicketsBot-cloud/gdl/objects/automoderation" "github.com/TicketsBot-cloud/gdl/objects/channel" "github.com/TicketsBot-cloud/gdl/objects/channel/embed" "github.com/TicketsBot-cloud/gdl/objects/channel/message" "github.com/TicketsBot-cloud/gdl/objects/guild" "github.com/TicketsBot-cloud/gdl/objects/guild/emoji" + "github.com/TicketsBot-cloud/gdl/objects/guild/scheduledevent" + "github.com/TicketsBot-cloud/gdl/objects/guild/soundboard" + "github.com/TicketsBot-cloud/gdl/objects/guild/stage" + "github.com/TicketsBot-cloud/gdl/objects/guild/sticker" "github.com/TicketsBot-cloud/gdl/objects/integration" "github.com/TicketsBot-cloud/gdl/objects/interaction" "github.com/TicketsBot-cloud/gdl/objects/invite" "github.com/TicketsBot-cloud/gdl/objects/member" + "github.com/TicketsBot-cloud/gdl/objects/sku" + "github.com/TicketsBot-cloud/gdl/objects/subscription" "github.com/TicketsBot-cloud/gdl/objects/user" "github.com/TicketsBot-cloud/gdl/rest" ) @@ -180,7 +187,7 @@ func (ctx *Context) GetThreadMember(channelId, userId uint64) (channel.ThreadMem } func (ctx *Context) ListThreadMembers(channelId uint64) ([]channel.ThreadMember, error) { - return rest.ListThreadMembers(context.Background(), ctx.Token, ctx.RateLimiter, channelId) + return rest.ListThreadMembers(context.Background(), ctx.Token, ctx.RateLimiter, channelId, rest.ListThreadMembersData{}) } func (ctx *Context) ListActiveThreads(channelId uint64) (rest.ThreadsResponse, error) { @@ -211,7 +218,7 @@ func (ctx *Context) CreatePublicThread(channelId uint64, name string, autoArchiv data := rest.StartThreadWithoutMessageData{ Name: name, AutoArchiveDuration: autoArchiveDuration, - Type: channel.ChannelTypeGuildPublicThread, + Type: channel.ChannelTypePublicThread, } return rest.StartThreadWithoutMessage(context.Background(), ctx.Token, ctx.RateLimiter, channelId, data) @@ -221,7 +228,7 @@ func (ctx *Context) CreatePrivateThread(requestCtx context.Context, channelId ui data := rest.StartThreadWithoutMessageData{ Name: name, AutoArchiveDuration: autoArchiveDuration, - Type: channel.ChannelTypeGuildPrivateThread, + Type: channel.ChannelTypePrivateThread, Invitable: invitable, } @@ -461,8 +468,8 @@ func (ctx *Context) GetGuildPruneCount(guildId uint64, days int) (int, error) { } // computePruneCount = whether 'pruned' is returned, discouraged for large guilds -func (ctx *Context) BeginGuildPrune(guildId uint64, days int, computePruneCount bool) error { - return rest.BeginGuildPrune(context.Background(), ctx.Token, ctx.RateLimiter, guildId, days, computePruneCount) +func (ctx *Context) BeginGuildPrune(guildId uint64, data rest.BeginGuildPruneData) error { + return rest.BeginGuildPrune(context.Background(), ctx.Token, ctx.RateLimiter, guildId, data) } func (ctx *Context) GetGuildVoiceRegions(guildId uint64) ([]guild.VoiceRegion, error) { @@ -506,8 +513,8 @@ func (ctx *Context) GetGuildVanityUrl(guildId uint64) (invite.Invite, error) { return rest.GetGuildVanityURL(context.Background(), ctx.Token, ctx.RateLimiter, guildId) } -func (ctx *Context) GetInvite(inviteCode string, withCounts bool) (invite.Invite, error) { - return rest.GetInvite(context.Background(), ctx.Token, ctx.RateLimiter, inviteCode, withCounts) +func (ctx *Context) GetInvite(inviteCode string, withCounts bool, guildScheduledEventId *uint64) (invite.Invite, error) { + return rest.GetInvite(context.Background(), ctx.Token, ctx.RateLimiter, inviteCode, withCounts, guildScheduledEventId) } func (ctx *Context) DeleteInvite(inviteCode string) (invite.Invite, error) { @@ -611,7 +618,7 @@ func (ctx *Context) GetGuildAuditLog(guildId uint64, data rest.GetGuildAuditLogD } func (ctx *Context) GetGlobalCommands(applicationId uint64) ([]interaction.ApplicationCommand, error) { - return rest.GetGlobalCommands(context.Background(), ctx.Token, ctx.RateLimiter, applicationId) + return rest.GetGlobalCommands(context.Background(), ctx.Token, ctx.RateLimiter, applicationId, false) } func (ctx *Context) CreateGlobalCommand(applicationId uint64, data rest.CreateCommandData) (interaction.ApplicationCommand, error) { @@ -627,7 +634,7 @@ func (ctx *Context) DeleteGlobalCommand(applicationId, commandId uint64) error { } func (ctx *Context) GetGuildCommands(applicationId, guildId uint64) ([]interaction.ApplicationCommand, error) { - return rest.GetGuildCommands(context.Background(), ctx.Token, ctx.RateLimiter, applicationId, guildId) + return rest.GetGuildCommands(context.Background(), ctx.Token, ctx.RateLimiter, applicationId, guildId, false) } func (ctx *Context) CreateGuildCommand(applicationId, guildId uint64, data rest.CreateCommandData) (interaction.ApplicationCommand, error) { @@ -657,3 +664,179 @@ func (ctx *Context) EditCommandPermissions(applicationId, guildId, commandId uin func (ctx *Context) EditBulkCommandPermissions(applicationId, guildId uint64, data []rest.CommandWithPermissionsData) ([]rest.CommandWithPermissionsData, error) { return rest.EditBulkCommandPermissions(context.Background(), ctx.Token, ctx.RateLimiter, applicationId, guildId, data) } + +func (ctx *Context) ModifyGlobalCommands(applicationId uint64, data []rest.CreateCommandData) ([]interaction.ApplicationCommand, error) { + return rest.ModifyGlobalCommands(context.Background(), ctx.Token, ctx.RateLimiter, applicationId, data) +} + +func (ctx *Context) ModifyGuildCommands(applicationId, guildId uint64, data []rest.CreateCommandData) ([]interaction.ApplicationCommand, error) { + return rest.ModifyGuildCommands(context.Background(), ctx.Token, ctx.RateLimiter, applicationId, guildId, data) +} + +func (ctx *Context) EditWebhookMessage(webhookId uint64, webhookToken string, messageId uint64, data rest.WebhookEditBody) (message.Message, error) { + return rest.EditWebhookMessage(context.Background(), webhookToken, ctx.RateLimiter, webhookId, messageId, data) +} + +func (ctx *Context) AddGuildMember(guildId, userId uint64, data rest.AddGuildMemberData) (*member.Member, error) { + return rest.AddGuildMember(context.Background(), ctx.Token, ctx.RateLimiter, guildId, userId, data) +} + +func (ctx *Context) GetGuildWelcomeScreen(guildId uint64) (guild.WelcomeScreen, error) { + return rest.GetGuildWelcomeScreen(context.Background(), ctx.Token, ctx.RateLimiter, guildId) +} + +func (ctx *Context) ModifyGuildWelcomeScreen(guildId uint64, data rest.ModifyGuildWelcomeScreenData) (guild.WelcomeScreen, error) { + return rest.ModifyGuildWelcomeScreen(context.Background(), ctx.Token, ctx.RateLimiter, guildId, data) +} + +// Auto-moderation + +func (ctx *Context) ListAutoModerationRules(guildId uint64) ([]automoderation.Rule, error) { + return rest.ListAutoModerationRules(context.Background(), ctx.Token, ctx.RateLimiter, guildId) +} + +func (ctx *Context) GetAutoModerationRule(guildId, ruleId uint64) (automoderation.Rule, error) { + return rest.GetAutoModerationRule(context.Background(), ctx.Token, ctx.RateLimiter, guildId, ruleId) +} + +func (ctx *Context) CreateAutoModerationRule(guildId uint64, data rest.CreateAutoModerationRuleData) (automoderation.Rule, error) { + return rest.CreateAutoModerationRule(context.Background(), ctx.Token, ctx.RateLimiter, guildId, data) +} + +func (ctx *Context) ModifyAutoModerationRule(guildId, ruleId uint64, data rest.ModifyAutoModerationRuleData) (automoderation.Rule, error) { + return rest.ModifyAutoModerationRule(context.Background(), ctx.Token, ctx.RateLimiter, guildId, ruleId, data) +} + +func (ctx *Context) DeleteAutoModerationRule(guildId, ruleId uint64) error { + return rest.DeleteAutoModerationRule(context.Background(), ctx.Token, ctx.RateLimiter, guildId, ruleId) +} + +// Scheduled events + +func (ctx *Context) ListGuildScheduledEvents(guildId uint64, withUserCount bool) ([]scheduledevent.GuildScheduledEvent, error) { + return rest.ListGuildScheduledEvents(context.Background(), ctx.Token, ctx.RateLimiter, guildId, withUserCount) +} + +func (ctx *Context) GetGuildScheduledEvent(guildId, eventId uint64, withUserCount bool) (scheduledevent.GuildScheduledEvent, error) { + return rest.GetGuildScheduledEvent(context.Background(), ctx.Token, ctx.RateLimiter, guildId, eventId, withUserCount) +} + +func (ctx *Context) CreateGuildScheduledEvent(guildId uint64, data rest.CreateGuildScheduledEventData) (scheduledevent.GuildScheduledEvent, error) { + return rest.CreateGuildScheduledEvent(context.Background(), ctx.Token, ctx.RateLimiter, guildId, data) +} + +func (ctx *Context) ModifyGuildScheduledEvent(guildId, eventId uint64, data rest.ModifyGuildScheduledEventData) (scheduledevent.GuildScheduledEvent, error) { + return rest.ModifyGuildScheduledEvent(context.Background(), ctx.Token, ctx.RateLimiter, guildId, eventId, data) +} + +func (ctx *Context) DeleteGuildScheduledEvent(guildId, eventId uint64) error { + return rest.DeleteGuildScheduledEvent(context.Background(), ctx.Token, ctx.RateLimiter, guildId, eventId) +} + +func (ctx *Context) GetGuildScheduledEventUsers(guildId, eventId uint64, data rest.GetGuildScheduledEventUsersData) ([]rest.GuildScheduledEventUser, error) { + return rest.GetGuildScheduledEventUsers(context.Background(), ctx.Token, ctx.RateLimiter, guildId, eventId, data) +} + +// Stage instances + +func (ctx *Context) CreateStageInstance(data rest.CreateStageInstanceData) (stage.StageInstance, error) { + return rest.CreateStageInstance(context.Background(), ctx.Token, ctx.RateLimiter, data) +} + +func (ctx *Context) GetStageInstance(channelId uint64) (stage.StageInstance, error) { + return rest.GetStageInstance(context.Background(), ctx.Token, ctx.RateLimiter, channelId) +} + +func (ctx *Context) ModifyStageInstance(channelId uint64, data rest.ModifyStageInstanceData) (stage.StageInstance, error) { + return rest.ModifyStageInstance(context.Background(), ctx.Token, ctx.RateLimiter, channelId, data) +} + +func (ctx *Context) DeleteStageInstance(channelId uint64) error { + return rest.DeleteStageInstance(context.Background(), ctx.Token, ctx.RateLimiter, channelId) +} + +// Soundboard + +func (ctx *Context) SendSoundboardSound(channelId uint64, data rest.SendSoundboardSoundData) error { + return rest.SendSoundboardSound(context.Background(), ctx.Token, ctx.RateLimiter, channelId, data) +} + +func (ctx *Context) GetDefaultSoundboardSounds() ([]soundboard.SoundboardSound, error) { + return rest.GetDefaultSoundboardSounds(context.Background(), ctx.Token, ctx.RateLimiter) +} + +func (ctx *Context) ListGuildSoundboardSounds(guildId uint64) ([]soundboard.SoundboardSound, error) { + return rest.ListGuildSoundboardSounds(context.Background(), ctx.Token, ctx.RateLimiter, guildId) +} + +func (ctx *Context) GetGuildSoundboardSound(guildId, soundId uint64) (soundboard.SoundboardSound, error) { + return rest.GetGuildSoundboardSound(context.Background(), ctx.Token, ctx.RateLimiter, guildId, soundId) +} + +func (ctx *Context) CreateGuildSoundboardSound(guildId uint64, data rest.CreateGuildSoundboardSoundData) (soundboard.SoundboardSound, error) { + return rest.CreateGuildSoundboardSound(context.Background(), ctx.Token, ctx.RateLimiter, guildId, data) +} + +func (ctx *Context) ModifyGuildSoundboardSound(guildId, soundId uint64, data rest.ModifyGuildSoundboardSoundData) (soundboard.SoundboardSound, error) { + return rest.ModifyGuildSoundboardSound(context.Background(), ctx.Token, ctx.RateLimiter, guildId, soundId, data) +} + +func (ctx *Context) DeleteGuildSoundboardSound(guildId, soundId uint64) error { + return rest.DeleteGuildSoundboardSound(context.Background(), ctx.Token, ctx.RateLimiter, guildId, soundId) +} + +// Poll + +func (ctx *Context) GetPollAnswerVoters(channelId, messageId uint64, answerId int, data rest.GetPollAnswerVotersData) ([]user.User, error) { + return rest.GetPollAnswerVoters(context.Background(), ctx.Token, ctx.RateLimiter, channelId, messageId, answerId, data) +} + +func (ctx *Context) EndPoll(channelId, messageId uint64) (message.Message, error) { + return rest.EndPoll(context.Background(), ctx.Token, ctx.RateLimiter, channelId, messageId) +} + +// SKU + +func (ctx *Context) ListSKUs(applicationId uint64) ([]sku.SKU, error) { + return rest.ListSKUs(context.Background(), ctx.Token, ctx.RateLimiter, applicationId) +} + +// Subscriptions + +func (ctx *Context) ListSKUSubscriptions(skuId uint64, data rest.ListSKUSubscriptionsData) ([]subscription.Subscription, error) { + return rest.ListSKUSubscriptions(context.Background(), ctx.Token, ctx.RateLimiter, skuId, data) +} + +func (ctx *Context) GetSKUSubscription(skuId, subscriptionId uint64) (subscription.Subscription, error) { + return rest.GetSKUSubscription(context.Background(), ctx.Token, ctx.RateLimiter, skuId, subscriptionId) +} + +// Stickers + +func (ctx *Context) GetSticker(stickerId uint64) (sticker.Sticker, error) { + return rest.GetSticker(context.Background(), ctx.Token, ctx.RateLimiter, stickerId) +} + +func (ctx *Context) GetStickerPacks() ([]rest.StickerPack, error) { + return rest.GetStickerPacks(context.Background(), ctx.Token, ctx.RateLimiter) +} + +func (ctx *Context) GetStickerPack(packId uint64) (rest.StickerPack, error) { + return rest.GetStickerPack(context.Background(), ctx.Token, ctx.RateLimiter, packId) +} + +func (ctx *Context) ListGuildStickers(guildId uint64) ([]sticker.Sticker, error) { + return rest.ListGuildStickers(context.Background(), ctx.Token, ctx.RateLimiter, guildId) +} + +func (ctx *Context) GetGuildSticker(guildId, stickerId uint64) (sticker.Sticker, error) { + return rest.GetGuildSticker(context.Background(), ctx.Token, ctx.RateLimiter, guildId, stickerId) +} + +func (ctx *Context) ModifyGuildSticker(guildId, stickerId uint64, data rest.ModifyGuildStickerData) (sticker.Sticker, error) { + return rest.ModifyGuildSticker(context.Background(), ctx.Token, ctx.RateLimiter, guildId, stickerId, data) +} + +func (ctx *Context) DeleteGuildSticker(guildId, stickerId uint64) error { + return rest.DeleteGuildSticker(context.Background(), ctx.Token, ctx.RateLimiter, guildId, stickerId) +} diff --git a/tools/cmd/cmdcaller.tmpl b/tools/cmd/cmdcaller/cmdcaller.tmpl similarity index 93% rename from tools/cmd/cmdcaller.tmpl rename to tools/cmd/cmdcaller/cmdcaller.tmpl index 88c35e54..0b7bdf99 100644 --- a/tools/cmd/cmdcaller.tmpl +++ b/tools/cmd/cmdcaller/cmdcaller.tmpl @@ -1,143 +1,143 @@ -// Code generated by /tools/cmd/generatecmdcaller.go; DO NOT EDIT. -//go:generate go run ../tools/cmd/generatecmdcaller.go - -package event - -import ( - "fmt" - "github.com/TicketsBot-cloud/worker/bot/command" - cmdcontext "github.com/TicketsBot-cloud/worker/bot/command/context" - {{- range .imports}} - "{{.}}" - {{- end}} - "github.com/TicketsBot-cloud/worker/bot/command/registry" - "github.com/pkg/errors" - "github.com/TicketsBot-cloud/gdl/objects/interaction" - "strconv" -) - -var ErrArgumentNotFound = errors.New("argument not found") - -func callCommand( - cmd registry.Command, - ctx *cmdcontext.SlashCommandContext, - options []interaction.ApplicationCommandInteractionDataOption, -) error { - switch v := cmd.(type) { - {{range .executors}} - case {{.ImportName}}: - {{- range $i, $arg := .Arguments}} - {{- if $arg.Required}} - var arg{{$i}} {{index $.typeMap $arg.Type}} - {{- else}} - var arg{{$i}} *{{index $.typeMap $arg.Type}} - {{- end}} - - opt{{$i}}, ok{{$i}} := findOption(cmd.Properties().Arguments[{{$i}}], options) - if !ok{{$i}} { - {{- if $arg.Required}} - return ErrArgumentNotFound - {{- else}} - arg{{$i}} = nil - {{- end}} - } else { - {{- if eq $arg.Type 3 }} {{/* string */}} - argValue, ok := opt{{$i}}.Value.(string) - if !ok { - return fmt.Errorf("option %s was not a string", opt{{$i}}.Name) - } - - {{- if $arg.Required}} - arg{{$i}} = argValue - {{- else}} - arg{{$i}} = &argValue - {{- end}} - - {{- else if eq $arg.Type 4 }} {{/* integer */}} - argValue, ok := opt{{$i}}.Value.(float64) - if !ok { - return fmt.Errorf("option %s was not a float64", opt{{$i}}.Name) - } - - {{- if $arg.Required}} - arg{{$i}} = int(argValue) - {{- else}} - tmp := int(argValue) - arg{{$i}} = &tmp - {{- end}} - - {{- else if eq $arg.Type 5 }} {{/* boolean */}} - argValue, ok := opt{{$i}}.Value.(bool) - if !ok { - return fmt.Errorf("option %s was not a bool", opt{{$i}}.Name) - } - - {{- if $arg.Required}} - arg{{$i}} = argValue - {{- else}} - arg{{$i}} = &argValue - {{- end}} - - {{/* user, channel, role, mentionable */}} - {{- else if or (eq $arg.Type 6) (eq $arg.Type 7) (eq $arg.Type 8) (eq $arg.Type 9) }} - raw, ok := opt{{$i}}.Value.(string) - if !ok { - return fmt.Errorf("option %s was not a snowflake", opt{{$i}}.Name) - } - - argValue, err := strconv.ParseUint(raw, 10, 64) - if err != nil { - return fmt.Errorf("option %s was not a valid snowflake", opt{{$i}}.Name) - } - - {{- if $arg.Required}} - arg{{$i}} = argValue - {{- else}} - arg{{$i}} = &argValue - {{- end}} - - {{- else if eq $arg.Type 10 }} {{/* number */}} - argValue, ok := opt{{$i}}.Value.(float64) - if !ok { - return fmt.Errorf("option %s was not a float64", opt{{$i}}.Name) - } - - {{- if $arg.Required}} - arg{{$i}} = argValue - {{- else}} - arg{{$i}} = &argValue - {{- end}} - - {{- else }} - {{panic "unsupported command option type"}} - - {{- end}} - } - {{- end}} - - v.Execute(ctx{{range $i, $arg := .Arguments}}, arg{{$i}}{{end}}) - {{- end}} - - {{/* special case */}} - case tags.TagAliasCommand: - v.Execute(ctx) - - default: - return fmt.Errorf("unknown command %s", cmd.Properties().Name) - } - - return nil -} - -func findOption( - arg command.Argument, - options []interaction.ApplicationCommandInteractionDataOption, -) (interaction.ApplicationCommandInteractionDataOption, bool) { - for _, option := range options { - if option.Name == arg.Name { - return option, true - } - } - - return interaction.ApplicationCommandInteractionDataOption{}, false -} +// Code generated by /tools/cmd/cmdcaller/main.go; DO NOT EDIT. +//go:generate go run ../tools/cmd/cmdcaller + +package event + +import ( + "fmt" + "github.com/TicketsBot-cloud/worker/bot/command" + cmdcontext "github.com/TicketsBot-cloud/worker/bot/command/context" + {{- range .imports}} + "{{.}}" + {{- end}} + "github.com/TicketsBot-cloud/worker/bot/command/registry" + "github.com/pkg/errors" + "github.com/TicketsBot-cloud/gdl/objects/interaction" + "strconv" +) + +var ErrArgumentNotFound = errors.New("argument not found") + +func callCommand( + cmd registry.Command, + ctx *cmdcontext.SlashCommandContext, + options []interaction.ApplicationCommandInteractionDataOption, +) error { + switch v := cmd.(type) { + {{range .executors}} + case {{.ImportName}}: + {{- range $i, $arg := .Arguments}} + {{- if $arg.Required}} + var arg{{$i}} {{index $.typeMap $arg.Type}} + {{- else}} + var arg{{$i}} *{{index $.typeMap $arg.Type}} + {{- end}} + + opt{{$i}}, ok{{$i}} := findOption(cmd.Properties().Arguments[{{$i}}], options) + if !ok{{$i}} { + {{- if $arg.Required}} + return ErrArgumentNotFound + {{- else}} + arg{{$i}} = nil + {{- end}} + } else { + {{- if eq $arg.Type 3 }} {{/* string */}} + argValue, ok := opt{{$i}}.Value.(string) + if !ok { + return fmt.Errorf("option %s was not a string", opt{{$i}}.Name) + } + + {{- if $arg.Required}} + arg{{$i}} = argValue + {{- else}} + arg{{$i}} = &argValue + {{- end}} + + {{- else if eq $arg.Type 4 }} {{/* integer */}} + argValue, ok := opt{{$i}}.Value.(float64) + if !ok { + return fmt.Errorf("option %s was not a float64", opt{{$i}}.Name) + } + + {{- if $arg.Required}} + arg{{$i}} = int(argValue) + {{- else}} + tmp := int(argValue) + arg{{$i}} = &tmp + {{- end}} + + {{- else if eq $arg.Type 5 }} {{/* boolean */}} + argValue, ok := opt{{$i}}.Value.(bool) + if !ok { + return fmt.Errorf("option %s was not a bool", opt{{$i}}.Name) + } + + {{- if $arg.Required}} + arg{{$i}} = argValue + {{- else}} + arg{{$i}} = &argValue + {{- end}} + + {{/* user, channel, role, mentionable */}} + {{- else if or (eq $arg.Type 6) (eq $arg.Type 7) (eq $arg.Type 8) (eq $arg.Type 9) }} + raw, ok := opt{{$i}}.Value.(string) + if !ok { + return fmt.Errorf("option %s was not a snowflake", opt{{$i}}.Name) + } + + argValue, err := strconv.ParseUint(raw, 10, 64) + if err != nil { + return fmt.Errorf("option %s was not a valid snowflake", opt{{$i}}.Name) + } + + {{- if $arg.Required}} + arg{{$i}} = argValue + {{- else}} + arg{{$i}} = &argValue + {{- end}} + + {{- else if eq $arg.Type 10 }} {{/* number */}} + argValue, ok := opt{{$i}}.Value.(float64) + if !ok { + return fmt.Errorf("option %s was not a float64", opt{{$i}}.Name) + } + + {{- if $arg.Required}} + arg{{$i}} = argValue + {{- else}} + arg{{$i}} = &argValue + {{- end}} + + {{- else }} + {{panic "unsupported command option type"}} + + {{- end}} + } + {{- end}} + + v.Execute(ctx{{range $i, $arg := .Arguments}}, arg{{$i}}{{end}}) + {{- end}} + + {{/* special case */}} + case tags.TagAliasCommand: + v.Execute(ctx) + + default: + return fmt.Errorf("unknown command %s", cmd.Properties().Name) + } + + return nil +} + +func findOption( + arg command.Argument, + options []interaction.ApplicationCommandInteractionDataOption, +) (interaction.ApplicationCommandInteractionDataOption, bool) { + for _, option := range options { + if option.Name == arg.Name { + return option, true + } + } + + return interaction.ApplicationCommandInteractionDataOption{}, false +} \ No newline at end of file diff --git a/tools/cmd/generatecmdcaller.go b/tools/cmd/cmdcaller/main.go similarity index 69% rename from tools/cmd/generatecmdcaller.go rename to tools/cmd/cmdcaller/main.go index c4226082..a219b17e 100644 --- a/tools/cmd/generatecmdcaller.go +++ b/tools/cmd/cmdcaller/main.go @@ -27,15 +27,15 @@ type executorData struct { var callerTemplate string var typeMap = map[interaction.ApplicationCommandOptionType]reflect.Type{ - interaction.OptionTypeString: reflect.TypeOf(""), // string - interaction.OptionTypeInteger: reflect.TypeOf(int(0)), // int - interaction.OptionTypeBoolean: reflect.TypeOf(false), // bool - interaction.OptionTypeUser: reflect.TypeOf(uint64(0)), // snowflake - interaction.OptionTypeChannel: reflect.TypeOf(uint64(0)), // snowflake - interaction.OptionTypeRole: reflect.TypeOf(uint64(0)), // snowflake - interaction.OptionTypeMentionable: reflect.TypeOf(uint64(0)), // snowflake - interaction.OptionTypeNumber: reflect.TypeOf(float64(0)), // float64 - interaction.OptionTypeAttachment: reflect.TypeOf(channel.Attachment{}), // attachment + interaction.ApplicationCommandOptionTypeString: reflect.TypeOf(""), // string + interaction.ApplicationCommandOptionTypeInteger: reflect.TypeOf(int(0)), // int + interaction.ApplicationCommandOptionTypeBoolean: reflect.TypeOf(false), // bool + interaction.ApplicationCommandOptionTypeUser: reflect.TypeOf(uint64(0)), // snowflake + interaction.ApplicationCommandOptionTypeChannel: reflect.TypeOf(uint64(0)), // snowflake + interaction.ApplicationCommandOptionTypeRole: reflect.TypeOf(uint64(0)), // snowflake + interaction.ApplicationCommandOptionTypeMentionable: reflect.TypeOf(uint64(0)), // snowflake + interaction.ApplicationCommandOptionTypeNumber: reflect.TypeOf(float64(0)), // float64 + interaction.ApplicationCommandOptionTypeAttachment: reflect.TypeOf(channel.Attachment{}), // attachment } func main() { diff --git a/tools/cmd/listeners.tmpl b/tools/cmd/listeners/listeners.tmpl similarity index 89% rename from tools/cmd/listeners.tmpl rename to tools/cmd/listeners/listeners.tmpl index 9f9f04df..3d08fc90 100644 --- a/tools/cmd/listeners.tmpl +++ b/tools/cmd/listeners/listeners.tmpl @@ -1,5 +1,5 @@ -// Code generated by /tools/cmd/generatelisteners.go; DO NOT EDIT. -//go:generate go run ../../tools/cmd/generatelisteners.go +// Code generated by /tools/cmd/listeners/main.go; DO NOT EDIT. +//go:generate go run ../../tools/cmd/listeners package listeners @@ -39,4 +39,4 @@ func HandleEvent(c *worker.Context, span *sentry.Span, payload payloads.Payload) } return nil -} +} \ No newline at end of file diff --git a/tools/cmd/generatelisteners.go b/tools/cmd/listeners/main.go similarity index 93% rename from tools/cmd/generatelisteners.go rename to tools/cmd/listeners/main.go index bb47555f..73f7d4e7 100644 --- a/tools/cmd/generatelisteners.go +++ b/tools/cmd/listeners/main.go @@ -10,7 +10,6 @@ import ( "strings" "unicode" - _ "github.com/TicketsBot-cloud/gdl/gateway/payloads/events" "golang.org/x/tools/go/packages" ) @@ -45,10 +44,6 @@ func main() { typeName := strings.TrimPrefix(object.Type().String(), PackageName+".") if typeName == object.Name() { - if typeName == "EventBus" { - continue - } - // Check if underlying type is a struct underlying := object.Type().Underlying() if _, ok := underlying.(*types.Struct); ok {