Skip to content

Commit 63ad130

Browse files
committed
feat(bot): New decorations are added to the code and middlewares are completely destroyed and we use decorations instead of middlewares.
1 parent 050dfc2 commit 63ad130

19 files changed

Lines changed: 285 additions & 339 deletions

File tree

src/bot/commands/admin/AdminCommands.ts

Lines changed: 155 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,17 @@ import { AdminService } from '../../service/admin/Admin';
1010
import { BlackListService } from '../../service/admin/Blacklist';
1111
import { ChatInfo } from '../../../utils/chat/ChatInfo';
1212
import { GroupSettingsService } from '../../service/admin/Welcome';
13-
import { User } from 'grammy/types';
13+
import { OnlyAdminsCanUse } from '../../../decorators/User';
14+
import { RequireReply, RestrictToGroupChats } from '../../../decorators/Context';
15+
import { EnsureUserAndGroup } from '../../../decorators/Database';
16+
import { BotIsAdmin } from '../../../decorators/Bot';
1417
export class AdminCommands {
1518
/** Approved Commands */
19+
@BotIsAdmin()
20+
@RestrictToGroupChats()
21+
@OnlyAdminsCanUse()
22+
@RequireReply()
23+
@EnsureUserAndGroup()
1624
@Catch({
1725
category: 'Admin Command',
1826
message: 'An unexpected error occurred while processing the "approved" command. Please try again later.',
@@ -26,9 +34,21 @@ export class AdminCommands {
2634
return;
2735
}
2836
const { groupId, userId } = validationResult;
29-
await ApprovedService.updateApproved(ctx, groupId, userId);
30-
await reply.textReply(`User with ID ${userId} has been successfully approved for group ${groupId}.`);
37+
const isApproved = await ApprovedService.updateApproved(groupId, userId);
38+
if (!isApproved) {
39+
await reply.textReply(`This user has already been approved.`);
40+
} else {
41+
await reply.textReply(
42+
`The user with ID ${userId} has been successfully approved to join the group ${groupId}. You can view the list of approved users using /approvedlist, and manage disapproved users with /disapproved.`
43+
);
44+
}
3145
}
46+
47+
@BotIsAdmin()
48+
@RestrictToGroupChats()
49+
@OnlyAdminsCanUse()
50+
@RequireReply()
51+
@EnsureUserAndGroup()
3252
@Catch({
3353
category: 'Admin Command',
3454
message: 'An unexpected error occurred while processing the "disapproved" command. Please try again later.',
@@ -37,16 +57,20 @@ export class AdminCommands {
3757
static async disapproved(ctx: Context) {
3858
const reply = new BotReply(ctx);
3959
// Validate the context to extract required group and user IDs
40-
const validationResult = await AdminValidationService.validateContext(ctx);
41-
42-
if (!validationResult) {
43-
return;
44-
}
45-
60+
const validationResult = (await AdminValidationService.validateContext(ctx))!;
4661
const { groupId, userId } = validationResult;
47-
await ApprovedService.updateDisapproved(ctx, groupId, userId);
48-
await reply.textReply(`User with ID ${userId} has been successfully disapproved for group ${groupId}.`);
62+
const disapprovedUser = await ApprovedService.updateDisapproved(groupId, userId);
63+
if (!disapprovedUser) {
64+
await reply.textReply('This user is not currently approved, so they cannot be disapproved.');
65+
} else {
66+
await reply.textReply(`User with ID ${userId} has been successfully disapproved and removed from group ${groupId}.`);
67+
}
4968
}
69+
70+
@BotIsAdmin()
71+
@RestrictToGroupChats()
72+
@OnlyAdminsCanUse()
73+
@EnsureUserAndGroup()
5074
@Catch({
5175
category: 'Admin Command',
5276
message: 'An unexpected error occurred while processing the "approvedlist" command. Please try again later.',
@@ -55,7 +79,7 @@ export class AdminCommands {
5579
static async approvedlist(ctx: Context) {
5680
const reply = new BotReply(ctx);
5781
const groupId = ctx.chat!.id;
58-
const approvedUsers = await ApprovedService.getApprovedUsers(ctx, groupId);
82+
const approvedUsers = await ApprovedService.getApprovedUsers(groupId);
5983
if (!approvedUsers.length) {
6084
await reply.textReply('There are currently no approved users in this group.');
6185
return;
@@ -66,6 +90,12 @@ export class AdminCommands {
6690
await reply.markdownReply(`Here is the list of approved users in this group:\n\n${approvedListMessage}`);
6791
}
6892
/** Ban Commands */
93+
@BotIsAdmin()
94+
@RestrictToGroupChats()
95+
@OnlyAdminsCanUse()
96+
@RequireReply()
97+
@EnsureUserAndGroup()
98+
@Catch()
6999
static async ban(ctx: Context) {
70100
const reply = new BotReply(ctx);
71101
const groupId = ctx.chat!.id;
@@ -74,23 +104,29 @@ export class AdminCommands {
74104
await ctx.api.banChatMember(groupId, ctx.message?.reply_to_message?.from?.id!);
75105
await reply.textReply(`User ${ctx.message?.reply_to_message?.from!.first_name} has been removed from the group and their information has been deleted.`);
76106
return;
77-
} else {
78-
await reply.textReply('User or group not found.');
79-
return;
80107
}
81108
}
109+
@BotIsAdmin()
110+
@RestrictToGroupChats()
111+
@OnlyAdminsCanUse()
112+
@RequireReply()
113+
@EnsureUserAndGroup()
114+
@Catch()
82115
static async unban(ctx: Context) {
83116
const reply = new BotReply(ctx);
84117
const unBanUser = await BanService.unBan(ctx);
85118
if (unBanUser) {
86-
await reply.textReply(`User ${ctx.message?.reply_to_message?.from?.first_name} has been unbanned and their information has been restored.`);
87-
return;
88-
} else {
89-
await reply.textReply('Please reply to a message from the user you want to unban.');
119+
await reply.textReply(`User ${ctx.message?.reply_to_message?.from?.first_name} has been unbanned.`);
90120
return;
91121
}
92122
}
93123
/** Warn Commands */
124+
@BotIsAdmin()
125+
@RestrictToGroupChats()
126+
@OnlyAdminsCanUse()
127+
@RequireReply()
128+
@EnsureUserAndGroup()
129+
@Catch()
94130
static async warn(ctx: Context) {
95131
const reply = new BotReply(ctx);
96132
const user = ctx.message?.reply_to_message?.from!;
@@ -101,11 +137,14 @@ export class AdminCommands {
101137
} else if (!isWarningLimitReached && warningApplied) {
102138
await reply.textReply(`User ${user.first_name} has been warned. They now have ${warnings} warnings.`);
103139
return;
104-
} else {
105-
await reply.textReply('User or group not found.');
106-
return;
107140
}
108141
}
142+
@BotIsAdmin()
143+
@RestrictToGroupChats()
144+
@OnlyAdminsCanUse()
145+
@RequireReply()
146+
@EnsureUserAndGroup()
147+
@Catch()
109148
static async rmwarn(ctx: Context) {
110149
const reply = new BotReply(ctx);
111150
const user = ctx.message?.reply_to_message?.from!;
@@ -117,40 +156,62 @@ export class AdminCommands {
117156
await reply.textReply('User or group not found or no warnings to remove.');
118157
}
119158
}
159+
@BotIsAdmin()
160+
@RestrictToGroupChats()
161+
@EnsureUserAndGroup()
120162
static async warns(ctx: Context) {
121163
const reply = new BotReply(ctx);
122164
const replyMessage = ctx.message?.reply_to_message;
123165
let user = ctx.message?.reply_to_message?.from!;
124-
if (replyMessage?.forum_topic_created) {
166+
if (!replyMessage) {
125167
user = ctx.from!;
126168
}
127-
const { warnings } = await WarnService.getUserWarnById(ctx);
128-
169+
const { warnings } = await WarnService.getUserWarnById(ctx, user.id);
129170
if (warnings >= 0) {
130-
await reply.textReply(`User ${user.first_name} currently has ${warnings} warnings.`);
171+
return await reply.textReply(`User ${user.first_name} currently has ${warnings} warnings.`);
131172
} else {
132-
await reply.textReply('User not found.');
173+
return await reply.textReply('User not found.');
133174
}
134175
}
176+
@BotIsAdmin()
177+
@RestrictToGroupChats()
178+
@OnlyAdminsCanUse()
179+
@EnsureUserAndGroup()
180+
@Catch()
135181
static async warnslist(ctx: Context) {
136182
const reply = new BotReply(ctx);
137183
const warns = await WarnService.getAllWarns(ctx);
138184
await reply.markdownReply(`${warns}`);
139185
}
140186
/** Mute Commands */
187+
@BotIsAdmin()
188+
@RestrictToGroupChats()
189+
@OnlyAdminsCanUse()
190+
@RequireReply()
191+
@EnsureUserAndGroup()
141192
@Catch()
142193
static async mute(ctx: Context) {
143194
const reply = new BotReply(ctx);
144195
const message = await MuteService.muteUser(ctx);
145196
return await reply.textReply(message);
146197
}
198+
@BotIsAdmin()
199+
@RestrictToGroupChats()
200+
@OnlyAdminsCanUse()
201+
@RequireReply()
202+
@EnsureUserAndGroup()
147203
@Catch()
148204
static async unmute(ctx: Context) {
149205
const reply = new BotReply(ctx);
150206
const message = await MuteService.unmuteUser(ctx);
151207
return await reply.textReply(message);
152208
}
153209
/** Admin Command */
210+
@BotIsAdmin()
211+
@RestrictToGroupChats()
212+
@OnlyAdminsCanUse()
213+
@RequireReply()
214+
@EnsureUserAndGroup()
154215
@Catch()
155216
static async grant(ctx: Context) {
156217
const reply = new BotReply(ctx);
@@ -163,6 +224,11 @@ export class AdminCommands {
163224
const grantUser = await AdminService.grant(ctx);
164225
await reply.textReply(grantUser);
165226
}
227+
@BotIsAdmin()
228+
@RestrictToGroupChats()
229+
@OnlyAdminsCanUse()
230+
@RequireReply()
231+
@EnsureUserAndGroup()
166232
@Catch()
167233
static async revoke(ctx: Context) {
168234
const reply = new BotReply(ctx);
@@ -175,16 +241,23 @@ export class AdminCommands {
175241
const revokeUser = await AdminService.revoke(ctx);
176242
await reply.textReply(revokeUser);
177243
}
244+
245+
/** BlackList Command */
246+
@BotIsAdmin()
247+
@RestrictToGroupChats()
248+
@OnlyAdminsCanUse()
249+
@EnsureUserAndGroup()
178250
@Catch({
179251
category: 'BlackList',
180252
message: 'Failed to retrieve or send the blacklist.',
181253
statusCode: 500,
182254
})
183-
/** BlackList Command */
184255
static async blacklist(ctx: Context) {
185256
const reply = new BotReply(ctx);
257+
// Fetch the group info
258+
const group = ctx.chat;
186259
const userId = ctx.from?.id!;
187-
const groupId = ctx.chat?.id!;
260+
const groupId = group?.id!;
188261
const admins = await ctx.getChatAdministrators();
189262
const isAdmin = admins.some((admin) => admin.user.id === userId);
190263
if (!isAdmin) {
@@ -193,19 +266,32 @@ export class AdminCommands {
193266
}
194267
await reply.textReply('I have sent you a message in your private chat with the blacklist.');
195268
const blackList = await BlackListService.getAll(ctx, groupId);
269+
// Gather information about the group
270+
const groupInfo = `
271+
Group Title: ${group?.title || 'N/A'}\n
272+
Group ID: ${groupId}\n
273+
Group Type: ${group?.type || 'Unknown'}
274+
`;
275+
276+
// Send the group info along with the blacklist
196277
if (blackList.length === 0) {
197-
await ctx.api.sendMessage(userId, 'The blacklist is currently empty.');
278+
await ctx.api.sendMessage(userId, `${groupInfo}\nThe blacklist is currently empty.`);
198279
} else {
199-
await ctx.api.sendMessage(userId, `Blacklist:\n${blackList.join('\n')}`);
280+
await ctx.api.sendMessage(userId, `${groupInfo}\nBlacklist:\n${blackList.join('\n')}`);
200281
}
201282
return;
202283
}
284+
285+
/** Add a Word to the Blacklist */
286+
@BotIsAdmin()
287+
@RestrictToGroupChats()
288+
@OnlyAdminsCanUse()
289+
@EnsureUserAndGroup()
203290
@Catch({
204291
category: 'BlackList',
205292
message: 'Failed to add word to the blacklist.',
206293
statusCode: 400,
207294
})
208-
/** Add a Word to the Blacklist */
209295
static async abl(ctx: Context) {
210296
const reply = new BotReply(ctx);
211297
await ctx.deleteMessage();
@@ -216,43 +302,65 @@ export class AdminCommands {
216302
return;
217303
}
218304
await BlackListService.add(groupId, word, ctx);
219-
await reply.send('Blacklist has been updated.');
305+
await reply.sendToTopic('Blacklist has been updated.', ctx.message?.reply_to_message?.message_thread_id!);
220306
}
307+
308+
/** Remove the Last Word from the Blacklist */
309+
@BotIsAdmin()
310+
@RestrictToGroupChats()
311+
@OnlyAdminsCanUse()
312+
@EnsureUserAndGroup()
221313
@Catch({
222314
category: 'BlackList',
223315
message: 'Failed to remove word from the blacklist.',
224316
statusCode: 400,
225317
})
226-
/** Remove the Last Word from the Blacklist */
227318
static async rmbl(ctx: Context) {
228319
const reply = new BotReply(ctx);
229320
await ctx.deleteMessage();
230321
const groupId = ctx.chat?.id!;
231322
const wordToRemove = ctx.message?.text?.split(' ')[1];
232323
await BlackListService.remove(groupId, ctx, wordToRemove);
233-
await reply.send('Blacklist has been updated.');
324+
await reply.sendToTopic('Blacklist has been updated.', ctx.message?.reply_to_message?.message_thread_id!);
234325
}
326+
327+
/** Clear the Entire Blacklist */
328+
@BotIsAdmin()
329+
@RestrictToGroupChats()
330+
@OnlyAdminsCanUse()
331+
@EnsureUserAndGroup()
235332
@Catch({
236333
category: 'BlackList',
237334
message: 'Failed to Clear the Entire Blacklist.',
238335
statusCode: 400,
239336
})
240-
/** Clear the Entire Blacklist */
241337
static async clrbl(ctx: Context) {
242338
await ctx.deleteMessage();
243339
const reply = new BotReply(ctx);
244340
const groupId = ctx.chat?.id!;
245341
await BlackListService.clear(groupId, ctx);
246-
await reply.send('The blacklist has been cleared.');
342+
await reply.sendToTopic('The blacklist has been cleared.', ctx.message?.reply_to_message?.message_thread_id!);
247343
}
248344
/** Pin Command */
345+
@BotIsAdmin()
346+
@RestrictToGroupChats()
347+
@OnlyAdminsCanUse()
348+
@RequireReply()
349+
@EnsureUserAndGroup()
350+
@Catch()
249351
static async pin(ctx: Context) {
250352
const reply = new BotReply(ctx);
251353
const groupId = ctx.chat?.id!;
252354
const messageId = ctx.message?.reply_to_message?.message_id!;
253355
await ctx.api.pinChatMessage(groupId, messageId);
254356
await reply.textReply('The message has been pinned.');
255357
}
358+
@BotIsAdmin()
359+
@RestrictToGroupChats()
360+
@OnlyAdminsCanUse()
361+
@RequireReply()
362+
@EnsureUserAndGroup()
363+
@Catch()
256364
static async unpin(ctx: Context) {
257365
const reply = new BotReply(ctx);
258366
const groupId = ctx.chat?.id!;
@@ -261,6 +369,11 @@ export class AdminCommands {
261369
await reply.textReply('The pinned message has been unpinned.');
262370
}
263371
/** Purge Command */
372+
@BotIsAdmin()
373+
@RestrictToGroupChats()
374+
@OnlyAdminsCanUse()
375+
@RequireReply()
376+
@EnsureUserAndGroup()
264377
static async purge(ctx: Context) {
265378
const reply = new BotReply(ctx);
266379
const chatInfo = new ChatInfo(ctx);
@@ -302,9 +415,13 @@ export class AdminCommands {
302415
await reply.send('Deleting done.');
303416
}
304417
/** Group Setting Command */
418+
@BotIsAdmin()
419+
@RestrictToGroupChats()
420+
@OnlyAdminsCanUse()
421+
@EnsureUserAndGroup()
305422
static async welcome(ctx: Context) {
306423
const reply = new BotReply(ctx);
307-
const input = ctx.message?.text!.split(/\s+/).slice(1);
424+
const input = ctx.message?.text!.split(' ').slice(1);
308425
const action = input![0]?.toLowerCase();
309426
const welcomeContent = input!.join(' ');
310427
if (!action) {

0 commit comments

Comments
 (0)