Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions bot/logic/open.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func OpenTicket(ctx context.Context, cmd registry.InteractionContext, panel *dat

// Make sure ticket count is within ticket limit
// Check ticket limit before ratelimit token to prevent 1 person from stopping everyone opening tickets
violatesTicketLimit, limit := getTicketLimit(ctx, cmd)
violatesTicketLimit, limit := getTicketLimit(ctx, cmd, panel)
if violatesTicketLimit {
// Notify the user
ticketsPluralised := "ticket"
Expand Down Expand Up @@ -794,7 +794,7 @@ func refreshCachedChannels(ctx context.Context, worker *worker.Context, guildId
}

// has hit ticket limit, ticket limit
func getTicketLimit(ctx context.Context, cmd registry.CommandContext) (bool, int) {
func getTicketLimit(ctx context.Context, cmd registry.CommandContext, panel *database.Panel) (bool, int) {
isStaff, err := cmd.UserPermissionLevel(ctx)
if err != nil {
sentry.ErrorWithContext(err, cmd.ToErrorContext())
Expand All @@ -805,28 +805,39 @@ func getTicketLimit(ctx context.Context, cmd registry.CommandContext) (bool, int
return false, 50
}

var openedTickets []database.Ticket
var openTicketCount int
var ticketLimit uint8

group, _ := errgroup.WithContext(ctx)

// get ticket limit
group.Go(func() (err error) {
ticketLimit, err = dbclient.Client.TicketLimit.Get(ctx, cmd.GuildId())
return
})
// If panel has a per-panel limit, use it and count only panel tickets
if panel != nil && panel.TicketLimit != nil {
ticketLimit = *panel.TicketLimit

group.Go(func() (err error) {
openedTickets, err = dbclient.Client.Tickets.GetOpenByUser(ctx, cmd.GuildId(), cmd.UserId())
return
})
group.Go(func() (err error) {
openTicketCount, err = dbclient.Client.Tickets.GetOpenCountByUserAndPanel(
ctx, cmd.GuildId(), cmd.UserId(), panel.PanelId)
return
})
} else {
// Use global limit and count all tickets
group.Go(func() (err error) {
ticketLimit, err = dbclient.Client.TicketLimit.Get(ctx, cmd.GuildId())
return
})

group.Go(func() (err error) {
openTicketCount, err = dbclient.Client.Tickets.GetOpenCountByUser(ctx, cmd.GuildId(), cmd.UserId())
return
})
}

if err := group.Wait(); err != nil {
sentry.ErrorWithContext(err, cmd.ToErrorContext())
return true, 1
}

return len(openedTickets) >= int(ticketLimit), int(ticketLimit)
return openTicketCount >= int(ticketLimit), int(ticketLimit)
}

func createWebhook(ctx context.Context, c registry.CommandContext, ticketId int, guildId, channelId uint64) error {
Expand Down
70 changes: 49 additions & 21 deletions bot/logic/reopen.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,23 @@ import (
"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/database"
"github.com/TicketsBot-cloud/worker/i18n"
)

func ReopenTicket(ctx context.Context, cmd registry.CommandContext, ticketId int) {
// Get the ticket first so we can check per-panel limits
ticket, err := dbclient.Client.Tickets.Get(ctx, ticketId, cmd.GuildId())
if err != nil {
cmd.HandleError(err)
return
}

if ticket.Id == 0 || ticket.GuildId != cmd.GuildId() {
cmd.Reply(customisation.Red, i18n.Error, i18n.MessageReopenTicketNotFound)
return
}

// Check ticket limit
permLevel, err := cmd.UserPermissionLevel(ctx)
if err != nil {
Expand All @@ -22,36 +35,51 @@ func ReopenTicket(ctx context.Context, cmd registry.CommandContext, ticketId int
}

if permLevel == permission.Everyone {
ticketLimit, err := dbclient.Client.TicketLimit.Get(ctx, cmd.GuildId())
if err != nil {
cmd.HandleError(err)
return
// Fetch panel if ticket has one for per-panel limit check
var panel *database.Panel
if ticket.PanelId != nil {
p, err := dbclient.Client.Panel.GetById(ctx, *ticket.PanelId)
if err != nil {
cmd.HandleError(err)
return
}
if p.PanelId != 0 {
panel = &p
}
}

// TODO: count()
openTickets, err := dbclient.Client.Tickets.GetOpenByUser(ctx, cmd.GuildId(), cmd.UserId())
if err != nil {
cmd.HandleError(err)
return
var ticketLimit uint8
var openTicketCount int

if panel != nil && panel.TicketLimit != nil {
// Use per-panel limit and count only panel tickets
ticketLimit = *panel.TicketLimit
openTicketCount, err = dbclient.Client.Tickets.GetOpenCountByUserAndPanel(ctx, cmd.GuildId(), cmd.UserId(), panel.PanelId)
if err != nil {
cmd.HandleError(err)
return
}
} else {
// Use global limit and count all tickets
ticketLimit, err = dbclient.Client.TicketLimit.Get(ctx, cmd.GuildId())
if err != nil {
cmd.HandleError(err)
return
}

openTicketCount, err = dbclient.Client.Tickets.GetOpenCountByUser(ctx, cmd.GuildId(), cmd.UserId())
if err != nil {
cmd.HandleError(err)
return
}
}

if len(openTickets) >= int(ticketLimit) {
if openTicketCount >= int(ticketLimit) {
cmd.Reply(customisation.Green, i18n.Error, i18n.MessageTicketLimitReached)
return
}
}

ticket, err := dbclient.Client.Tickets.Get(ctx, ticketId, cmd.GuildId())
if err != nil {
cmd.HandleError(err)
return
}

if ticket.Id == 0 || ticket.GuildId != cmd.GuildId() {
cmd.Reply(customisation.Red, i18n.Error, i18n.MessageReopenTicketNotFound)
return
}

// Ensure user has permissino to reopen the ticket
hasPermission, err := HasPermissionForTicket(ctx, cmd.Worker(), ticket, cmd.UserId())
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/TicketsBot-cloud/analytics-client v0.0.0-20250604180646-6606dfc8fc8c
github.com/TicketsBot-cloud/archiverclient v0.0.0-20251015181023-f0b66a074704
github.com/TicketsBot-cloud/common v0.0.0-20260210203202-54154661338e
github.com/TicketsBot-cloud/database v0.0.0-20260215113825-54c67fb267fc
github.com/TicketsBot-cloud/database v0.0.0-20260217113520-9cc86e3b374b
github.com/TicketsBot-cloud/gdl v0.0.0-20260213180045-11af01c262ca
github.com/caarlos0/env/v10 v10.0.0
github.com/elliotchance/orderedmap v1.8.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ github.com/TicketsBot-cloud/archiverclient v0.0.0-20251015181023-f0b66a074704 h1
github.com/TicketsBot-cloud/archiverclient v0.0.0-20251015181023-f0b66a074704/go.mod h1:Mux1bEPpOHwRw1wo6Fa6qJLJH9Erk9qv1yAIfLi1Wmw=
github.com/TicketsBot-cloud/common v0.0.0-20260210203202-54154661338e h1:nFKV7yEm8MWbCP7dtsJ88+agcxDUD0YKIotVHMVvytw=
github.com/TicketsBot-cloud/common v0.0.0-20260210203202-54154661338e/go.mod h1:tGrTHFz09OM3eDWF+62hIi9ELpT4igCFi868FKSvKBg=
github.com/TicketsBot-cloud/database v0.0.0-20260215113825-54c67fb267fc h1:9fQmqYQN7Hc85ds+uklaNU1ab199NAhpT5A3fQ3P8g8=
github.com/TicketsBot-cloud/database v0.0.0-20260215113825-54c67fb267fc/go.mod h1:HQXAgmNSm7/FmBYwcsa6qpZqMrDhbLoEl+AyqFQ+RwY=
github.com/TicketsBot-cloud/database v0.0.0-20260217113520-9cc86e3b374b h1:nE8VAv13rUPOSMTnULKsuCDHXlWnbst7DmocviUN6I8=
github.com/TicketsBot-cloud/database v0.0.0-20260217113520-9cc86e3b374b/go.mod h1:HQXAgmNSm7/FmBYwcsa6qpZqMrDhbLoEl+AyqFQ+RwY=
github.com/TicketsBot-cloud/gdl v0.0.0-20260213180045-11af01c262ca h1:/HRqcgOPfv6d9NzE6CqHXN4U1QgElyJ9DcxNNT8kV6g=
github.com/TicketsBot-cloud/gdl v0.0.0-20260213180045-11af01c262ca/go.mod h1:CdwBR2egPtxUXjD2CgC9ZwfuB8dz9HPePM8nuG6dt7Y=
github.com/TicketsBot-cloud/logarchiver v0.0.0-20251018211319-7a7df5cacbdc h1:qTLNpCvIqM7UwZ6MdWQ9EztcDsIJfHh+VJdG+ULLEaA=
Expand Down