Spaces:
Paused
Paused
| import { Telegraf } from "telegraf"; | |
| import { telegrafBots } from "../models"; | |
| import { setupCommandHandlers } from "./handlers/commandHandlers"; | |
| import { setupCallbackHandlers } from "./handlers/index"; | |
| import { BotContext } from "./types/botTypes"; | |
| import { supabase } from "../db/supabase"; | |
| import { createLogger } from "../utils/logger"; | |
| import { messageManager } from "./utils/messageManager"; | |
| import { handleLanguageSelection, handleLanguageChange } from "./handlers/languageHandlers"; | |
| import { getBotIdFromToken, saveBotTokenMapping, isValidBotToken } from "../utils/botUtils"; | |
| import { groupCheckMiddleware } from "./middleware/groupCheckMiddleware"; | |
| // import { balanceUpdateService } from "./services/BalanceUpdateService"; | |
| const logger = createLogger('BotManager'); | |
| export const BotCommands: { command: string; description: string }[] = [ | |
| { command: 'start', description: 'بدء البوت' }, | |
| // { command: 'help', description: 'يعرض قائمة المساعدة' }, | |
| // { command: 'about', description: 'معلومات عن البوت' }, | |
| // { command: 'contact', description: 'تواصل معنا' }, | |
| // { command: 'balance', description: 'رصيدي' }, | |
| { command: 'change_language', description: 'تغيير اللغة / Change language' }, | |
| ]; | |
| // Add this interface to match your database schema | |
| export interface BotData { | |
| id: string; | |
| name: string; | |
| user_id: string; | |
| bot_token: string; | |
| is_active: boolean; | |
| currency: string; | |
| profit_type: 'fix' | 'percentage'; | |
| profit_value_percentage: number; | |
| profit_value_fix: number; | |
| last_activity: string | null; | |
| version: string; | |
| // API Keys and External Service Configuration | |
| fivesim_api_key: string; | |
| paypal_client_id: string; | |
| paypal_client_secret: string; | |
| crypto_wallet_address: string; | |
| admin_contact: string; | |
| // Group Join Settings | |
| join_group_required: boolean; | |
| group_channel_username: string; | |
| settings: Record<string, any>; | |
| state: Record<string, any>; | |
| suffix_email: string; | |
| created_at: string; | |
| updated_at: string; | |
| } | |
| // Update the initializeBot function to use our utilities | |
| export const initializeBot = async (botToken: string, botData?: BotData) => { | |
| try { | |
| // Validate bot token | |
| if (!isValidBotToken(botToken)) { | |
| throw new Error('Invalid bot token format'); | |
| } | |
| const bot = new Telegraf<BotContext>(botToken); | |
| // Extract and save bot ID mapping | |
| const botId = getBotIdFromToken(botToken); | |
| saveBotTokenMapping(botToken, botId); | |
| // Set bot ID and load messages | |
| await messageManager.loadMessages(); | |
| // Set language based on bot settings or default to Arabic | |
| messageManager.setLanguage(botData?.settings?.language || 'ar'); | |
| // Add bot data to context for use in handlers | |
| bot.context.botData = botData || null; | |
| // Setup middleware to track activity | |
| bot.use(async (ctx, next) => { | |
| if (botData?.id) { | |
| // Update last_activity in database | |
| await supabase | |
| .from('bots') | |
| .update({ | |
| last_activity: new Date().toISOString() | |
| }) | |
| .eq('id', botData.id); | |
| } | |
| return next(); | |
| }); | |
| // Add group check middleware | |
| bot.use(groupCheckMiddleware); | |
| // Setup command handlers | |
| setupCommandHandlers(bot); | |
| // Setup callback handlers | |
| setupCallbackHandlers(bot); | |
| // Initialize balance update service and ensure it's properly set up | |
| try { | |
| // balanceUpdateService.setBot(bot); | |
| logger.info('Balance update service initialized successfully'); | |
| } catch (error: any) { | |
| logger.error(`Failed to initialize balance update service: ${error.message}`); | |
| // Continue initialization even if balance service fails | |
| } | |
| // Set bot commands | |
| try { | |
| await bot.telegram.setMyCommands(BotCommands, { | |
| scope: { type: 'default' } | |
| }); | |
| logger.info('Bot commands set successfully'); | |
| } catch (error: any) { | |
| logger.error(`Failed to set bot commands: ${error.message}`); | |
| // Continue initialization even if setting commands fails | |
| } | |
| return { | |
| success: true, | |
| message: botData?.name ? `Bot "${botData.name}" initialized successfully` : "Bot initialized successfully", | |
| bot | |
| }; | |
| } catch (error: any) { | |
| logger.error(`Failed to initialize bot: ${error.message}`); | |
| return { success: false, message: `Failed to initialize bot: ${error.message}` }; | |
| } | |
| }; | |
| // Utility function to update bot status in database | |
| const updateBotStatus = async (botId: string, isActive: boolean, error?: string) => { | |
| try { | |
| await supabase | |
| .from('bots') | |
| .update({ | |
| is_active: isActive, | |
| last_activity: new Date().toISOString(), | |
| state: { | |
| status: isActive ? 'running' : 'error', | |
| startedAt: isActive ? new Date().toISOString() : undefined, | |
| error: error | |
| } | |
| }) | |
| .eq('id', botId); | |
| } catch (error: any) { | |
| logger.error(`Error updating bot status: ${error.message}`); | |
| } | |
| }; | |
| export const stopBot = async (botId: string) => { | |
| try { | |
| // Get bot token from database | |
| const { data: botData, error } = await supabase | |
| .from('bots') | |
| .select('bot_token') | |
| .eq('id', botId) | |
| .single(); | |
| if (error || !botData) { | |
| await updateBotStatus(botId, false, "Bot not found in database"); | |
| return { success: false, message: "Bot not found in database" }; | |
| } | |
| const botToken = botData.bot_token; | |
| const bot = telegrafBots.get(botToken); | |
| if (bot) { | |
| await bot.stop(); | |
| telegrafBots.delete(botToken); | |
| // Update database | |
| await updateBotStatus(botId, false); | |
| return { success: true, message: "Bot stopped successfully" }; | |
| } | |
| // Bot instance not found | |
| await updateBotStatus(botId, false, "Bot instance not found"); | |
| return { success: false, message: "Bot instance not found" }; | |
| } catch (error: any) { | |
| logger.error(`Error stopping bot: ${error.message}`); | |
| await updateBotStatus(botId, false, error.message); | |
| return { success: false, message: `Failed to stop bot: ${error.message}` }; | |
| } | |
| }; | |
| // New function to update bot settings | |
| export const updateBotSettings = async (botId: string, settings: Record<string, any>) => { | |
| try { | |
| // Get bot data from database | |
| const { data: botData, error } = await supabase | |
| .from('bots') | |
| .select('bot_token, settings') | |
| .eq('id', botId) | |
| .single(); | |
| if (error || !botData) { | |
| return { success: false, message: "Bot not found in database" }; | |
| } | |
| // Merge existing settings with new ones | |
| const updatedSettings = { ...(botData.settings || {}), ...settings }; | |
| // Update database | |
| await supabase | |
| .from('bots') | |
| .update({ | |
| settings: updatedSettings, | |
| updated_at: new Date().toISOString() | |
| }) | |
| .eq('id', botId); | |
| // Update running bot if it exists | |
| const bot = telegrafBots.get(botData.bot_token); | |
| if (bot && bot.context) { | |
| bot.context.botData = { | |
| ...(bot.context.botData || {}), | |
| settings: updatedSettings | |
| }; | |
| } | |
| return { success: true, message: "Bot settings updated successfully" }; | |
| } catch (error: any) { | |
| logger.error(`Error updating bot settings: ${error.message}`); | |
| return { success: false, message: `Failed to update bot settings: ${error.message}` }; | |
| } | |
| }; | |