1- import { Context } from 'grammy' ;
1+ import { Context , InlineKeyboard } from 'grammy' ;
22import { BotReply } from '../../../utils/chat/BotReply' ;
33import { Catch } from '../../../decorators/Catch' ;
44import { AdminValidationService } from '../../service/admin/validation' ;
55import { ApprovedService } from '../../service/admin/Approved' ;
6-
6+ import { BanService } from '../../service/admin/Ban' ;
7+ import { WarnService } from '../../service/admin/Warn' ;
8+ import { parseDuration , tehranZone } from '../../../utils' ;
9+ import { MuteService } from '../../service/admin/Mute' ;
10+ import { AdminService } from '../../service/admin/Admin' ;
11+ import { BlackListService } from '../../service/admin/Blacklist' ;
12+ import { ChatInfo } from '../../../utils/chat/ChatInfo' ;
13+ import { GroupSettingsService } from '../../service/admin/Welcome' ;
714export class AdminCommands {
815 /** Approved Commands */
916 @Catch ( {
@@ -13,7 +20,7 @@ export class AdminCommands {
1320 } )
1421 static async approved ( ctx : Context ) {
1522 const reply = new BotReply ( ctx ) ;
16- const validationResult = await AdminValidationService . validateApprovalContext ( ctx ) ;
23+ const validationResult = await AdminValidationService . validateContext ( ctx ) ;
1724
1825 if ( ! validationResult ) {
1926 return ;
@@ -30,14 +37,14 @@ export class AdminCommands {
3037 static async disapproved ( ctx : Context ) {
3138 const reply = new BotReply ( ctx ) ;
3239 // Validate the context to extract required group and user IDs
33- const validationResult = await AdminValidationService . validateApprovalContext ( ctx ) ;
40+ const validationResult = await AdminValidationService . validateContext ( ctx ) ;
3441
3542 if ( ! validationResult ) {
3643 return ;
3744 }
3845
3946 const { groupId, userId } = validationResult ;
40- await ApprovedService . updateDisapproved ( ctx , groupId , userId ) ;
47+ await ApprovedService . updateDisapproved ( ctx , groupId , userId ) ;
4148 await reply . textReply ( `User with ID ${ userId } has been successfully disapproved for group ${ groupId } .` ) ;
4249 }
4350 @Catch ( {
@@ -47,54 +54,264 @@ export class AdminCommands {
4754 } )
4855 static async approvedlist ( ctx : Context ) {
4956 const reply = new BotReply ( ctx ) ;
50- const chat = ctx . chat ;
51- if ( ! ( chat ?. type === 'group' || chat ?. type === 'supergroup' ) ) {
52- await ctx . reply ( 'This command can only be used in groups.' ) ;
53- return ;
54- }
55-
56- const groupId = chat . id ;
57+ const groupId = ctx . chat ! . id ;
5758 const approvedUsers = await ApprovedService . getApprovedUsers ( ctx , groupId ) ;
5859 if ( ! approvedUsers . length ) {
59- await reply . textReply ( 'No users are approved in this group.' ) ;
60+ await reply . textReply ( 'There are currently no approved users in this group.' ) ;
6061 return ;
6162 }
62- const approvedListMessage = approvedUsers . map ( ( user ) => `ID: ${ user . telegram_id } ,\nFirstname: ${ user . first_name } ` ) . join ( '\n' ) ;
63- await reply . textReply ( `Approved users in this group:\n${ approvedListMessage } ` ) ;
63+ const approvedListMessage = approvedUsers . map ( ( user ) => `• **ID:** ${ user . telegram_id } \n **Name:** ${ user . first_name } ` ) . join ( '\n\n' ) ;
64+
65+ // Send a formatted message with the list of approved users
66+ await reply . markdownReply ( `Here is the list of approved users in this group:\n\n${ approvedListMessage } ` ) ;
6467 }
6568 /** Ban Commands */
66- static async ban ( ) { }
67- static async unban ( ) { }
69+ static async ban ( ctx : Context ) {
70+ const reply = new BotReply ( ctx ) ;
71+ const groupId = ctx . chat ! . id ;
72+ const isBanUser = await BanService . ban ( ctx ) ;
73+ if ( isBanUser ) {
74+ await ctx . api . banChatMember ( groupId , ctx . message ?. reply_to_message ?. from ?. id ! ) ;
75+ await reply . textReply ( `User ${ ctx . message ?. reply_to_message ?. from ! . first_name } has been removed from the group and their information has been deleted.` ) ;
76+ return ;
77+ } else {
78+ await reply . textReply ( 'User or group not found.' ) ;
79+ return ;
80+ }
81+ }
82+ static async unban ( ctx : Context ) {
83+ const reply = new BotReply ( ctx ) ;
84+ const unBanUser = await BanService . unBan ( ctx ) ;
85+ 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.' ) ;
90+ return ;
91+ }
92+ }
6893 /** Warn Commands */
69- static async warn ( ) { }
70- static async rmwarn ( ) { }
71- static async warns ( ) { }
72- static async warnslist ( ) { }
94+ static async warn ( ctx : Context ) {
95+ const reply = new BotReply ( ctx ) ;
96+ const user = ctx . message ?. reply_to_message ?. from ! ;
97+ const { isWarningLimitReached, warningApplied, warnings } = await WarnService . warnUser ( ctx ) ;
98+ if ( isWarningLimitReached && warningApplied ) {
99+ await reply . textReply ( `User ${ user . first_name } has been muted for 1 day due to excessive warnings.` ) ;
100+ return ;
101+ } else if ( ! isWarningLimitReached && warningApplied ) {
102+ await reply . textReply ( `User ${ user . first_name } has been warned. They now have ${ warnings } warnings.` ) ;
103+ return ;
104+ } else {
105+ await reply . textReply ( 'User or group not found.' ) ;
106+ return ;
107+ }
108+ }
109+ static async rmwarn ( ctx : Context ) {
110+ const reply = new BotReply ( ctx ) ;
111+ const user = ctx . message ?. reply_to_message ?. from ! ;
112+ const { warningRemoved, warnings } = await WarnService . removeWarn ( ctx ) ;
113+
114+ if ( warningRemoved ) {
115+ await reply . textReply ( `User ${ user . first_name } now has ${ warnings } warnings after the removal.` ) ;
116+ } else {
117+ await reply . textReply ( 'User or group not found or no warnings to remove.' ) ;
118+ }
119+ }
120+ static async warns ( ctx : Context ) {
121+ const reply = new BotReply ( ctx ) ;
122+ const user = ctx . message ?. reply_to_message ?. from ! ;
123+
124+ const { warnings } = await WarnService . getUserWarnById ( ctx ) ;
125+
126+ if ( warnings >= 0 ) {
127+ await reply . textReply ( `User ${ user . first_name } currently has ${ warnings } warnings.` ) ;
128+ } else {
129+ await reply . textReply ( 'User not found.' ) ;
130+ }
131+ }
132+ static async warnslist ( ctx : Context ) {
133+ const reply = new BotReply ( ctx ) ;
134+ const warns = await WarnService . getAllWarns ( ctx ) ;
135+ await reply . markdownReply ( `${ warns } ` ) ;
136+ }
73137 /** Mute Commands */
74- static async mute ( ) { }
75- static async unmute ( ) { }
76- static async mutelist ( ) { }
138+ static async mute ( ctx : Context ) {
139+ const reply = new BotReply ( ctx ) ;
140+ const message = await MuteService . muteUser ( ctx ) ;
141+ return await reply . textReply ( message ) ;
142+ }
143+ static async unmute ( ctx : Context ) {
144+ const reply = new BotReply ( ctx ) ;
145+ const message = await MuteService . unmuteUser ( ctx ) ;
146+ return await reply . textReply ( message ) ;
147+ }
77148 /** Admin Command */
78- static async grant ( ) { }
79- static async revoke ( ) { }
149+ static async grant ( ctx : Context ) {
150+ const reply = new BotReply ( ctx ) ;
151+ const grantUser = await AdminService . grant ( ctx ) ;
152+ await reply . textReply ( grantUser ) ;
153+ }
154+ static async revoke ( ctx : Context ) {
155+ const reply = new BotReply ( ctx ) ;
156+ const revokeUser = await AdminService . revoke ( ctx ) ;
157+ await reply . textReply ( revokeUser ) ;
158+ }
159+ @Catch ( {
160+ category : 'BlackList' ,
161+ message : 'Failed to retrieve or send the blacklist.' ,
162+ statusCode : 500 ,
163+ } )
80164 /** BlackList Command */
81- static async blacklist ( ) { }
82- static async rmbl ( ) { }
83- static async abl ( ) { }
84- /** Rules Commands */
85- /** add-rule|edit-rule|delete-rule|delete_last-rule|view-rule| */
86- static async rules ( ) { }
165+ static async blacklist ( ctx : Context ) {
166+ const reply = new BotReply ( ctx ) ;
167+ const userId = ctx . from ?. id ! ;
168+ const groupId = ctx . chat ?. id ! ;
169+ const admins = await ctx . getChatAdministrators ( ) ;
170+ const isAdmin = admins . some ( ( admin ) => admin . user . id === userId ) ;
171+ if ( ! isAdmin ) {
172+ await reply . textReply ( 'You need to be an admin to view the blacklist.' ) ;
173+ return ;
174+ }
175+ await reply . textReply ( 'I have sent you a message in your private chat with the blacklist.' ) ;
176+ const blackList = await BlackListService . getAll ( ctx , groupId ) ;
177+ if ( blackList . length === 0 ) {
178+ await ctx . api . sendMessage ( userId , 'The blacklist is currently empty.' ) ;
179+ } else {
180+ await ctx . api . sendMessage ( userId , `Blacklist:\n${ blackList . join ( '\n' ) } ` ) ;
181+ }
182+ return ;
183+ }
184+ @Catch ( {
185+ category : 'BlackList' ,
186+ message : 'Failed to add word to the blacklist.' ,
187+ statusCode : 400 ,
188+ } )
189+ /** Add a Word to the Blacklist */
190+ static async abl ( ctx : Context ) {
191+ const reply = new BotReply ( ctx ) ;
192+ await ctx . deleteMessage ( ) ;
193+ const groupId = ctx . chat ?. id ! ;
194+ const word = ctx . message ?. text ?. split ( ' ' ) [ 1 ] ;
195+ if ( ! word ) {
196+ await reply . textReply ( 'Please specify a word to add to the blacklist.' ) ;
197+ return ;
198+ }
199+ await BlackListService . add ( groupId , word ) ;
200+ await reply . send ( 'Blacklist has been updated.' ) ;
201+ }
202+ @Catch ( {
203+ category : 'BlackList' ,
204+ message : 'Failed to remove word from the blacklist.' ,
205+ statusCode : 400 ,
206+ } )
207+ /** Remove the Last Word from the Blacklist */
208+ static async rmbl ( ctx : Context ) {
209+ const reply = new BotReply ( ctx ) ;
210+ await ctx . deleteMessage ( ) ;
211+ const groupId = ctx . chat ?. id ! ;
212+ const wordToRemove = ctx . message ?. text ?. split ( ' ' ) [ 1 ] ;
213+ await BlackListService . remove ( groupId , wordToRemove ) ;
214+ await reply . send ( 'Blacklist has been updated.' ) ;
215+ }
216+ @Catch ( {
217+ category : 'BlackList' ,
218+ message : 'Failed to Clear the Entire Blacklist.' ,
219+ statusCode : 400 ,
220+ } )
221+ /** Clear the Entire Blacklist */
222+ static async clrbl ( ctx : Context ) {
223+ await ctx . deleteMessage ( ) ;
224+ const reply = new BotReply ( ctx ) ;
225+ const groupId = ctx . chat ?. id ! ;
226+ await BlackListService . clear ( groupId ) ;
227+ await reply . send ( 'The blacklist has been cleared.' ) ;
228+ }
87229 /** Pin Command */
88- static async pin ( ) { }
89- static async unpin ( ) { }
230+ static async pin ( ctx : Context ) {
231+ const reply = new BotReply ( ctx ) ;
232+ const groupId = ctx . chat ?. id ! ;
233+ const messageId = ctx . message ?. reply_to_message ?. message_id ! ;
234+ await ctx . api . pinChatMessage ( groupId , messageId ) ;
235+ await reply . textReply ( 'The message has been pinned.' ) ;
236+ }
237+ static async unpin ( ctx : Context ) {
238+ const reply = new BotReply ( ctx ) ;
239+ const groupId = ctx . chat ?. id ! ;
240+ const messageId = ctx . message ?. reply_to_message ?. message_id ! ;
241+ await ctx . api . unpinChatMessage ( groupId , messageId ) ;
242+ await reply . textReply ( 'The pinned message has been unpinned.' ) ;
243+ }
90244 /** Purge Command */
91- static async purge ( ) { }
245+ static async purge ( ctx : Context ) {
246+ const reply = new BotReply ( ctx ) ;
247+ const chatId = ctx . chat ?. id ;
248+ const replyToMessageId = ctx . message ?. reply_to_message ?. message_id ;
249+ if ( ! chatId || ! replyToMessageId ) {
250+ return reply . send ( 'Please reply to a message and use the /purge command.' ) ;
251+ }
252+
253+ let lastMessageId = ctx . message ?. message_id ;
254+ if ( ! lastMessageId ) {
255+ return reply . send ( 'No message ID found.' ) ;
256+ }
257+
258+ const countMessages = lastMessageId - replyToMessageId ;
259+ if ( countMessages <= 0 ) {
260+ return reply . send ( 'The reply-to message is not older than the current message or no messages to delete.' ) ;
261+ }
262+
263+ const messagesToDelete = [ ] ;
264+ for ( let i = 0 ; i <= countMessages ; i ++ ) {
265+ messagesToDelete . push ( replyToMessageId + i ) ;
266+ }
267+
268+ const deleteMessagesInBatches = async ( messages : number [ ] ) => {
269+ const batchSize = 100 ;
270+ for ( let i = 0 ; i < messages . length ; i += batchSize ) {
271+ const batch = messages . slice ( i , i + batchSize ) ;
272+ await ctx . deleteMessages ( batch ) ;
273+ }
274+ } ;
275+
276+ await deleteMessagesInBatches ( messagesToDelete ) ;
277+ await reply . send ( 'Deleting done.' ) ;
278+ }
92279 /** Group Setting Command */
93- static async lock ( ) { }
94- static async unlock ( ) { }
95- static async title ( ) { }
96- static async welcome ( ) { }
280+ static async welcome ( ctx : Context ) {
281+ const reply = new BotReply ( ctx ) ;
282+ const input = ctx . message ?. text ! . split ( / \s + / ) . slice ( 1 ) ;
283+ const action = input ! [ 0 ] ?. toLowerCase ( ) ;
284+ const welcomeContent = input ! . join ( ' ' ) ;
285+ if ( ! action ) {
286+ // Retrieve the current welcome message from the database (or service)
287+ const currentWelcome = await GroupSettingsService . getWelcomeMessage ( ctx , welcomeContent ) ;
288+ if ( currentWelcome ) {
289+ await reply . textReply ( `Current welcome message: \n${ currentWelcome } ` ) ;
290+ } else {
291+ await reply . textReply ( 'No welcome message set for this group.' ) ;
292+ }
293+ return ;
294+ }
295+
296+ // Case to remove the welcome message
297+ if ( action === 'r' ) {
298+ // Delete the current welcome message from the database (or service)
299+ const result = await GroupSettingsService . removeWelcomeMessage ( ctx ) ;
300+ if ( result ) {
301+ await reply . textReply ( 'The welcome message has been removed.' ) ;
302+ } else {
303+ await reply . textReply ( 'No welcome message to remove.' ) ;
304+ }
305+ return ;
306+ }
307+ if ( welcomeContent ) {
308+ console . log ( 'welcomeContent' , welcomeContent ) ;
309+ await GroupSettingsService . setWelcomeMessage ( ctx , welcomeContent ) ;
310+ await reply . textReply ( `The welcome message has been updated to: \n${ welcomeContent } ` ) ;
311+ return ;
312+ }
97313
98- /** General Commands */
99- static async group_stats ( ) { }
314+ // Default response if no valid action is detected
315+ await reply . textReply ( 'Invalid usage of the /welcome command. Use "/welcome" to view the current message, "/welcome r" to remove it, or "/welcome [message]" to set a new welcome message.' ) ;
316+ }
100317}
0 commit comments