Skip to content

Commit f0d1a87

Browse files
committed
feat(bot): implement core utilities and features for command handling and rate limiting
- Add JSON configuration for group and command responses: - Includes responses for various bot actions like user management (`ban`, `mute`, `warn`), group events (e.g., welcome messages), and command outputs. - Centralized text management for better localization and customization. - Implement centralized logging utility: - Added a `Log` class utilizing `@medishen/gland-logger` for structured logging. - Provides methods for logging `info`, `warn`, `error`, and `debug` messages with configurable transport and format. - Define command list: - Created a `COMMANDS` constant for standardized command names. - Categorized commands into general, user, and admin-specific functionalities. - Defined `CommandName` type for stricter typing in command handling. - Add rate-limiting utility: - `RateLimiter` class to prevent command abuse with configurable limits: - Maximum commands (`COMMAND_LIMIT`) per time frame (`TIME_FRAME`). - Automatic cleanup of stale entries after a defined interval (`CLEANUP_INTERVAL`). - Ensures smoother operation and protects against spam. - Miscellaneous: - Improved maintainability and readability by organizing utilities and constants. - Established groundwork for scalable bot features with structured handling of commands and responses.
1 parent ae82067 commit f0d1a87

6 files changed

Lines changed: 334 additions & 0 deletions

File tree

src/utils/RateLimiter.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { RateLimitEntry } from '../types/ResponseTypes';
2+
3+
export class RateLimiter {
4+
private static rateLimits: Map<number, RateLimitEntry> = new Map();
5+
private static COMMAND_LIMIT = 5; // Max commands allowed
6+
private static TIME_FRAME = 10000; // Time frame in milliseconds (10 seconds)
7+
private static CLEANUP_INTERVAL = 60000; // Cleanup interval in milliseconds (1 minute)
8+
9+
// Initializes the cleanup task
10+
static initCleanup() {
11+
setInterval(() => {
12+
const currentTime = Date.now();
13+
for (const [userId, entry] of this.rateLimits.entries()) {
14+
if (currentTime - entry.lastCommandTime > this.TIME_FRAME) {
15+
this.rateLimits.delete(userId);
16+
}
17+
}
18+
}, this.CLEANUP_INTERVAL);
19+
}
20+
21+
// Rate limit checking logic
22+
static limit(userId: number): boolean {
23+
const currentTime = Date.now();
24+
const entry = this.rateLimits.get(userId);
25+
26+
if (entry) {
27+
if (currentTime - entry.lastCommandTime > this.TIME_FRAME) {
28+
// Reset if the time frame has passed
29+
this.rateLimits.set(userId, {
30+
lastCommandTime: currentTime,
31+
commandCount: 1,
32+
});
33+
return true;
34+
}
35+
36+
if (entry.commandCount < this.COMMAND_LIMIT) {
37+
// Increment the command count
38+
entry.commandCount += 1;
39+
this.rateLimits.set(userId, entry);
40+
return true;
41+
} else {
42+
// Rate limit exceeded, silently return false
43+
return false;
44+
}
45+
} else {
46+
// First command from the user
47+
this.rateLimits.set(userId, {
48+
lastCommandTime: currentTime,
49+
commandCount: 1,
50+
});
51+
return true;
52+
}
53+
}
54+
}
55+
RateLimiter.initCleanup();

src/utils/index.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
export const COMMANDS: string[] = [
2+
/** General Commands */
3+
'start',
4+
'help',
5+
'commands',
6+
'date',
7+
'viewsupportcontact',
8+
'getbotinfo',
9+
/** Users Commands */
10+
'rules',
11+
'codetime',
12+
'future',
13+
'news',
14+
'groupinfo',
15+
'report',
16+
'cancel',
17+
'link',
18+
'adminlist',
19+
/** admin Commands */
20+
/** Approved Commands */
21+
'approved','disapproved','approvedlist',
22+
/** Ban Commands */
23+
'ban','unban',
24+
/** Warn Commands */
25+
'warn','rmwarn','warns','warnslist',
26+
/** Mute Commands */
27+
'mute','unmute','mutelist',
28+
/** Admin Command */
29+
'grant','revoke',
30+
/** BlackList Command */
31+
'blacklist','rmbl','abl',
32+
/** Rules Commands */
33+
'rules',
34+
/** Pin Command */
35+
'pin','unpin',
36+
/** Purge Command */
37+
'purge',
38+
/** Group Setting Command */
39+
'lock','unlock','title','welcome',
40+
/** General Commands */
41+
'group_stats',
42+
'shahin',
43+
'aran',
44+
] as const;
45+
46+
export type CommandName = (typeof COMMANDS)[number];

src/utils/jsons/blacklist.json

Whitespace-only changes.

src/utils/jsons/botMessages.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"gorup": {
3+
"user": {
4+
"ban": {
5+
"banned": "",
6+
"un_ban": "",
7+
"ban_use_blacklist_message": ""
8+
},
9+
"mute": "",
10+
"warn": ""
11+
},
12+
"join_to_new_group": "",
13+
"new_member_welcome": "Welcome to the group, {name}! Please introduce yourself."
14+
},
15+
"command": {
16+
"link": "Here is the group link: [Group Link]",
17+
"status": "Checking status for {username}. Please wait...",
18+
"time": "Current time: {current_time}",
19+
"date": "Today's date: {current_date}",
20+
"report": "Thank you for reporting the issue! It will be reviewed by the admin team.",
21+
"unreport": "The report has been removed.",
22+
"future": "Please wait for future updates regarding this issue. Thank you for your patience.",
23+
"info": "Here is the information about the group: [Group Info]",
24+
"admins": "Here are the current admins of the group: [Admin List]",
25+
"purge": "Purging messages... This may take a moment.",
26+
"news": "Latest news in the community: [News Updates]",
27+
"lock": "The group is now locked. No new members can join.",
28+
"unlock": "The group is now unlocked. New members can join."
29+
},
30+
"help": {
31+
"general": "I am here to assist you! To see a list of commands, use the `/commands` command in a private chat with the bot."
32+
},
33+
"start": {
34+
"Private": "Welcome to CMCOP!\n I am the dedicated robot and police of Codemodule community.\n Use the /help command to explore my features and commands.",
35+
"gorup": "Hello! What can I do?"
36+
},
37+
"commands": {
38+
"private": "Use this command in a private chat to interact with the bot.",
39+
"public": "This command is only available in private chats. Please use it there."
40+
}
41+
}

0 commit comments

Comments
 (0)