-
Notifications
You must be signed in to change notification settings - Fork 59
/
temporaryRoleCommand.ts
217 lines (198 loc) · 5.54 KB
/
temporaryRoleCommand.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
import {
ApplicationCommandOptionType,
ApplicationCommandType,
CommandInteraction,
GuildMember,
PermissionsBitField,
Role,
time,
} from 'discord.js'
import parse from 'humanize-ms'
import { prisma } from '@/prisma'
import { defineCommand } from '@/types/defineCommand'
export const temporaryRoleCommand = defineCommand({
data: {
name: 'temp-role',
description: 'Set a temporary role for a user',
defaultMemberPermissions: PermissionsBitField.Flags.ManageRoles,
type: ApplicationCommandType.ChatInput,
options: [
{
name: 'add',
description: 'Add a temporary role to a user',
type: ApplicationCommandOptionType.Subcommand,
options: [
{
name: 'user',
description: 'User to set the temporary role for',
type: ApplicationCommandOptionType.User,
required: true,
},
{
name: 'role',
description: 'Role to set',
type: ApplicationCommandOptionType.Role,
required: true,
},
{
name: 'duration',
description: 'Duration of the temporary role e.g. 1d',
type: ApplicationCommandOptionType.String,
required: true,
},
],
},
{
name: 'remove',
description: 'Remove a temporary role from a user',
type: ApplicationCommandOptionType.Subcommand,
options: [
{
name: 'user',
description: 'User to remove the temporary role from',
type: ApplicationCommandOptionType.User,
required: true,
},
{
name: 'role',
description: 'Role to remove',
type: ApplicationCommandOptionType.Role,
required: true,
},
],
},
],
},
ephemeral: true,
execute: async (botContext, interaction) => {
if (!interaction.guild || !interaction.isChatInputCommand()) return
// Get user from the interaction
const user = interaction.options.getMember('user') as GuildMember
// Get role from the interaction
const role = interaction.options.getRole('role') as Role
// Get duration from the interaction
const duration = interaction.options.getString('duration') as string
if (interaction.options.getSubcommand() === 'add') {
await temporaryRoleAdd(interaction, user, role, duration)
} else if (interaction.options.getSubcommand() === 'remove') {
await temporaryRoleRemove(interaction, user, role)
}
},
})
async function temporaryRoleAdd(
interaction: CommandInteraction,
user: GuildMember,
role: Role,
duration: string,
) {
// Parse the duration
const durationMs = parse(duration)
// Check if the duration is invalid
if (!durationMs) {
await interaction.editReply({
content: `Invalid duration: ${duration}`,
})
return
}
// Check if the user already has the role
if (user.roles.cache.has(role.id)) {
await interaction.editReply({
content: `User: ${user} already has role: ${role}`,
})
return
}
const expiresAt = new Date(Date.now() + durationMs)
try {
// Add the role to the user
await user.roles.add(role)
// Add the temporary role to the database
try {
await prisma.tempRole.create({
data: {
guildId: interaction.guildId as string,
userId: user.id,
roleId: role.id,
expiresAt: expiresAt,
},
})
} catch (error) {
console.error(
`Failed to add temp role to database`,
(error as Error).message,
)
}
// Reply to the interaction
await interaction.editReply({
content: `User: ${user} got role: ${role} for duration: ${duration} (expires at: ${time(
expiresAt,
)})`,
})
} catch (error) {
console.error(
`Failed to add role "${role.name}" to "${user.user.tag}"`,
(error as Error).message,
)
await interaction.editReply({
content: `Failed to add role: ${role} to user: ${user}`,
})
}
}
async function temporaryRoleRemove(
interaction: CommandInteraction,
user: GuildMember,
role: Role,
) {
// Check if the role is not a temporary role
if (
user.roles.cache.has(role.id) &&
!(await prisma.tempRole.findFirst({
where: {
guildId: interaction.guildId as string,
userId: user.id,
roleId: role.id,
},
}))
) {
await interaction.editReply({
content: `Cannot remove role: ${role} from user: ${user} because it's not a temporary role`,
})
return
}
// Check if the user not has the role
if (!user.roles.cache.has(role.id)) {
await interaction.editReply({
content: `User: ${user} does not have role: ${role}`,
})
return
}
try {
// Remove the role from the user
await user.roles.remove(role)
// Remove the temporary role from the database
try {
await prisma.tempRole.deleteMany({
where: {
guildId: interaction.guildId as string,
userId: user.id,
roleId: role.id,
},
})
} catch (error) {
console.error(
`Failed to remove temp role from database`,
(error as Error).message,
)
}
// Reply to the interaction
await interaction.editReply({
content: `User: ${user} lost role: ${role}`,
})
} catch {
console.error(
`Failed to remove role "${role.name}" from "${user.user.tag}"`,
)
await interaction.editReply({
content: `Failed to remove role: ${role} from user: ${user}`,
})
}
}