Skip to content

Commit 3e2b1cc

Browse files
committed
add modal for automod timeout, kick, ban
1 parent af04fab commit 3e2b1cc

File tree

5 files changed

+150
-279
lines changed

5 files changed

+150
-279
lines changed

dbot/command.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ type (
1010
CommandHandler func(b *Bot, p *message.Printer, e *events.ApplicationCommandInteractionCreate) error
1111
ComponentHandler func(b *Bot, args []string, p *message.Printer, e *events.ComponentInteractionCreate) error
1212
AutocompleteHandler func(b *Bot, p *message.Printer, e *events.AutocompleteInteractionCreate) error
13+
ModalHandler func(b *Bot, args []string, p *message.Printer, e *events.ModalSubmitInteractionCreate) error
1314
)
1415

1516
type Command struct {
@@ -18,6 +19,7 @@ type Command struct {
1819
CommandHandler map[string]CommandHandler
1920
ComponentHandler map[string]ComponentHandler
2021
AutoCompleteHandler map[string]AutocompleteHandler
22+
ModalHandler map[string]ModalHandler
2123
}
2224

2325
func (b *Bot) LoadCommands(commands ...Command) {

dbot/command_map.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,24 @@ func (m *CommandMap) OnEvent(event bot.Event) {
7474
}
7575
m.bot.Logger.Errorf("No component handler for action \"%s\" on command \"%s\"", action, cmdName)
7676
}
77+
} else if e, ok := event.(*events.ModalSubmitInteractionCreate); ok {
78+
customID := e.Data.CustomID.String()
79+
if !strings.HasPrefix(customID, "cmd:") {
80+
return
81+
}
82+
args := strings.Split(customID, ":")
83+
cmdName, action := args[1], args[2]
84+
if cmd, ok := m.commands[cmdName]; ok {
85+
if cmd.ModalHandler != nil {
86+
if handler, ok := cmd.ModalHandler[action]; ok {
87+
if err := handler(m.bot, args[3:], getMessagePrinter(e.BaseInteraction), e); err != nil {
88+
m.bot.Logger.Errorf("Failed to handle modal interaction for \"%s\" \"%s\" : %s", cmdName, action, err)
89+
}
90+
return
91+
}
92+
}
93+
m.bot.Logger.Errorf("No modal handler for action \"%s\" on command \"%s\"", action, cmdName)
94+
}
7795
}
7896
}
7997

dbot/commands/report.go

Lines changed: 124 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"database/sql"
55
"fmt"
66
"strconv"
7-
"strings"
87
"time"
98

109
"github.com/KittyBot-Org/KittyBotGo/db/.gen/kittybot-go/public/model"
@@ -29,6 +28,9 @@ var Report = dbot.Command{
2928
"confirm": reportConfirmHandler,
3029
"delete": reportDeleteHandler,
3130
},
31+
ModalHandler: map[string]dbot.ModalHandler{
32+
"action-confirm": reportActionConfirmHandler,
33+
},
3234
}
3335

3436
func reportHandler(b *dbot.Bot, p *message.Printer, e *events.ApplicationCommandInteractionCreate) error {
@@ -188,15 +190,8 @@ func reportConfirmHandler(b *dbot.Bot, args []string, p *message.Printer, e *eve
188190
},
189191
},
190192
{
191-
Label: "Timeout User for 1 hour",
192-
Value: "timeout:1",
193-
Emoji: &discord.ComponentEmoji{
194-
Name: "🚫",
195-
},
196-
},
197-
{
198-
Label: "Timeout User for 1 day",
199-
Value: "timeout:24",
193+
Label: "Timeout User",
194+
Value: "timeout",
200195
Emoji: &discord.ComponentEmoji{
201196
Name: "🚫",
202197
},
@@ -278,13 +273,13 @@ func reportActionHandler(b *dbot.Bot, args []string, p *message.Printer, e *even
278273
})
279274
}
280275

281-
reason := rest.WithReason(fmt.Sprintf("automod action by %s caused by report %d", e.User().Tag(), reportID))
276+
reason := fmt.Sprintf("AutoMod action by: %s\nCaused by report #%d", e.User().Tag(), reportID)
282277

283278
var content string
284279
value := e.SelectMenuInteractionData().Values[0]
285280
switch value {
286281
case "delete-message":
287-
if err = b.Client.Rest().DeleteMessage(snowflake.MustParse(report.ChannelID), snowflake.MustParse(report.MessageID), reason); err != nil {
282+
if err = b.Client.Rest().DeleteMessage(snowflake.MustParse(report.ChannelID), snowflake.MustParse(report.MessageID), rest.WithReason(reason)); err != nil {
288283
b.Logger.Errorf("Failed to delete message: %s", err)
289284
content = "Failed to delete message, please reach out to a bot developer."
290285
} else {
@@ -333,42 +328,138 @@ func reportActionHandler(b *dbot.Bot, args []string, p *message.Printer, e *even
333328
content = formatReports(reports, *user)
334329
}
335330

336-
case "timeout:1", "timeout:24":
331+
case "timeout":
332+
return e.CreateModal(discord.ModalCreate{
333+
CustomID: discord.CustomID(fmt.Sprintf("cmd:report:action-confirm:timeout:%s", report.UserID)),
334+
Title: "Timeout User",
335+
Components: []discord.ContainerComponent{
336+
discord.ActionRowComponent{
337+
discord.TextInputComponent{
338+
CustomID: "duration",
339+
Style: discord.TextInputStyleShort,
340+
Label: "Timeout Duration",
341+
MinLength: json.NewPtr(2),
342+
Required: true,
343+
Placeholder: "time units: s, m, h example: 1h3s",
344+
Value: "1h",
345+
},
346+
},
347+
discord.ActionRowComponent{
348+
discord.TextInputComponent{
349+
CustomID: "reason",
350+
Style: discord.TextInputStyleParagraph,
351+
Label: "Timeout Reason",
352+
Required: true,
353+
Placeholder: "The reason for the timeout",
354+
Value: reason,
355+
},
356+
},
357+
},
358+
})
359+
360+
case "kick":
361+
return e.CreateModal(discord.ModalCreate{
362+
CustomID: discord.CustomID(fmt.Sprintf("cmd:report:action-confirm:kick:%s", report.UserID)),
363+
Title: "Kick User",
364+
Components: []discord.ContainerComponent{
365+
discord.ActionRowComponent{
366+
discord.TextInputComponent{
367+
CustomID: "reason",
368+
Style: discord.TextInputStyleParagraph,
369+
Label: "Kick Reason",
370+
Required: true,
371+
Placeholder: "The reason for the kick",
372+
Value: reason,
373+
},
374+
},
375+
},
376+
})
377+
378+
case "ban":
379+
return e.CreateModal(discord.ModalCreate{
380+
CustomID: discord.CustomID(fmt.Sprintf("cmd:report:action-confirm:ban:%s", report.UserID)),
381+
Title: "Ban User",
382+
Components: []discord.ContainerComponent{
383+
discord.ActionRowComponent{
384+
discord.TextInputComponent{
385+
CustomID: "del-days",
386+
Style: discord.TextInputStyleShort,
387+
Label: "Message Delete Days",
388+
MinLength: json.NewPtr(1),
389+
MaxLength: 1,
390+
Required: true,
391+
Placeholder: "0-7",
392+
Value: "0",
393+
},
394+
},
395+
discord.ActionRowComponent{
396+
discord.TextInputComponent{
397+
CustomID: "reason",
398+
Style: discord.TextInputStyleParagraph,
399+
Label: "Ban Reason",
400+
Required: true,
401+
Placeholder: "The reason for the ban",
402+
Value: reason,
403+
},
404+
},
405+
},
406+
})
407+
408+
default:
409+
b.Logger.Errorf("Unknown report action: %s", value)
410+
content = "Unknown action."
411+
}
412+
return e.CreateMessage(discord.MessageCreate{
413+
Content: content,
414+
Flags: discord.MessageFlagEphemeral,
415+
})
416+
}
417+
418+
func reportActionConfirmHandler(b *dbot.Bot, args []string, p *message.Printer, e *events.ModalSubmitInteractionCreate) error {
419+
userID := snowflake.MustParse(args[1])
420+
reason := e.Data.Text("reason")
421+
422+
var content string
423+
switch args[0] {
424+
case "timeout":
337425
until := time.Now()
338-
if strings.HasSuffix(value, "24") {
339-
until = until.Add(24 * time.Hour)
340-
} else {
341-
until = until.Add(1 * time.Hour)
342-
}
343-
if _, err = b.Client.Rest().UpdateMember(*e.GuildID(), snowflake.MustParse(report.UserID), discord.MemberUpdate{
344-
CommunicationDisabledUntil: json.NewOptional(until),
345-
}, reason); err != nil {
346-
b.Logger.Errorf("Failed to update member: %s", err)
347-
content = "Failed to timeout user, please reach out to a bot developer."
426+
duration, err := time.ParseDuration(e.Data.Text("duration"))
427+
if err != nil {
428+
content = "Invalid duration. Please use a valid duration."
348429
} else {
349-
content = "User timed out."
430+
until = until.Add(duration)
431+
if _, err = b.Client.Rest().UpdateMember(*e.GuildID(), userID, discord.MemberUpdate{
432+
CommunicationDisabledUntil: json.NewOptional(until),
433+
}, rest.WithReason(reason)); err != nil {
434+
b.Logger.Errorf("Failed to update member: %s", err)
435+
content = "Failed to timeout user, please reach out to a bot developer."
436+
} else {
437+
content = fmt.Sprintf("Timed out user until %s.", discord.TimestampStyleShortDateTime.FormatTime(until))
438+
}
350439
}
351440

352441
case "kick":
353-
if err = b.Client.Rest().RemoveMember(*e.GuildID(), snowflake.MustParse(report.UserID), reason); err != nil {
442+
if err := b.Client.Rest().RemoveMember(*e.GuildID(), userID, rest.WithReason(reason)); err != nil {
354443
b.Logger.Errorf("Failed to kick user: %s", err)
355444
content = "Failed to kick user, please reach out to a bot developer."
356445
} else {
357446
content = "User kicked."
358447
}
359448

360449
case "ban":
361-
if err = b.Client.Rest().AddBan(*e.GuildID(), snowflake.MustParse(report.UserID), 0, reason); err != nil {
362-
b.Logger.Errorf("Failed to ban user: %s", err)
363-
content = "Failed to ban user, please reach out to a bot developer."
450+
delDays, err := strconv.Atoi(e.Data.Text("del-days"))
451+
if err != nil || delDays < 0 || delDays > 7 {
452+
content = "Invalid message deletion days. Make sure it's a number between 0 and 7."
364453
} else {
365-
content = "User banned."
454+
if err = b.Client.Rest().AddBan(*e.GuildID(), userID, 0, rest.WithReason(reason)); err != nil {
455+
b.Logger.Errorf("Failed to ban user: %s", err)
456+
content = "Failed to ban user, please reach out to a bot developer."
457+
} else {
458+
content = fmt.Sprintf("Banned %s. And deleted messages of the last %d days.", discord.UserMention(userID), delDays)
459+
}
366460
}
367-
368-
default:
369-
b.Logger.Errorf("Unknown report action: %s", value)
370-
content = "Unknown action."
371461
}
462+
372463
return e.CreateMessage(discord.MessageCreate{
373464
Content: content,
374465
Flags: discord.MessageFlagEphemeral,

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/KittyBot-Org/KittyBotGo
33
go 1.18
44

55
require (
6-
github.com/disgoorg/disgo v0.13.5
6+
github.com/disgoorg/disgo v0.13.7
77
github.com/disgoorg/disgolink/disgolink v1.7.3-0.20220702231836-318a7f2edb19
88
github.com/disgoorg/disgolink/lavalink v1.7.2-0.20220702231836-318a7f2edb19
99
github.com/disgoorg/log v1.2.0
@@ -37,7 +37,6 @@ require (
3737
github.com/sasha-s/go-csync v0.0.0-20210812194225-61421b77c44b // indirect
3838
github.com/stretchr/testify v1.8.0 // indirect
3939
golang.org/x/exp v0.0.0-20220713135740-79cabaa25d75 // indirect
40-
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
4140
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
4241
google.golang.org/protobuf v1.28.0 // indirect
4342
gopkg.in/yaml.v3 v3.0.1 // indirect

0 commit comments

Comments
 (0)