| const fs = require('fs'); |
| const path = require('path'); |
| const { TelegramClient } = require('telegram'); |
| const { StringSession } = require('telegram/sessions'); |
| const { Api } = require('telegram'); |
| const TelegramBot = require('node-telegram-bot-api'); |
| const { Logger } = require('telegram/extensions'); |
| const input = require('input'); |
|
|
| |
| class CustomLogger { |
| constructor(prefix) { |
| this.prefix = prefix; |
| } |
|
|
| log(level, message) { |
| |
| |
| } |
|
|
| error(message) { |
| this.log('ERROR', message); |
| } |
|
|
| warn(message) { |
| this.log('WARN', message); |
| } |
|
|
| info(message) { |
| this.log('INFO', message); |
| } |
|
|
| debug(message) { |
| this.log('DEBUG', message); |
| } |
| } |
|
|
| |
| const BOT_TOKEN = process.env.BOT_TOKEN || '8019149324:AAGBAmRy0M-q6u0FqzREzwDtH-c5V-f9xoM'; |
|
|
| |
| const bot = new TelegramBot(BOT_TOKEN, { polling: true }); |
|
|
| |
| const STATES = { |
| IDLE: 'idle', |
| API_ID: 'api_id', |
| API_HASH: 'api_hash', |
| PHONE: 'phone', |
| CODE: 'code', |
| PASSWORD: 'password' |
| }; |
|
|
| |
| const userSessions = new Map(); |
|
|
| |
| function isValidPhone(phone) { |
| return /^\+\d{10,15}$/.test(phone); |
| } |
|
|
| |
| function createUserSession(userId) { |
| return { |
| userId, |
| state: STATES.IDLE, |
| apiId: null, |
| apiHash: null, |
| phone: null, |
| client: null, |
| sessionName: `aayco_${userId}`, |
| stringSession: null, |
| phoneCodeHash: null |
| }; |
| } |
|
|
| |
| async function cleanupSession(userId) { |
| const session = userSessions.get(userId); |
| if (!session) return; |
| |
| try { |
| if (session.client) { |
| await session.client.disconnect(); |
| } |
| |
| |
| const sessionFile = `${session.sessionName}.session`; |
| if (fs.existsSync(sessionFile)) { |
| fs.unlinkSync(sessionFile); |
| } |
| } catch (error) { |
| console.error(`Error cleaning up session for user ${userId}:`, error); |
| } finally { |
| userSessions.delete(userId); |
| } |
| } |
|
|
| |
| bot.onText(/\/start/, async (msg) => { |
| const userId = msg.from.id; |
| await bot.sendMessage(userId, |
| "π Welcome to the Userbot Session Generator!\n\n" + |
| "Use /pair to start creating your session file.\n" + |
| "Use /cancel at any time to stop the process." |
| ); |
| }); |
|
|
| |
| bot.onText(/\/pair/, async (msg) => { |
| const userId = msg.from.id; |
| |
| |
| if (userSessions.has(userId)) { |
| const existingSession = userSessions.get(userId); |
| if (existingSession.state !== STATES.IDLE) { |
| await bot.sendMessage(userId, |
| "β οΈ You already have an active session process.\n" + |
| "Complete or /cancel it before starting a new one." |
| ); |
| return; |
| } |
| } |
| |
| |
| const session = createUserSession(userId); |
| session.state = STATES.API_ID; |
| userSessions.set(userId, session); |
| |
| await bot.sendMessage(userId, |
| "π Let's create your userbot session.\n" + |
| "Please provide your **API ID** (a number from my.telegram.org):\n" + |
| "Example: 1234567" |
| ); |
| }); |
|
|
| |
| bot.onText(/\/cancel/, async (msg) => { |
| const userId = msg.from.id; |
| |
| if (userSessions.has(userId)) { |
| await cleanupSession(userId); |
| await bot.sendMessage(userId, "π Session creation cancelled."); |
| } else { |
| await bot.sendMessage(userId, "There's no active session to cancel."); |
| } |
| }); |
|
|
| |
| bot.on('message', async (msg) => { |
| if (msg.text && msg.text.startsWith('/')) return; |
| |
| const userId = msg.from.id; |
| const text = msg.text?.trim(); |
| |
| if (!userSessions.has(userId) || !text) return; |
| |
| const session = userSessions.get(userId); |
| |
| try { |
| switch (session.state) { |
| case STATES.API_ID: |
| await handleApiId(userId, text); |
| break; |
| case STATES.API_HASH: |
| await handleApiHash(userId, text); |
| break; |
| case STATES.PHONE: |
| await handlePhone(userId, text); |
| break; |
| case STATES.CODE: |
| await handleCode(userId, text); |
| break; |
| case STATES.PASSWORD: |
| await handlePassword(userId, text); |
| break; |
| } |
| } catch (error) { |
| console.error(`Error handling message for user ${userId}:`, error); |
| await bot.sendMessage(userId, |
| `β οΈ An error occurred: ${error.message}\n` + |
| "Please try again with /pair." |
| ); |
| await cleanupSession(userId); |
| } |
| }); |
|
|
| |
| async function handleApiId(userId, text) { |
| if (!text.match(/^\d+$/)) { |
| await bot.sendMessage(userId, |
| "β API ID must be a number.\n" + |
| "Please send a valid **API ID**:" |
| ); |
| return; |
| } |
| |
| const session = userSessions.get(userId); |
| session.apiId = parseInt(text, 10); |
| session.state = STATES.API_HASH; |
| |
| await bot.sendMessage(userId, |
| "β
API ID received.\n" + |
| "Now provide your **API Hash** (a string from my.telegram.org):\n" + |
| "Example: abcdef1234567890abcdef1234567890" |
| ); |
| } |
|
|
| |
| async function handleApiHash(userId, text) { |
| if (text.length < 32) { |
| await bot.sendMessage(userId, |
| "β API Hash must be at least 32 characters long.\n" + |
| "Please send a valid **API Hash**:" |
| ); |
| return; |
| } |
| |
| const session = userSessions.get(userId); |
| session.apiHash = text; |
| session.state = STATES.PHONE; |
| |
| await bot.sendMessage(userId, |
| "β
API Hash received.\n" + |
| "Now provide your **phone number** (with country code):\n" + |
| "Example: +12025550123" |
| ); |
| } |
|
|
| |
| async function handlePhone(userId, phone) { |
| if (!isValidPhone(phone)) { |
| await bot.sendMessage(userId, |
| "β Invalid phone number format.\n" + |
| "Please send a valid phone number (e.g., +12025550123):" |
| ); |
| return; |
| } |
| |
| const session = userSessions.get(userId); |
| session.phone = phone; |
| |
| try { |
| |
| const stringSession = new StringSession(""); |
| |
| |
| const client = new TelegramClient( |
| stringSession, |
| session.apiId, |
| session.apiHash, |
| { |
| connectionRetries: 5, |
| baseLogger: new CustomLogger('GramJS'), |
| useWSS: false, |
| autoReconnect: true |
| } |
| ); |
| |
| session.client = client; |
| |
| |
| await client.connect(); |
| const result = await client.invoke( |
| new Api.auth.SendCode({ |
| phoneNumber: session.phone, |
| apiId: session.apiId, |
| apiHash: session.apiHash, |
| settings: new Api.CodeSettings({}) |
| }) |
| ); |
| |
| session.phoneCodeHash = result.phoneCodeHash; |
| session.state = STATES.CODE; |
| |
| await bot.sendMessage(userId, |
| "β
Code request sent to your phone.\n" + |
| "Please enter the verification code you received:" |
| ); |
| } catch (error) { |
| console.error('Error in handlePhone:', error); |
| let errorMessage = error.message; |
| |
| if (error.errorMessage === 'PHONE_NUMBER_INVALID') { |
| errorMessage = "The phone number is invalid. Please check and try again."; |
| } else if (error.errorMessage === 'PHONE_NUMBER_BANNED') { |
| errorMessage = "This phone number is banned from Telegram."; |
| } else if (error.errorMessage.includes('FLOOD')) { |
| errorMessage = "Too many attempts. Please wait before trying again."; |
| } |
| |
| await bot.sendMessage(userId, |
| `β Error sending code: ${errorMessage}\n` + |
| "Please try again with /pair or contact support." |
| ); |
| await cleanupSession(userId); |
| } |
| } |
|
|
| |
| async function handleCode(userId, code) { |
| if (!code.match(/^\d+$/)) { |
| await bot.sendMessage(userId, |
| "β Code must be a number.\n" + |
| "Please enter the verification code:" |
| ); |
| return; |
| } |
| |
| const session = userSessions.get(userId); |
| |
| try { |
| |
| const result = await session.client.invoke( |
| new Api.auth.SignIn({ |
| phoneNumber: session.phone, |
| phoneCodeHash: session.phoneCodeHash, |
| phoneCode: code |
| }) |
| ); |
| |
| if (result._ === 'auth.authorizationSignUpRequired') { |
| throw new Error("This phone number is not registered. Please sign up first."); |
| } |
| |
| await finishSession(userId); |
| } catch (error) { |
| console.error('Error in handleCode:', error); |
| |
| if (error.errorMessage === "SESSION_PASSWORD_NEEDED") { |
| session.state = STATES.PASSWORD; |
| await bot.sendMessage(userId, |
| "π Your account has two-factor authentication enabled.\n" + |
| "Please enter your 2FA password:" |
| ); |
| } else { |
| let errorMessage = error.message; |
| |
| if (error.errorMessage === 'PHONE_CODE_INVALID') { |
| errorMessage = "The verification code is invalid."; |
| } else if (error.errorMessage === 'PHONE_CODE_EXPIRED') { |
| errorMessage = "The verification code has expired. Please request a new one."; |
| } |
| |
| await bot.sendMessage(userId, |
| `β Sign-in failed: ${errorMessage}\n` + |
| "Please try again with /pair." |
| ); |
| await cleanupSession(userId); |
| } |
| } |
| } |
|
|
| |
| async function handlePassword(userId, password) { |
| const session = userSessions.get(userId); |
| |
| try { |
| |
| await session.client.invoke( |
| new Api.auth.CheckPassword({ |
| password: password |
| }) |
| ); |
| |
| await finishSession(userId); |
| } catch (error) { |
| console.error('Error in handlePassword:', error); |
| let errorMessage = error.message; |
| |
| if (error.errorMessage === 'PASSWORD_HASH_INVALID') { |
| errorMessage = "The 2FA password is incorrect."; |
| } |
| |
| await bot.sendMessage(userId, |
| `β 2FA authentication failed: ${errorMessage}\n` + |
| "Please try again with /pair." |
| ); |
| await cleanupSession(userId); |
| } |
| } |
|
|
| |
| async function finishSession(userId) { |
| const session = userSessions.get(userId); |
| |
| try { |
| await bot.sendMessage(userId, |
| "π Successfully signed in!\n" + |
| "Generating your session file..." |
| ); |
| |
| const sessionString = session.client.session.save(); |
| const sessionFile = `aayco_${userId}.session`; |
| fs.writeFileSync(sessionFile, sessionString); |
| |
| await bot.sendDocument(userId, sessionFile, { |
| caption: "Here's your session file for your userbot. Keep it safe!", |
| filename: 'aayco.session' |
| }); |
| |
| await cleanupSession(userId); |
| } catch (error) { |
| console.error('Error in finishSession:', error); |
| await bot.sendMessage(userId, |
| `β Error creating session file: ${error.message}\n` + |
| "Please try again with /pair." |
| ); |
| await cleanupSession(userId); |
| } |
| } |
|
|
| |
| console.log("Starting bot..."); |
|
|
| |
| bot.on('polling_error', (error) => { |
| console.error('Polling error:', error); |
| }); |
|
|
| process.on('unhandledRejection', (reason, promise) => { |
| console.error('Unhandled Rejection at:', promise, 'reason:', reason); |
| }); |
|
|
| |
| process.on('SIGINT', async () => { |
| console.log('Shutting down...'); |
| |
| for (const [userId, session] of userSessions.entries()) { |
| try { |
| await cleanupSession(userId); |
| } catch (error) { |
| console.error(`Error cleaning up session for user ${userId}:`, error); |
| } |
| } |
| |
| bot.stopPolling(); |
| process.exit(0); |
| }); |