Mohammed Foud commited on
Commit ·
52048a9
1
Parent(s): 66cae89
all
Browse files
src/bots/botManager.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { createLogger } from "../utils/logger";
|
|
| 8 |
import { messageManager } from "./utils/messageManager";
|
| 9 |
import { handleLanguageSelection, handleLanguageChange } from "./handlers/languageHandlers";
|
| 10 |
import { getBotIdFromToken, saveBotTokenMapping, isValidBotToken } from "../utils/botUtils";
|
|
|
|
| 11 |
// import { balanceUpdateService } from "./services/BalanceUpdateService";
|
| 12 |
|
| 13 |
const logger = createLogger('BotManager');
|
|
@@ -42,6 +43,10 @@ export interface BotData {
|
|
| 42 |
crypto_wallet_address: string;
|
| 43 |
admin_contact: string;
|
| 44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
settings: Record<string, any>;
|
| 46 |
state: Record<string, any>;
|
| 47 |
suffix_email: string;
|
|
@@ -86,6 +91,9 @@ export const initializeBot = async (botToken: string, botData?: BotData) => {
|
|
| 86 |
return next();
|
| 87 |
});
|
| 88 |
|
|
|
|
|
|
|
|
|
|
| 89 |
// Setup command handlers
|
| 90 |
setupCommandHandlers(bot);
|
| 91 |
|
|
|
|
| 8 |
import { messageManager } from "./utils/messageManager";
|
| 9 |
import { handleLanguageSelection, handleLanguageChange } from "./handlers/languageHandlers";
|
| 10 |
import { getBotIdFromToken, saveBotTokenMapping, isValidBotToken } from "../utils/botUtils";
|
| 11 |
+
import { groupCheckMiddleware } from "./middleware/groupCheckMiddleware";
|
| 12 |
// import { balanceUpdateService } from "./services/BalanceUpdateService";
|
| 13 |
|
| 14 |
const logger = createLogger('BotManager');
|
|
|
|
| 43 |
crypto_wallet_address: string;
|
| 44 |
admin_contact: string;
|
| 45 |
|
| 46 |
+
// Group Join Settings
|
| 47 |
+
join_group_required: boolean;
|
| 48 |
+
group_channel_username: string;
|
| 49 |
+
|
| 50 |
settings: Record<string, any>;
|
| 51 |
state: Record<string, any>;
|
| 52 |
suffix_email: string;
|
|
|
|
| 91 |
return next();
|
| 92 |
});
|
| 93 |
|
| 94 |
+
// Add group check middleware
|
| 95 |
+
bot.use(groupCheckMiddleware);
|
| 96 |
+
|
| 97 |
// Setup command handlers
|
| 98 |
setupCommandHandlers(bot);
|
| 99 |
|
src/bots/db.sql
CHANGED
|
@@ -131,6 +131,10 @@ CREATE TABLE IF NOT EXISTS public.bots (
|
|
| 131 |
crypto_wallet_address VARCHAR(255),
|
| 132 |
admin_contact VARCHAR(255),
|
| 133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
settings JSONB DEFAULT '{}',
|
| 135 |
state JSONB DEFAULT '{}',
|
| 136 |
suffix_email VARCHAR(255) DEFAULT 'saerosms.com',
|
|
|
|
| 131 |
crypto_wallet_address VARCHAR(255),
|
| 132 |
admin_contact VARCHAR(255),
|
| 133 |
|
| 134 |
+
-- Group Join Settings
|
| 135 |
+
join_group_required BOOLEAN DEFAULT false,
|
| 136 |
+
group_channel_username VARCHAR(255),
|
| 137 |
+
|
| 138 |
settings JSONB DEFAULT '{}',
|
| 139 |
state JSONB DEFAULT '{}',
|
| 140 |
suffix_email VARCHAR(255) DEFAULT 'saerosms.com',
|
src/bots/middleware/groupCheckMiddleware.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { BotContext } from '../types/botTypes';
|
| 2 |
+
import { createLogger } from '../../utils/logger';
|
| 3 |
+
import { messageManager } from '../utils/messageManager';
|
| 4 |
+
|
| 5 |
+
const logger = createLogger('GroupCheckMiddleware');
|
| 6 |
+
|
| 7 |
+
export const groupCheckMiddleware = async (ctx: BotContext, next: () => Promise<void>) => {
|
| 8 |
+
try {
|
| 9 |
+
// Skip check for non-message updates
|
| 10 |
+
if (!ctx.message || !ctx.from) {
|
| 11 |
+
return next();
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
const botData = ctx.botData;
|
| 15 |
+
if (!botData?.join_group_required || !botData?.group_channel_username) {
|
| 16 |
+
return next();
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
// Skip check for admin commands
|
| 20 |
+
if ('text' in ctx.message && ctx.message.text?.startsWith('/')) {
|
| 21 |
+
return next();
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
try {
|
| 25 |
+
// Check if user is a member of the required group
|
| 26 |
+
const chatMember = await ctx.telegram.getChatMember(
|
| 27 |
+
botData.group_channel_username,
|
| 28 |
+
ctx.from.id
|
| 29 |
+
);
|
| 30 |
+
|
| 31 |
+
if (['member', 'administrator', 'creator'].includes(chatMember.status)) {
|
| 32 |
+
return next();
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
// User is not a member of the required group
|
| 36 |
+
const message = messageManager.getMessage('join_group_required');
|
| 37 |
+
|
| 38 |
+
await ctx.reply(message, {
|
| 39 |
+
parse_mode: 'HTML',
|
| 40 |
+
link_preview_options: { is_disabled: true }
|
| 41 |
+
});
|
| 42 |
+
|
| 43 |
+
} catch (error: any) {
|
| 44 |
+
logger.error(`Error checking group membership: ${error.message}`);
|
| 45 |
+
// If there's an error checking membership, allow the user to proceed
|
| 46 |
+
return next();
|
| 47 |
+
}
|
| 48 |
+
} catch (error: any) {
|
| 49 |
+
logger.error(`Error in group check middleware: ${error.message}`);
|
| 50 |
+
return next();
|
| 51 |
+
}
|
| 52 |
+
};
|
src/bots/migrations/add_group_join_settings.sql
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-- Add group join settings columns to bots table
|
| 2 |
+
ALTER TABLE public.bots
|
| 3 |
+
ADD COLUMN IF NOT EXISTS join_group_required BOOLEAN NOT NULL DEFAULT false,
|
| 4 |
+
ADD COLUMN IF NOT EXISTS group_channel_username VARCHAR(255);
|
| 5 |
+
|
| 6 |
+
-- Add comment to explain the columns
|
| 7 |
+
COMMENT ON COLUMN public.bots.join_group_required IS 'Whether users must join a group to use the bot';
|
| 8 |
+
COMMENT ON COLUMN public.bots.group_channel_username IS 'The username of the required group/channel (without @ symbol)';
|
src/bots/utils/messageUtils.ts
CHANGED
|
@@ -187,4 +187,11 @@ export const getAffordableProductsMessage = (balance: number, ctx: BotContext) =
|
|
| 187 |
export const getNoAffordableProductsMessage = (balance: number, ctx: BotContext) => {
|
| 188 |
return messageManager.getMessage('no_affordable_products')
|
| 189 |
.replace('{balance}', formatPrice(ctx, balance));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
};
|
|
|
|
| 187 |
export const getNoAffordableProductsMessage = (balance: number, ctx: BotContext) => {
|
| 188 |
return messageManager.getMessage('no_affordable_products')
|
| 189 |
.replace('{balance}', formatPrice(ctx, balance));
|
| 190 |
+
};
|
| 191 |
+
|
| 192 |
+
export const getJoinGroupRequiredMessage = (group: string) => {
|
| 193 |
+
return {
|
| 194 |
+
ar: `⚠️ يجب عليك الانضمام إلى المجموعة أولاً لاستخدام البوت\n\n📢 انضم إلى المجموعة: @${group}`,
|
| 195 |
+
en: `⚠️ You must join the group first to use the bot\n\n📢 Join the group: @${group}`
|
| 196 |
+
};
|
| 197 |
};
|