Skip to content

Commit a89fc31

Browse files
committed
feat(group-settings): implement welcome message management and warnings system
- Added functionality to manage group welcome messages: - Retrieve (`getWelcomeMessage`), set (`setWelcomeMessage`), and remove (`removeWelcomeMessage`) welcome messages for groups. - Introduced warnings management system: - Warn users (`warnUser`) with reasons and track warnings per user and group. - Remove warnings (`removeWarn`) for users. - Retrieve warnings count for a specific user (`getUserWarnById`). - Generate a detailed group warning report (`getAllWarns`) with structured output. - Integrated services (`ServiceProvider`) for database interaction: - Group, user, and warning services provide core data handling. - Ensured proper validation using `AdminValidationService` for context validation.
1 parent b275c8f commit a89fc31

2 files changed

Lines changed: 235 additions & 0 deletions

File tree

src/bot/service/admin/Warn.ts

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import { Context } from 'grammy';
2+
import { AdminValidationService } from './validation';
3+
import { ServiceProvider } from '../../../service/database/ServiceProvider';
4+
5+
export class WarnService {
6+
static async warnUser(ctx: Context): Promise<{
7+
warningApplied: boolean;
8+
isWarningLimitReached: boolean;
9+
warnings: number;
10+
}> {
11+
const validationResult = await AdminValidationService.validateContext(ctx);
12+
if (!validationResult) {
13+
return {
14+
warningApplied: false,
15+
isWarningLimitReached: false,
16+
warnings: 0,
17+
};
18+
}
19+
const { groupId, userId } = validationResult;
20+
const services = ServiceProvider.getInstance();
21+
const input = ctx.message?.text!.split(/\s+/).slice(1);
22+
const reason = input!.join('')?.toLowerCase() || 'reason is not set for warning';
23+
const [groupService, userService, warnService] = await Promise.all([services.getGroupService(), services.getUserService(), services.getWarnsService()]);
24+
let group = await groupService.getByGroupId(groupId);
25+
let user = await userService.getByTelegramId(userId);
26+
const userData = { first_name: ctx!.message?.reply_to_message?.from?.first_name!, id: userId, username: ctx.message?.reply_to_message?.from?.username! };
27+
if (!user) {
28+
user = await userService.save(userData);
29+
}
30+
if (!group) {
31+
group = await groupService.save(ctx);
32+
}
33+
let warn = await warnService.getByGroupId(groupId);
34+
if (!warn) {
35+
warn = await warnService.save(group.id, user.id, reason);
36+
}
37+
38+
const warningsGroup = [...group.warnings.map(Number)];
39+
if (!warningsGroup.includes(+user.telegram_id)) {
40+
warningsGroup.push(+user.telegram_id);
41+
}
42+
// Remove the user from the group's approved_users and members arrays
43+
const updatedGroup = {
44+
...group,
45+
warnings: warningsGroup,
46+
};
47+
const updatedUser = {
48+
...user,
49+
warnings: Number(user.warnings) + 1, // Increment user warnings
50+
};
51+
const updatedWarning = {
52+
...warn,
53+
reason: reason,
54+
};
55+
if (updatedUser.warnings >= 3) {
56+
// Reset the warnings count and clear the user from the group's warning list
57+
const updatedGroup = {
58+
...group,
59+
warnings: group.warnings.filter((id) => Number(id) !== Number(user.telegram_id)),
60+
};
61+
const updatedUser = {
62+
...user,
63+
warnings: 0,
64+
};
65+
await warnService.delete(warn.id);
66+
await Promise.all([groupService.update(updatedGroup), userService.update(updatedUser)]);
67+
return {
68+
warningApplied: true,
69+
isWarningLimitReached: true,
70+
warnings: 0,
71+
};
72+
}
73+
await Promise.all([groupService.update(updatedGroup), userService.update(updatedUser), warnService.update(updatedWarning)]);
74+
return {
75+
warningApplied: true,
76+
isWarningLimitReached: false,
77+
warnings: updatedUser.warnings,
78+
};
79+
}
80+
static async removeWarn(ctx: Context): Promise<{ warningRemoved: boolean; warnings: number }> {
81+
const validationResult = await AdminValidationService.validateContext(ctx);
82+
if (!validationResult) {
83+
return { warningRemoved: false, warnings: 0 };
84+
}
85+
86+
const { groupId, userId } = validationResult;
87+
const services = ServiceProvider.getInstance();
88+
const [groupService, userService] = await Promise.all([services.getGroupService(), services.getUserService()]);
89+
let group = await groupService.getByGroupId(groupId);
90+
let user = await userService.getByTelegramId(userId);
91+
const userData = { first_name: ctx!.message?.reply_to_message?.from?.first_name!, id: userId, username: ctx.message?.reply_to_message?.from?.username! };
92+
if (!user) {
93+
user = await userService.save(userData);
94+
}
95+
if (!group) {
96+
group = await groupService.save(ctx);
97+
}
98+
const updatedUser = {
99+
...user,
100+
warnings: user.warnings - 1,
101+
};
102+
await userService.update(updatedUser);
103+
return {
104+
warningRemoved: true,
105+
warnings: updatedUser.warnings,
106+
};
107+
}
108+
static async getUserWarnById(ctx: Context): Promise<{ warnings: number }> {
109+
const validationResult = await AdminValidationService.validateContext(ctx);
110+
if (!validationResult) {
111+
return { warnings: 0 };
112+
}
113+
114+
const { userId } = validationResult;
115+
const services = ServiceProvider.getInstance();
116+
const userService = await services.getUserService();
117+
let user = await userService.getByTelegramId(userId);
118+
let replyMessage = ctx.message?.reply_to_message?.from;
119+
const userData = { first_name: replyMessage?.first_name!, id: userId, username: replyMessage?.username! };
120+
if (!user) {
121+
user = await userService.save(userData);
122+
}
123+
124+
return { warnings: user.warnings };
125+
}
126+
static async getAllWarns(ctx: Context): Promise<string> {
127+
const replyMessage = ctx.from;
128+
// Ensure the user ID of the replied message is valid
129+
const userId = replyMessage!.id!;
130+
const chat = ctx.chat;
131+
const groupId = chat?.id!;
132+
const services = ServiceProvider.getInstance();
133+
const [groupService, userService, warnService] = await Promise.all([services.getGroupService(), services.getUserService(), services.getWarnsService()]);
134+
let group = await groupService.getByGroupId(groupId);
135+
let user = await userService.getByTelegramId(userId);
136+
const userData = { first_name: ctx!.message?.reply_to_message?.from?.first_name!, id: userId, username: ctx.message?.reply_to_message?.from?.username! };
137+
if (!user) {
138+
user = await userService.save(userData);
139+
}
140+
if (!group) {
141+
group = await groupService.save(ctx);
142+
}
143+
let warn = await warnService.getByGroupId(groupId);
144+
if (!warn) {
145+
warn = await warnService.save(group.id, user.id, 'The reason for the warning is not specified');
146+
}
147+
// Get all users from the group's warning list
148+
const usersWithWarnings: { first_name: string; userId: string; warnings: number; reason: string }[] = [];
149+
for (const userId of group.warnings) {
150+
const user = await userService.getByTelegramId(userId);
151+
if (user) {
152+
const reason = warn.reason;
153+
usersWithWarnings.push({
154+
first_name: user.first_name,
155+
userId: `${user.telegram_id}`,
156+
warnings: user.warnings,
157+
reason: reason || 'No specific reason provided',
158+
});
159+
}
160+
}
161+
162+
// Generate structured output
163+
let output = `**Group Warning Report**\n`;
164+
output += `Group ID: ${groupId}\n\n`;
165+
output += `**Users with Warnings:**\n`;
166+
167+
usersWithWarnings.forEach((user, index) => {
168+
output += `\n${index + 1}. Name: ${user.first_name}\n`;
169+
output += ` User ID: ${user.userId}\n`;
170+
output += ` Warnings: ${user.warnings}\n`;
171+
output += ` Reason: ${user.reason}\n`;
172+
});
173+
174+
// Add summary
175+
output += `\n---\nTotal Users with Warnings: ${usersWithWarnings.length}\n`;
176+
177+
return output;
178+
}
179+
}

src/bot/service/admin/Welcome.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { Context } from 'grammy';
2+
import { ServiceProvider } from '../../../service/database/ServiceProvider';
3+
import { Group } from '../../../types/database/TablesTypes';
4+
export class GroupSettingsService {
5+
static async getWelcomeMessage(ctx: Context, welcomeContent: string): Promise<Group['welcome_message']> {
6+
const { groupService } = await GroupSettingsService.getServices();
7+
const groupId = ctx.chat?.id!;
8+
let group = await groupService.getByGroupId(groupId);
9+
if (!group) {
10+
group = await groupService.save(ctx);
11+
}
12+
return group.welcome_message;
13+
}
14+
static async removeWelcomeMessage(ctx: Context): Promise<string> {
15+
const { groupService } = await GroupSettingsService.getServices();
16+
const groupId = ctx.chat?.id!;
17+
18+
// Get the group by its ID
19+
let group = await groupService.getByGroupId(groupId);
20+
if (!group) {
21+
// If no group exists, create a new one
22+
group = await groupService.save(ctx);
23+
}
24+
25+
// Remove the welcome message (set it to an empty string or null)
26+
const updatedGroup = await groupService.update({
27+
...group,
28+
welcome_message: '',
29+
});
30+
31+
return updatedGroup.welcome_message ? updatedGroup.welcome_message : 'The welcome message has been removed.';
32+
}
33+
static async setWelcomeMessage(ctx: Context, welcomeContent: string): Promise<string> {
34+
const { groupService } = await GroupSettingsService.getServices();
35+
const groupId = ctx.chat?.id!;
36+
// Get the group by its ID
37+
let group = await groupService.getByGroupId(groupId);
38+
if (!group) {
39+
// If no group exists, create a new one
40+
group = await groupService.save(ctx);
41+
}
42+
// Update the welcome message
43+
const updatedGroup = await groupService.update({
44+
...group,
45+
welcome_message: welcomeContent,
46+
});
47+
return updatedGroup.welcome_message;
48+
}
49+
private static async getServices() {
50+
const service = ServiceProvider.getInstance();
51+
const groupService = await service.getGroupService();
52+
return {
53+
groupService,
54+
};
55+
}
56+
}

0 commit comments

Comments
 (0)