├── Procfile ├── heroku.yml ├── bot ├── helpers │ ├── bindb.py │ ├── commands.py │ ├── dcutil.py │ ├── guard.py │ ├── logger.py │ ├── defend.py │ ├── utils.py │ ├── pgbar.py │ ├── security.py │ ├── graph.py │ ├── buttons.py │ └── botutils.py ├── SmartCookies │ └── SmartUtilBot.txt ├── core │ ├── mongo.py │ └── database.py ├── __init__.py ├── modules │ ├── privacy.py │ ├── ytag.py │ ├── start.py │ ├── help.py │ ├── yth.py │ ├── spl.py │ ├── sptxt.py │ ├── gra.py │ ├── cyrptx.py │ ├── ss.py │ ├── topbn.py │ ├── syn.py │ ├── ai.py │ ├── bin.py │ ├── fake.py │ ├── speedtest.py │ ├── audio.py │ ├── getusr.py │ ├── voice.py │ ├── dmn.py │ ├── crypt.py │ ├── m2t.py │ ├── decoders.py │ ├── enh.py │ ├── rembg.py │ ├── vnote.py │ ├── binmd.py │ ├── mbin.py │ ├── pron.py │ └── dep.py └── __main__.py ├── start.sh ├── docker-compose.yml ├── requirements.txt ├── Dockerfile ├── .env ├── config.py └── app.json /Procfile: -------------------------------------------------------------------------------- 1 | worker: bash start.sh 2 | -------------------------------------------------------------------------------- /heroku.yml: -------------------------------------------------------------------------------- 1 | build: 2 | docker: 3 | web: Dockerfile 4 | 5 | run: 6 | worker: python3 -m bot 7 | -------------------------------------------------------------------------------- /bot/helpers/bindb.py: -------------------------------------------------------------------------------- 1 | #Copyright @ISmartCoder 2 | #Updates Channel @abirxdhackz 3 | from smartbindb import SmartBinDB 4 | 5 | smartdb = SmartBinDB() -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | python3 -m bot -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | smartutilbot: 3 | build: . 4 | container_name: smartutilbot 5 | ports: 6 | - "8000:8000" 7 | env_file: 8 | - .env 9 | volumes: 10 | - .:/app 11 | -------------------------------------------------------------------------------- /bot/SmartCookies/SmartUtilBot.txt: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | # Netscape HTTP Cookie File Keep Here -------------------------------------------------------------------------------- /bot/helpers/commands.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from config import COMMAND_PREFIX 5 | 6 | BotCommands = COMMAND_PREFIX -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pyrofork 2 | tgcrypto 3 | aiogram 4 | google-generativeai 5 | aiohttp 6 | telethon 7 | cryptg 8 | pytz 9 | telegraph 10 | pycountry 11 | beautifulsoup4 12 | Pillow 13 | yt-dlp 14 | python-dateutil 15 | motor 16 | aiofiles 17 | python-dotenv 18 | psutil 19 | pydub 20 | speedtest-cli 21 | py-yt-search 22 | lxml 23 | smartfaker 24 | smartbindb 25 | qrcode 26 | reportlab 27 | pypdf -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | 5 | FROM python:3.9-slim-buster 6 | 7 | RUN apt update && apt install -y git curl ffmpeg && apt clean 8 | 9 | WORKDIR /app 10 | 11 | COPY requirements.txt . 12 | RUN pip install --no-cache-dir -r requirements.txt 13 | 14 | COPY . . 15 | 16 | RUN chmod +x start.sh 17 | 18 | EXPOSE 8000 19 | 20 | CMD ["bash", "start.sh"] 21 | -------------------------------------------------------------------------------- /bot/helpers/dcutil.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | def SmartDCLocate(): 5 | return { 6 | 1: "MIA, Miami, USA, US", 7 | 2: "AMS, Amsterdam, Netherlands, NL", 8 | 3: "MBA, Mumbai, India, IN", 9 | 4: "STO, Stockholm, Sweden, SE", 10 | 5: "SIN, Singapore, SG", 11 | 6: "LHR, London, United Kingdom, GB", 12 | 7: "FRA, Frankfurt, Germany, DE", 13 | 8: "JFK, New York, USA, US", 14 | 9: "HKG, Hong Kong, HK", 15 | 10: "TYO, Tokyo, Japan, JP", 16 | 11: "SYD, Sydney, Australia, AU", 17 | 12: "GRU, São Paulo, Brazil, BR", 18 | 13: "DXB, Dubai, UAE, AE", 19 | 14: "CDG, Paris, France, FR", 20 | 15: "ICN, Seoul, South Korea, KR", 21 | 22 | } 23 | -------------------------------------------------------------------------------- /bot/helpers/guard.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from aiogram import Bot 5 | from aiogram.types import Message 6 | from bot.core.database import SmartGuards 7 | from bot.helpers.logger import LOGGER 8 | from config import OWNER_ID 9 | 10 | def admin_only(func): 11 | async def wrapper(message: Message, bot: Bot): 12 | user_id = message.from_user.id 13 | auth_admins_data = await SmartGuards.find({}, {"user_id": 1, "_id": 0}).to_list(None) 14 | AUTH_ADMIN_IDS = [admin["user_id"] for admin in auth_admins_data] 15 | if user_id != OWNER_ID and user_id not in AUTH_ADMIN_IDS: 16 | LOGGER.info(f"Unauthorized settings access attempt by user_id {user_id}") 17 | return 18 | return await func(message, bot) 19 | return wrapper -------------------------------------------------------------------------------- /bot/helpers/logger.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import logging 5 | from logging.handlers import RotatingFileHandler 6 | 7 | logging.basicConfig( 8 | level=logging.INFO, 9 | format="%(asctime)s - %(levelname)s - %(message)s", 10 | datefmt='%Y-%m-%d %H:%M:%S', 11 | handlers=[ 12 | RotatingFileHandler( 13 | "botlog.txt", 14 | maxBytes=50000000, 15 | backupCount=10 16 | ), 17 | logging.StreamHandler() 18 | ] 19 | ) 20 | 21 | logging.getLogger("aiogram").setLevel(logging.ERROR) 22 | logging.getLogger("pyrogram").setLevel(logging.ERROR) 23 | logging.getLogger("telethon").setLevel(logging.ERROR) 24 | logging.getLogger("aiohttp").setLevel(logging.ERROR) 25 | logging.getLogger("apscheduler").setLevel(logging.ERROR) 26 | 27 | LOGGER = logging.getLogger(__name__) -------------------------------------------------------------------------------- /bot/core/mongo.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from motor.motor_asyncio import AsyncIOMotorClient 5 | from urllib.parse import urlparse, parse_qs 6 | from bot.helpers.logger import LOGGER 7 | from config import MONGO_URL 8 | 9 | LOGGER.info("Creating MONGO_CLIENT From MONGO_URL") 10 | 11 | try: 12 | parsed = urlparse(MONGO_URL) 13 | query_params = parse_qs(parsed.query) 14 | db_name = query_params.get("appName", [None])[0] 15 | 16 | if not db_name: 17 | raise ValueError("No database name found in MONGO_URL (missing 'appName' query param)") 18 | 19 | MONGO_CLIENT = AsyncIOMotorClient(MONGO_URL) 20 | db = MONGO_CLIENT.get_database(db_name) 21 | SmartUsers = db["user_activity"] 22 | 23 | LOGGER.info(f"MONGO_CLIENT Created Successfully!") 24 | except Exception as e: 25 | LOGGER.error(f"Failed to create MONGO_CLIENT: {e}") 26 | raise 27 | -------------------------------------------------------------------------------- /bot/helpers/defend.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from aiogram import Bot 5 | from aiogram.types import Message 6 | from .security import SmartShield 7 | from bot.core.database import SmartSecurity 8 | from .logger import LOGGER 9 | from .notify import Smart_Notify 10 | 11 | def SmartDefender(func): 12 | async def wrapper(message: Message, bot: Bot): 13 | try: 14 | if await SmartSecurity.find_one({"user_id": message.from_user.id}): 15 | await SmartShield(bot, message.from_user.id, message) 16 | return 17 | return await func(message, bot) 18 | except Exception as e: 19 | await Smart_Notify(bot, "SmartDefender", e, message) 20 | LOGGER.error(f"Error in SmartDefender for user {message.from_user.id}: {e}") 21 | await SmartShield(bot, message.from_user.id, message) 22 | return wrapper -------------------------------------------------------------------------------- /bot/helpers/utils.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import asyncio 5 | import functools 6 | import os 7 | from bot.helpers.logger import LOGGER 8 | 9 | def new_task(func): 10 | async def wrapper(message, bot, **kwargs): 11 | try: 12 | task = asyncio.create_task(func(message, bot)) 13 | task.add_done_callback(lambda t: t.exception() and LOGGER.error(f"{func.__name__} failed: {t.exception()}")) 14 | except Exception as e: 15 | LOGGER.error(f"new_task error in {func.__name__}: {e}") 16 | return wrapper 17 | 18 | def clean_download(*files): 19 | for file in files: 20 | try: 21 | if os.path.exists(file): 22 | os.remove(file) 23 | LOGGER.info(f"Removed temporary file {file}") 24 | except Exception as e: 25 | LOGGER.error(f"clean_download error for {file}: {e}") -------------------------------------------------------------------------------- /bot/core/database.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from motor.motor_asyncio import AsyncIOMotorClient 5 | from urllib.parse import urlparse, parse_qs 6 | from config import DATABASE_URL 7 | from bot.helpers.logger import LOGGER 8 | 9 | LOGGER.info("Creating Database Client From DATABASE_URL") 10 | try: 11 | parsed = urlparse(DATABASE_URL) 12 | query_params = parse_qs(parsed.query) 13 | db_name = query_params.get("appName", [None])[0] 14 | if not db_name: 15 | raise ValueError("No database name found in DATABASE_URL (missing 'appName' query param)") 16 | mongo_client = AsyncIOMotorClient(DATABASE_URL) 17 | db = mongo_client.get_database(db_name) 18 | SmartGuards = db["SmartGuards"] 19 | SmartSecurity = db["SmartSecurity"] 20 | SmartReboot = db["SmartReboot"] 21 | LOGGER.info(f"Database Client Created Successfully!") 22 | except Exception as e: 23 | LOGGER.error(f"Database Client Create Error: {e}") 24 | raise -------------------------------------------------------------------------------- /bot/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import asyncio 5 | import logging 6 | from config import BOT_TOKEN, API_ID, API_HASH, SESSION_STRING 7 | from bot.helpers.logger import LOGGER 8 | from aiogram import Bot, Dispatcher 9 | from aiogram.client.default import DefaultBotProperties 10 | from aiogram.enums import ParseMode 11 | from pyrogram import Client 12 | 13 | logging.basicConfig(level=logging.INFO) 14 | 15 | LOGGER.info("Creating Bot Client From BOT_TOKEN") 16 | SmartAIO = Bot( 17 | token=BOT_TOKEN, 18 | default=DefaultBotProperties(parse_mode=ParseMode.HTML) 19 | ) 20 | dp = Dispatcher() 21 | SmartPyro = Client( 22 | name="SmartUtilBot", 23 | api_id=API_ID, 24 | api_hash=API_HASH, 25 | bot_token=BOT_TOKEN 26 | ) 27 | LOGGER.info("Creating User Client From SESSION_STRING") 28 | SmartUserBot = Client( 29 | "SmartUser", 30 | api_id=API_ID, 31 | api_hash=API_HASH, 32 | session_string=SESSION_STRING, 33 | workers=10 34 | ) 35 | LOGGER.info("User Client Created Successfully !") 36 | LOGGER.info("Bot Client Created Successfully!") 37 | 38 | __all__ = ["SmartAIO", "dp", "SmartPyro", "SmartUserBot"] 39 | -------------------------------------------------------------------------------- /bot/helpers/pgbar.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import time 5 | from .logger import LOGGER 6 | 7 | async def progress_bar(current, total, status_message, start_time, last_update_time): 8 | elapsed_time = time.time() - start_time 9 | percentage = (current / total) * 100 10 | progress = f"{'▓' * int(percentage // 5)}{'░' * (20 - int(percentage // 5))}" 11 | speed = current / elapsed_time / 1024 / 1024 12 | uploaded = current / 1024 / 1024 13 | total_size = total / 1024 / 1024 14 | 15 | if time.time() - last_update_time[0] < 1: 16 | return 17 | last_update_time[0] = time.time() 18 | 19 | text = ( 20 | f"Smart Upload Progress Bar ✅\n" 21 | f"━━━━━━━━━━━━━━━━━\n" 22 | f"{progress}\n" 23 | f"Percentage: {percentage:.2f}%\n" 24 | f"Speed: {speed:.2f} MB/s\n" 25 | f"Status: {uploaded:.2f} MB of {total_size:.2f} MB\n" 26 | f"━━━━━━━━━━━━━━━━━\n" 27 | f"Smooth Transfer → Activated ✅" 28 | ) 29 | try: 30 | await status_message.edit_text(text, parse_mode="HTML") 31 | except Exception as e: 32 | LOGGER.error(f"Error updating progress: {e}") -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | 5 | API_ID=YOUR_API_ID 6 | API_HASH=YOUR_API_HASH 7 | BOT_TOKEN=YOUR_BOT_TOKEN 8 | SESSION_STRING=YOUR_SESSION_STRING 9 | OWNER_ID=YOUR_OWNER_ID 10 | DEVELOPER_USER_ID=YOUR_USER_ID 11 | MONGO_URL=YOUR_MONGO_URL 12 | DATABASE_URL=YOUR_DATABASE_URL 13 | OPENAI_API_KEY=YOUR_OPENAI_API_KEY 14 | REPLICATE_API_TOKEN=YOUR_REPLICATE_API_TOKEN 15 | GOOGLE_API_KEY=YOUR_GROK_API_KEY 16 | TRANS_API_KEY=YOUR_TRANS_API_KEY 17 | OCR_API_KEY=YOUR_OCR_API_KEY 18 | MODEL_NAME=gemini-2.0-flash 19 | CC_SCRAPPER_LIMIT=5000 20 | SUDO_CCSCR_LIMIT=10000 21 | MULTI_CCSCR_LIMIT=2000 22 | MAIL_SCR_LIMIT=10000 23 | SUDO_MAILSCR_LIMIT=15000 24 | CC_GEN_LIMIT=2000 25 | MULTI_CCGEN_LIMIT=5000 26 | TEXT_MODEL=deepseek-r1-distill-llama-70b 27 | GROQ_API_URL=https://api.groq.com/openai/v1/chat/completions 28 | GROQ_API_KEY=YOUR_GROK_API_KEY 29 | A360APIBASEURL=https://a360api-c8fbf2fa3cda.herokuapp.com 30 | UPDATE_CHANNEL_URL=t.me/TheSmartDev 31 | LOG_CHANNEL_ID=-1002735511721 32 | COMMAND_PREFIX=!|.|#|,|/ 33 | DOMAIN_CHK_LIMIT=20 34 | PROXY_CHECK_LIMIT=20 35 | IMGAI_SIZE_LIMIT=5242880 36 | MAX_TXT_SIZE=15728640 37 | MAX_VIDEO_SIZE=2147483648 38 | YT_COOKIES_PATH=bot/SmartCookies/SmartUtilBot.txt 39 | VIDEO_RESOLUTION=1280x720 40 | IMAGE_UPLOAD_KEY=YOUR_IMAGE_UPLOAD_KEY 41 | IPINFO_API_TOKEN=YOUR_IPINFO_API_TOKEN 42 | WEB_SS_KEY=YOUR_WEB_SS_KEY 43 | -------------------------------------------------------------------------------- /bot/helpers/security.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from aiogram import Bot 5 | from aiogram.types import Message 6 | from .buttons import SmartButtons 7 | from .botutils import send_message 8 | from .logger import LOGGER 9 | from .notify import Smart_Notify 10 | from pyrogram.enums import ParseMode as SmartParseMode 11 | from config import OWNER_ID 12 | 13 | async def SmartShield(bot: Bot, chat_id: int, message: Message = None): 14 | try: 15 | buttons = SmartButtons() 16 | buttons.button(text="Contact Owner 👨🏻‍💻", url=f"tg://user?id={OWNER_ID}") 17 | reply_markup = buttons.build_menu(b_cols=1) 18 | ban_message = ( 19 | "❌ Sorry Bro You're Banned From Using Me\n" 20 | "━━━━━━━━━━━━━━━━━━━━━━\n" 21 | "You're Currently Banned From Using Me Or My Services.\n" 22 | "If you believe this was a mistake or want to appeal, \n" 23 | "please contact the admin. 🚨\n" 24 | "━━━━━━━━━━━━━━━━━━━━━━\n" 25 | "Note: NSFW Work Can Cause Forever Ban ✅" 26 | ) 27 | await send_message( 28 | chat_id=chat_id, 29 | text=ban_message, 30 | parse_mode=SmartParseMode.HTML, 31 | reply_markup=reply_markup 32 | ) 33 | except Exception as e: 34 | await Smart_Notify(bot, "SmartShield", e, message) 35 | LOGGER.error(f"Error sending ban message to {chat_id}: {e}") -------------------------------------------------------------------------------- /bot/helpers/graph.py: -------------------------------------------------------------------------------- 1 | from telegraph import Telegraph 2 | from bot.helpers.logger import LOGGER 3 | import asyncio 4 | 5 | class SmartGraph: 6 | def __init__(self): 7 | self.telegraph = Telegraph() 8 | self.max_retries = 5 9 | self.retry_delay = 1 10 | self.initialized = False 11 | 12 | async def initialize(self): 13 | if self.initialized: 14 | return True 15 | for attempt in range(self.max_retries): 16 | try: 17 | response = self.telegraph.create_account( 18 | short_name="SmartUtilBot", 19 | author_name="SmartUtilBot", 20 | author_url="https://t.me/abirxdhackz" 21 | ) 22 | LOGGER.info(f"HTTP Request: POST https://api.graph.org/createAccount/ \"HTTP/1.1 200 OK\"") 23 | self.initialized = True 24 | return True 25 | except Exception as e: 26 | LOGGER.error(f"HTTP Request: POST https://api.graph.org/createAccount/ \"HTTP/1.1 500 Failed\": {e}") 27 | if attempt < self.max_retries - 1: 28 | await asyncio.sleep(self.retry_delay) 29 | continue 30 | LOGGER.error("Failed to create or access Telegraph account after maximum retries") 31 | self.initialized = False 32 | return False 33 | 34 | async def create_page(self, title, content, author_name="SmartUtilBot", author_url="https://t.me/abirxdhackz"): 35 | if not self.initialized: 36 | if not await self.initialize(): 37 | return None 38 | for attempt in range(self.max_retries): 39 | try: 40 | safe_content = content.replace('<', '<').replace('>', '>') 41 | page = self.telegraph.create_page( 42 | title=title, 43 | html_content=f'
{safe_content}
', 44 | author_name=author_name, 45 | author_url=author_url 46 | ) 47 | LOGGER.info(f"HTTP Request: POST https://api.graph.org/createPage/ \"HTTP/1.1 200 OK\"") 48 | return page['url'].replace('telegra.ph', 'graph.org') 49 | except Exception as e: 50 | LOGGER.error(f"HTTP Request: POST https://api.graph.org/createPage/ \"HTTP/1.1 500 Failed\": {e}") 51 | if attempt < self.max_retries - 1: 52 | await asyncio.sleep(self.retry_delay) 53 | continue 54 | LOGGER.error("Failed to create Telegraph page after maximum retries") 55 | return None -------------------------------------------------------------------------------- /bot/modules/privacy.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from aiogram import Bot 5 | from aiogram.filters import Command 6 | from aiogram.types import Message, CallbackQuery 7 | from aiogram.enums import ParseMode 8 | from bot import dp 9 | from bot.helpers.buttons import SmartButtons 10 | from bot.helpers.botutils import send_message 11 | from bot.helpers.commands import BotCommands 12 | from bot.helpers.logger import LOGGER 13 | from bot.helpers.defend import SmartDefender 14 | 15 | privacy_text = ( 16 | "📜 Privacy Policy for Smart Util Bot\n\n" 17 | "Welcome to Smart Util Bot. By using our services, you agree to this privacy policy.\n\n" 18 | "1. Information We Collect:\n" 19 | " - Personal Information: User ID and username for personalization.\n" 20 | " - Usage Data: Information on how you use the app to improve our services.\n\n" 21 | "2. Usage of Information:\n" 22 | " - Service Enhancement: To provide and improve Smart Util.\n" 23 | " - Communication: Updates and new features.\n" 24 | " - Security: To prevent unauthorized access.\n" 25 | " - Advertisements: Display of promotions.\n\n" 26 | "3. Data Security:\n" 27 | " - These tools do not store any data, ensuring your privacy.\n" 28 | " - We use strong security measures, although no system is 100% secure.\n\n" 29 | "Thank you for using Smart Util Bot. We prioritize your privacy and security." 30 | ) 31 | 32 | @dp.message(Command(commands=["privacy"], prefix=BotCommands)) 33 | @SmartDefender 34 | async def privacy_command(message: Message, bot: Bot): 35 | LOGGER.info(f"Received command: '{message.text}' from user {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 36 | buttons = SmartButtons() 37 | buttons.button(text="Close ❌", callback_data="close_privacy") 38 | reply_markup = buttons.build_menu(b_cols=1, h_cols=1, f_cols=1) 39 | try: 40 | await send_message( 41 | chat_id=message.chat.id, 42 | text=privacy_text, 43 | parse_mode=ParseMode.HTML, 44 | reply_markup=reply_markup 45 | ) 46 | LOGGER.info(f"Successfully sent privacy message to chat {message.chat.id}") 47 | except Exception as e: 48 | LOGGER.error(f"Failed to send privacy message to chat {message.chat.id}: {e}") 49 | 50 | @dp.callback_query(lambda c: c.data == "close_privacy") 51 | @SmartDefender 52 | async def handle_close_privacy_callback(callback_query: CallbackQuery, bot: Bot): 53 | try: 54 | await callback_query.message.delete() 55 | LOGGER.info(f"Successfully deleted privacy message for user {callback_query.from_user.id} in chat {callback_query.message.chat.id}") 56 | except Exception as e: 57 | LOGGER.error(f"Failed to delete privacy message for user {callback_query.from_user.id} in chat {callback_query.message.chat.id}: {e}") -------------------------------------------------------------------------------- /bot/modules/ytag.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import aiohttp 5 | from aiogram import Bot 6 | from aiogram.filters import Command 7 | from aiogram.types import Message 8 | from aiogram.enums import ParseMode, ChatType 9 | from bot import dp, SmartAIO 10 | from bot.helpers.utils import new_task, clean_download 11 | from bot.helpers.botutils import send_message, delete_messages 12 | from bot.helpers.notify import Smart_Notify 13 | from bot.helpers.logger import LOGGER 14 | from bot.helpers.buttons import SmartButtons 15 | from bot.helpers.commands import BotCommands 16 | from bot.helpers.defend import SmartDefender 17 | from config import A360APIBASEURL 18 | 19 | logger = LOGGER 20 | 21 | @dp.message(Command(commands=["ytag"], prefix=BotCommands)) 22 | @new_task 23 | @SmartDefender 24 | async def ytag(message: Message, bot: Bot): 25 | if message.chat.type not in [ChatType.PRIVATE, ChatType.GROUP, ChatType.SUPERGROUP]: 26 | await send_message( 27 | chat_id=message.chat.id, 28 | text="❌ This command only works in private or group chats", 29 | parse_mode=ParseMode.HTML 30 | ) 31 | return 32 | if len(message.text.split()) < 2: 33 | await send_message( 34 | chat_id=message.chat.id, 35 | text="❌ Please provide a YouTube URL. Usage: /ytag [URL]", 36 | parse_mode=ParseMode.HTML 37 | ) 38 | return 39 | url = message.text.split()[1].strip() 40 | fetching_msg = await send_message( 41 | chat_id=message.chat.id, 42 | text="Processing Your Request...", 43 | parse_mode=ParseMode.HTML 44 | ) 45 | try: 46 | api_url = f"{A360APIBASEURL}/yt/dl?url={url}" 47 | async with aiohttp.ClientSession() as session: 48 | async with session.get(api_url) as resp: 49 | if resp.status != 200: 50 | raise Exception(f"API returned status {resp.status}") 51 | data = await resp.json() 52 | tags = data.get("tags", []) 53 | if not tags: 54 | response = "Sorry, no tags available for this video." 55 | else: 56 | tags_str = "\n".join([f"{tag}" for tag in tags]) 57 | response = f"Your Requested Video Tags ✅\n━━━━━━━━━━━━━━━━\n{tags_str}" 58 | await SmartAIO.edit_message_text( 59 | chat_id=message.chat.id, 60 | message_id=fetching_msg.message_id, 61 | text=response, 62 | parse_mode=ParseMode.HTML, 63 | disable_web_page_preview=True 64 | ) 65 | except Exception as e: 66 | await SmartAIO.edit_message_text( 67 | chat_id=message.chat.id, 68 | message_id=fetching_msg.message_id, 69 | text="Sorry Bro YouTube Tags API Dead", 70 | parse_mode=ParseMode.HTML, 71 | disable_web_page_preview=True 72 | ) 73 | await Smart_Notify(bot, "/ytag", e, message) -------------------------------------------------------------------------------- /bot/helpers/buttons.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CopyTextButton 5 | from bot.helpers.logger import LOGGER 6 | 7 | class SmartButtons: 8 | def __init__(self): 9 | self._button = [] 10 | self._header_button = [] 11 | self._footer_button = [] 12 | 13 | def button(self, text, callback_data=None, url=None, pay=None, web_app=None, login_url=None, 14 | switch_inline_query=None, switch_inline_query_current_chat=None, 15 | switch_inline_query_chosen_chat=None, copy_text=None, callback_game=None, position=None): 16 | kwargs = {} 17 | if callback_data is not None: 18 | kwargs["callback_data"] = callback_data 19 | if url is not None: 20 | kwargs["url"] = url 21 | if pay is not None: 22 | kwargs["pay"] = pay 23 | if web_app is not None: 24 | kwargs["web_app"] = web_app 25 | if login_url is not None: 26 | kwargs["login_url"] = login_url 27 | if switch_inline_query is not None: 28 | kwargs["switch_inline_query"] = switch_inline_query 29 | if switch_inline_query_current_chat is not None: 30 | kwargs["switch_inline_query_current_chat"] = switch_inline_query_current_chat 31 | if switch_inline_query_chosen_chat is not None: 32 | kwargs["switch_inline_query_chosen_chat"] = switch_inline_query_chosen_chat 33 | if copy_text is not None: 34 | if isinstance(copy_text, str): 35 | kwargs["copy_text"] = CopyTextButton(text=copy_text) 36 | else: 37 | kwargs["copy_text"] = copy_text 38 | if callback_game is not None: 39 | kwargs["callback_game"] = callback_game 40 | 41 | try: 42 | button = InlineKeyboardButton(text=text, **kwargs) 43 | except Exception as e: 44 | LOGGER.error(f"Failed to create InlineKeyboardButton: {e}") 45 | raise 46 | 47 | if not position: 48 | self._button.append(button) 49 | elif position == "header": 50 | self._header_button.append(button) 51 | elif position == "footer": 52 | self._footer_button.append(button) 53 | 54 | def build_menu(self, b_cols=1, h_cols=8, f_cols=8): 55 | menu = [self._button[i:i + b_cols] for i in range(0, len(self._button), b_cols)] 56 | if self._header_button: 57 | h_cnt = len(self._header_button) 58 | if h_cnt > h_cols: 59 | header_buttons = [self._header_button[i:i + h_cols] for i in range(0, len(self._header_button), h_cols)] 60 | menu = header_buttons + menu 61 | else: 62 | menu.insert(0, self._header_button) 63 | if self._footer_button: 64 | if len(self._footer_button) > f_cols: 65 | [menu.append(self._footer_button[i:i + f_cols]) for i in range(0, len(self._footer_button), f_cols)] 66 | else: 67 | menu.append(self._footer_button) 68 | return InlineKeyboardMarkup(inline_keyboard=menu) 69 | 70 | def reset(self): 71 | self._button = [] 72 | self._header_button = [] 73 | self._footer_button = [] 74 | -------------------------------------------------------------------------------- /bot/__main__.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import logging 3 | import os 4 | from bot import SmartAIO, dp, SmartPyro, SmartUserBot 5 | from bot.core.database import SmartReboot 6 | from bot.helpers.logger import LOGGER 7 | from bot.misc.callback import handle_callback_query 8 | from importlib import import_module 9 | 10 | async def main(): 11 | try: 12 | modules_path = "bot.modules" 13 | modules_dir = os.path.join(os.path.dirname(__file__), "modules") 14 | for filename in os.listdir(modules_dir): 15 | if filename.endswith(".py") and filename != "__init__.py": 16 | module_name = filename[:-3] 17 | try: 18 | import_module(f"{modules_path}.{module_name}") 19 | except Exception as e: 20 | LOGGER.error(f"Failed to load module {module_name}: {e}") 21 | 22 | dp.callback_query.register(handle_callback_query) 23 | 24 | await SmartPyro.start() 25 | await SmartUserBot.start() 26 | 27 | LOGGER.info("Bot Successfully Started 💥") 28 | 29 | restart_data = await SmartReboot.find_one() 30 | if restart_data: 31 | try: 32 | await SmartAIO.edit_message_text( 33 | chat_id=restart_data["chat_id"], 34 | message_id=restart_data["msg_id"], 35 | text="Restarted Successfully 💥", 36 | parse_mode="HTML" 37 | ) 38 | await SmartReboot.delete_one({"_id": restart_data["_id"]}) 39 | 40 | except Exception as e: 41 | LOGGER.error(f"Failed to update restart message: {e}") 42 | 43 | try: 44 | await SmartAIO.delete_webhook(drop_pending_updates=True) 45 | 46 | except Exception as e: 47 | LOGGER.warning(f"Could not clear webhook: {e}") 48 | 49 | await asyncio.sleep(1) 50 | 51 | await dp.start_polling( 52 | SmartAIO, 53 | drop_pending_updates=True, 54 | allowed_updates=dp.resolve_used_update_types(), 55 | handle_signals=False 56 | ) 57 | 58 | except asyncio.CancelledError: 59 | LOGGER.info("Polling cancelled, shutting down...") 60 | raise 61 | except Exception as e: 62 | LOGGER.error(f"Main loop failed: {e}") 63 | raise 64 | 65 | async def cleanup(): 66 | try: 67 | await SmartPyro.stop() 68 | LOGGER.info("Terminated SmartPyro session") 69 | except Exception as e: 70 | LOGGER.error(f"Failed to stop SmartPyro: {e}") 71 | 72 | try: 73 | await SmartUserBot.stop() 74 | LOGGER.info("Terminated SmartUserBot session") 75 | except Exception as e: 76 | LOGGER.error(f"Failed to stop SmartUserBot: {e}") 77 | 78 | try: 79 | await SmartAIO.session.close() 80 | LOGGER.info("Closed SmartAIO session") 81 | except Exception as e: 82 | LOGGER.error(f"Failed to close SmartAIO session: {e}") 83 | 84 | if __name__ == "__main__": 85 | logging.basicConfig(level=logging.INFO) 86 | loop = asyncio.get_event_loop() 87 | try: 88 | loop.run_until_complete(main()) 89 | except KeyboardInterrupt: 90 | LOGGER.info("Stop signal received. Shutting down...") 91 | try: 92 | loop.run_until_complete(cleanup()) 93 | except Exception as e: 94 | LOGGER.error(f"Failed to terminate sessions: {e}") 95 | finally: 96 | if not loop.is_closed(): 97 | loop.close() -------------------------------------------------------------------------------- /bot/modules/start.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import asyncio 5 | from bot import dp 6 | from config import UPDATE_CHANNEL_URL 7 | from bot.helpers.botutils import send_message, delete_messages 8 | from bot.helpers.buttons import SmartButtons 9 | from bot.helpers.commands import BotCommands 10 | from bot.helpers.defend import SmartDefender 11 | from aiogram import Bot 12 | from aiogram.filters import Command, CommandStart 13 | from aiogram.types import Message 14 | from aiogram.enums import ChatType 15 | 16 | @dp.message(CommandStart()) 17 | @dp.message(Command(commands=["start"], prefix=BotCommands)) 18 | @SmartDefender 19 | async def start_command_handler(message: Message, bot: Bot): 20 | chat_id = message.chat.id 21 | 22 | animation_message = await send_message( 23 | chat_id=chat_id, 24 | text="Starting The Smart-Util bot..." 25 | ) 26 | if not animation_message: 27 | return 28 | 29 | await asyncio.sleep(0.2) 30 | await animation_message.edit_text("Getting session keys wait...") 31 | await asyncio.sleep(0.2) 32 | await delete_messages(chat_id=chat_id, message_ids=animation_message.message_id) 33 | 34 | buttons = SmartButtons() 35 | buttons.button(text="⚙️ Main Menu", callback_data="main_menu", position="header") 36 | buttons.button(text="ℹ️ About Me", callback_data="about_me") 37 | buttons.button(text="📄 Policy & Terms", callback_data="policy_terms") 38 | reply_markup = buttons.build_menu(b_cols=2, h_cols=1, f_cols=1) 39 | 40 | if message.chat.type == ChatType.PRIVATE: 41 | full_name = "User" 42 | if message.from_user: 43 | full_name = f"{message.from_user.first_name or ''} {message.from_user.last_name or ''}".strip() 44 | response_text = ( 45 | f"Hi {full_name}! Welcome To This Bot\n" 46 | "━━━━━━━━━━━━━━━━━━━━━\n" 47 | "Smart Util is your ultimate toolkit on Telegram, packed with AI tools, " 48 | "educational resources, downloaders, temp mail, crypto utilities, and more. " 49 | "Simplify your tasks with ease!\n" 50 | "━━━━━━━━━━━━━━━━━━━━━\n" 51 | f"Don't forget to join here for updates!" 52 | ) 53 | else: 54 | group_name = message.chat.title or "this group" 55 | if message.from_user: 56 | full_name = f"{message.from_user.first_name or ''} {message.from_user.last_name or ''}".strip() 57 | response_text = ( 58 | f"Hi {full_name}! Welcome To This Bot\n" 59 | "━━━━━━━━━━━━━━━━━━━━━\n" 60 | "Smart Util is your ultimate toolkit on Telegram, packed with AI tools, " 61 | "educational resources, downloaders, temp mail, crypto utilities, and more. " 62 | "Simplify your tasks with ease!\n" 63 | "━━━━━━━━━━━━━━━━━━━━━\n" 64 | f"Don't forget to join here for updates!" 65 | ) 66 | else: 67 | response_text = ( 68 | f"Hi{group_name} Welcome To This Bot\n" 69 | "━━━━━━━━━━━━━━━━━━━━━\n" 70 | "Smart Util is your ultimate toolkit on Telegram, packed with AI tools, " 71 | "educational resources, downloaders, temp mail, crypto utilities, and more. " 72 | "Simplify your tasks with ease!\n" 73 | "━━━━━━━━━━━━━━━━━━━━━\n" 74 | f"Don't forget to join here for updates!" 75 | ) 76 | 77 | await send_message( 78 | chat_id=chat_id, 79 | text=response_text, 80 | reply_markup=reply_markup, 81 | disable_web_page_preview=True 82 | ) 83 | -------------------------------------------------------------------------------- /bot/modules/help.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from aiogram import Bot 5 | from bot import dp 6 | from config import UPDATE_CHANNEL_URL 7 | from bot.helpers.botutils import send_message 8 | from bot.helpers.buttons import SmartButtons 9 | from bot.helpers.commands import BotCommands 10 | from bot.helpers.logger import LOGGER 11 | from bot.helpers.notify import Smart_Notify 12 | from bot.helpers.utils import new_task 13 | from bot.helpers.defend import SmartDefender 14 | from aiogram.filters import Command 15 | from aiogram.types import Message 16 | from aiogram.enums import ChatType 17 | 18 | @dp.message(Command(commands=["help", "cmds"], prefix=BotCommands)) 19 | @new_task 20 | @SmartDefender 21 | async def help_command_handler(message: Message, bot: Bot): 22 | LOGGER.info(f"Received command: '{message.text}' from user {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 23 | chat_id = message.chat.id 24 | 25 | buttons = SmartButtons() 26 | buttons.button(text="⚙️ Main Menu", callback_data="main_menu", position="header") 27 | buttons.button(text="ℹ️ About Me", callback_data="about_me") 28 | buttons.button(text="📄 Policy & Terms", callback_data="policy_terms") 29 | reply_markup = buttons.build_menu(b_cols=2, h_cols=1, f_cols=1) 30 | 31 | if message.chat.type == ChatType.PRIVATE: 32 | full_name = "User" 33 | if message.from_user: 34 | full_name = f"{message.from_user.first_name or ''} {message.from_user.last_name or ''}".strip() 35 | 36 | response_text = ( 37 | f"Hi {full_name}! Welcome To This Bot\n" 38 | "━━━━━━━━━━━━━━━━━━━━━\n" 39 | "Smart Util is your ultimate toolkit on Telegram, packed with AI tools, " 40 | "educational resources, downloaders, temp mail, crypto utilities, and more. " 41 | "Simplify your tasks with ease!\n" 42 | "━━━━━━━━━━━━━━━━━━━━━\n" 43 | f"Don't forget to join here for updates!" 44 | ) 45 | else: 46 | group_name = message.chat.title or "this group" 47 | if message.from_user: 48 | full_name = f"{message.from_user.first_name or ''} {message.from_user.last_name or ''}".strip() 49 | response_text = ( 50 | f"Hi {full_name}! Welcome To This Bot\n" 51 | "━━━━━━━━━━━━━━━━━━━━━\n" 52 | "Smart Util is your ultimate toolkit on Telegram, packed with AI tools, " 53 | "educational resources, downloaders, temp mail, crypto utilities, and more. " 54 | "Simplify your tasks with ease!\n" 55 | "━━━━━━━━━━━━━━━━━━━━━\n" 56 | f"Don't forget to join here for updates!" 57 | ) 58 | else: 59 | response_text = ( 60 | f"Hi {group_name} Welcome To This Bot\n" 61 | "━━━━━━━━━━━━━━━━━━━━━\n" 62 | "Smart Util is your ultimate toolkit on Telegram, packed with AI tools, " 63 | "educational resources, downloaders, temp mail, crypto utilities, and more. " 64 | "Simplify your tasks with ease!\n" 65 | "━━━━━━━━━━━━━━━━━━━━━\n" 66 | f"Don't forget to join here for updates!" 67 | ) 68 | 69 | try: 70 | await send_message( 71 | chat_id=chat_id, 72 | text=response_text, 73 | reply_markup=reply_markup, 74 | disable_web_page_preview=True 75 | ) 76 | LOGGER.info(f"Successfully sent help message to chat {chat_id}") 77 | except Exception as e: 78 | LOGGER.error(f"Failed to send help message to chat {chat_id}: {e}") 79 | await Smart_Notify(bot, "help", e, message) 80 | await send_message( 81 | chat_id=chat_id, 82 | text="❌ Sorry, an error occurred while processing the help command", 83 | parse_mode=ParseMode.HTML 84 | ) 85 | LOGGER.info(f"Sent error message to chat {chat_id}") -------------------------------------------------------------------------------- /bot/helpers/botutils.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from bot import SmartAIO 5 | from bot.helpers.logger import LOGGER 6 | from aiogram.types import Message 7 | from aiogram.enums import ParseMode 8 | from aiogram.types import InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply 9 | from aiogram.types import MessageEntity, LinkPreviewOptions, ReplyParameters, SuggestedPostParameters 10 | 11 | async def send_message( 12 | chat_id: int | str, 13 | text: str, 14 | parse_mode: str | None = ParseMode.HTML, 15 | reply_markup: InlineKeyboardMarkup | ReplyKeyboardMarkup | ReplyKeyboardRemove | ForceReply | None = None, 16 | reply_to_message_id: int | None = None, 17 | disable_web_page_preview: bool | None = False, 18 | business_connection_id: str | None = None, 19 | message_thread_id: int | None = None, 20 | direct_messages_topic_id: int | None = None, 21 | entities: list[MessageEntity] | None = None, 22 | link_preview_options: LinkPreviewOptions | None = None, 23 | disable_notification: bool | None = None, 24 | protect_content: bool | None = None, 25 | allow_paid_broadcast: bool | None = None, 26 | message_effect_id: str | None = None, 27 | suggested_post_parameters: SuggestedPostParameters | None = None, 28 | reply_parameters: ReplyParameters | None = None, 29 | allow_sending_without_reply: bool | None = None 30 | ): 31 | try: 32 | return await SmartAIO.send_message( 33 | chat_id=chat_id, 34 | text=text, 35 | parse_mode=parse_mode, 36 | reply_markup=reply_markup, 37 | reply_to_message_id=reply_to_message_id, 38 | disable_web_page_preview=disable_web_page_preview, 39 | business_connection_id=business_connection_id, 40 | message_thread_id=message_thread_id, 41 | direct_messages_topic_id=direct_messages_topic_id, 42 | entities=entities, 43 | link_preview_options=link_preview_options, 44 | disable_notification=disable_notification, 45 | protect_content=protect_content, 46 | allow_paid_broadcast=allow_paid_broadcast, 47 | message_effect_id=message_effect_id, 48 | suggested_post_parameters=suggested_post_parameters, 49 | reply_parameters=reply_parameters, 50 | allow_sending_without_reply=allow_sending_without_reply 51 | ) 52 | except Exception as e: 53 | LOGGER.error(f"Failed to send message to {chat_id}: {e}") 54 | return None 55 | 56 | def get_args(message: Message): 57 | if not message.text: 58 | return [] 59 | text = message.text.split(None, 1) 60 | if len(text) < 2: 61 | return [] 62 | args = text[1].strip() 63 | if not args: 64 | return [] 65 | result = [] 66 | current = "" 67 | in_quotes = False 68 | quote_char = None 69 | i = 0 70 | while i < len(args): 71 | char = args[i] 72 | if char in ('"', "'") and (i == 0 or args[i-1] != '\\'): 73 | if in_quotes and char == quote_char: 74 | in_quotes = False 75 | quote_char = None 76 | if current: 77 | result.append(current) 78 | current = "" 79 | else: 80 | in_quotes = True 81 | quote_char = char 82 | elif char == ' ' and not in_quotes: 83 | if current: 84 | result.append(current) 85 | current = "" 86 | else: 87 | current += char 88 | i += 1 89 | if current: 90 | result.append(current) 91 | return result 92 | 93 | async def delete_messages(chat_id, message_ids): 94 | try: 95 | if isinstance(message_ids, int): 96 | message_ids = [message_ids] 97 | await SmartAIO.delete_messages(chat_id=chat_id, message_ids=message_ids) 98 | LOGGER.info(f"Deleted messages {message_ids} in chat {chat_id}") 99 | return True 100 | except Exception as e: 101 | LOGGER.error(f"Failed to delete messages {message_ids} in chat {chat_id}: {e}") 102 | return False -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import os 5 | from dotenv import load_dotenv 6 | 7 | load_dotenv() 8 | 9 | def get_env_or_default(key, default=None, cast_func=str): 10 | value = os.getenv(key) 11 | if value is not None and value.strip() != "": 12 | try: 13 | return cast_func(value) 14 | except (ValueError, TypeError) as e: 15 | print(f"Error casting {key} with value '{value}' to {cast_func.__name__}: {e}") 16 | return default 17 | return default 18 | 19 | API_ID = get_env_or_default("API_ID", "Your_API_ID_Here") 20 | API_HASH = get_env_or_default("API_HASH", "Your_API_HASH_Here") 21 | BOT_TOKEN = get_env_or_default("BOT_TOKEN", "Your_BOT_TOKEN_Here") 22 | SESSION_STRING = get_env_or_default("SESSION_STRING", "Your_SESSION_STRING_Here") 23 | OWNER_ID = get_env_or_default("OWNER_ID", "Your_OWNER_ID_Here", int) 24 | DEVELOPER_USER_ID = get_env_or_default("DEVELOPER_USER_ID", "Your_DEVELOPER_USER_ID_Here", int) 25 | MONGO_URL = get_env_or_default("MONGO_URL", "Your_MONGO_URL_Here") 26 | DATABASE_URL = get_env_or_default("DATABASE_URL", "Your_DATABASE_URL_Here") 27 | OPENAI_API_KEY = get_env_or_default("OPENAI_API_KEY", "Your_OPENAI_API_KEY_Here") 28 | REPLICATE_API_TOKEN = get_env_or_default("REPLICATE_API_TOKEN", "Your_REPLICATE_API_TOKEN_Here") 29 | GOOGLE_API_KEY = get_env_or_default("GOOGLE_API_KEY", "Your_GOOGLE_API_KEY_Here") 30 | OCR_API_KEY = get_env_or_default("OCR_API_KEY", "Your_OCR_API_KEY_Here") 31 | TRANS_API_KEY = get_env_or_default("TRANS_API_KEY", "Your_TRANS_API_KEY_Here") 32 | MODEL_NAME = get_env_or_default("MODEL_NAME", "gemini-2.0-flash") 33 | CC_SCRAPPER_LIMIT = get_env_or_default("CC_SCRAPPER_LIMIT", 5000, int) 34 | SUDO_CCSCR_LIMIT = get_env_or_default("SUDO_CCSCR_LIMIT", 10000, int) 35 | MULTI_CCSCR_LIMIT = get_env_or_default("MULTI_CCSCR_LIMIT", 2000, int) 36 | MAIL_SCR_LIMIT = get_env_or_default("MAIL_SCR_LIMIT", 10000, int) 37 | SUDO_MAILSCR_LIMIT = get_env_or_default("SUDO_MAILSCR_LIMIT", 15000, int) 38 | CC_GEN_LIMIT = get_env_or_default("CC_GEN_LIMIT", 2000, int) 39 | MULTI_CCGEN_LIMIT = get_env_or_default("MULTI_CCGEN_LIMIT", 5000, int) 40 | A360APIBASEURL = get_env_or_default("A360APIBASEURL", "https://a360api-c8fbf2fa3cda.herokuapp.com") 41 | GROQ_API_KEY = get_env_or_default("GROQ_API_KEY", "Your_GROQ_API_KEY_Here") 42 | WEB_SS_KEY = get_env_or_default("WEB_SS_KEY", "Your_WEB_SS_KEY_Here") 43 | IMAGE_UPLOAD_KEY = get_env_or_default("IMAGE_UPLOAD_KEY", "Your_IMAGE_UPLOAD_KEY_Here") 44 | GROQ_API_URL = get_env_or_default("GROQ_API_URL", "https://api.groq.com/openai/v1/chat/completions") 45 | TEXT_MODEL = get_env_or_default("TEXT_MODEL", "deepseek-r1-distill-llama-70b") 46 | IPINFO_API_TOKEN = get_env_or_default("IPINFO_API_TOKEN", "Your_IPINFO_API_TOKEN_Here") 47 | raw_prefixes = get_env_or_default("COMMAND_PREFIX", "!|.|#|,|/") 48 | COMMAND_PREFIX = [prefix.strip() for prefix in raw_prefixes.split("|") if prefix.strip()] 49 | UPDATE_CHANNEL_URL = get_env_or_default("UPDATE_CHANNEL_URL", "https://t.me/TheSmartDev") 50 | LOG_CHANNEL_ID = get_env_or_default("LOG_CHANNEL_ID", "-1002735511721") 51 | IMGAI_SIZE_LIMIT = get_env_or_default("IMGAI_SIZE_LIMIT", 5242880, int) 52 | MAX_TXT_SIZE = get_env_or_default("MAX_TXT_SIZE", 15728640, int) 53 | MAX_VIDEO_SIZE = get_env_or_default("MAX_VIDEO_SIZE", 2147483648, int) 54 | YT_COOKIES_PATH = get_env_or_default("YT_COOKIES_PATH", "bot/SmartCookies/SmartUtilBot.txt") 55 | VIDEO_RESOLUTION = get_env_or_default("VIDEO_RESOLUTION", "1280x720", lambda x: tuple(map(int, x.split('x')))) 56 | DOMAIN_CHK_LIMIT = get_env_or_default("DOMAIN_CHK_LIMIT", 20, int) 57 | PROXY_CHECK_LIMIT = get_env_or_default("PROXY_CHECK_LIMIT", 20, int) 58 | 59 | required_vars = { 60 | "API_ID": API_ID, 61 | "API_HASH": API_HASH, 62 | "BOT_TOKEN": BOT_TOKEN, 63 | "SESSION_STRING": SESSION_STRING, 64 | "OWNER_ID": OWNER_ID, 65 | "DEVELOPER_USER_ID": DEVELOPER_USER_ID, 66 | "MONGO_URL": MONGO_URL, 67 | "DATABASE_URL": DATABASE_URL 68 | } 69 | 70 | for var_name, var_value in required_vars.items(): 71 | if var_value is None or var_value == f"Your_{var_name}_Here" or (isinstance(var_value, str) and var_value.strip() == ""): 72 | raise ValueError(f"Required variable {var_name} is missing or invalid. Set it in .env (VPS), config.py (VPS), or Heroku config vars.") 73 | 74 | if not COMMAND_PREFIX: 75 | raise ValueError("No command prefixes found. Set COMMAND_PREFIX in .env, config.py, or Heroku config vars.") -------------------------------------------------------------------------------- /bot/modules/yth.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import aiohttp 5 | import re 6 | import os 7 | from aiogram import Bot 8 | from aiogram.filters import Command 9 | from aiogram.types import Message, FSInputFile 10 | from aiogram.enums import ParseMode, ChatType 11 | from bot import dp, SmartAIO 12 | from bot.helpers.utils import new_task, clean_download 13 | from bot.helpers.botutils import send_message, delete_messages 14 | from bot.helpers.notify import Smart_Notify 15 | from bot.helpers.logger import LOGGER 16 | from bot.helpers.buttons import SmartButtons 17 | from bot.helpers.commands import BotCommands 18 | from bot.helpers.defend import SmartDefender 19 | from config import A360APIBASEURL 20 | 21 | logger = LOGGER 22 | 23 | def youtube_parser(url): 24 | reg_exp = r"(?:youtube\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)|.*[?&]v=)|youtu\.be/)([^\"&?/ ]{11})" 25 | try: 26 | match = re.search(reg_exp, url) 27 | return match.group(1) if match else False 28 | except Exception as e: 29 | return False 30 | 31 | @dp.message(Command(commands=["yth"], prefix=BotCommands)) 32 | @new_task 33 | @SmartDefender 34 | async def yth(message: Message, bot: Bot): 35 | if message.chat.type not in [ChatType.PRIVATE, ChatType.GROUP, ChatType.SUPERGROUP]: 36 | await send_message( 37 | chat_id=message.chat.id, 38 | text="❌ This command only works in private or group chats", 39 | parse_mode=ParseMode.HTML 40 | ) 41 | return 42 | if len(message.text.split()) < 2: 43 | await send_message( 44 | chat_id=message.chat.id, 45 | text="❌ Provide a Valid YouTube link", 46 | parse_mode=ParseMode.HTML 47 | ) 48 | return 49 | youtube_url = message.text.split()[1].strip() 50 | fetching_msg = await send_message( 51 | chat_id=message.chat.id, 52 | text="Fetching YouTube thumbnail...✨", 53 | parse_mode=ParseMode.HTML 54 | ) 55 | try: 56 | video_id = youtube_parser(youtube_url) 57 | if not video_id: 58 | await SmartAIO.edit_message_text( 59 | chat_id=message.chat.id, 60 | message_id=fetching_msg.message_id, 61 | text="Invalid YouTube link Bro ❌", 62 | parse_mode=ParseMode.HTML 63 | ) 64 | return 65 | api_url = f"{A360APIBASEURL}/yt/dl?url={youtube_url}" 66 | async with aiohttp.ClientSession() as session: 67 | async with session.get(api_url) as resp: 68 | if resp.status != 200: 69 | raise Exception(f"API returned status {resp.status}") 70 | data = await resp.json() 71 | thumbnail_url = data.get("thumbnail") 72 | if not thumbnail_url: 73 | await SmartAIO.edit_message_text( 74 | chat_id=message.chat.id, 75 | message_id=fetching_msg.message_id, 76 | text="No thumbnail available for this video ❌", 77 | parse_mode=ParseMode.HTML 78 | ) 79 | return 80 | os.makedirs("./downloads", exist_ok=True) 81 | file_path = f"./downloads/thumbnail_{video_id}.jpg" 82 | async with aiohttp.ClientSession() as session: 83 | async with session.get(thumbnail_url) as resp: 84 | if resp.status != 200: 85 | raise Exception(f"Failed to download thumbnail: status {resp.status}") 86 | with open(file_path, "wb") as f: 87 | f.write(await resp.read()) 88 | await bot.send_photo( 89 | chat_id=message.chat.id, 90 | photo=FSInputFile(file_path), 91 | caption="Photo Sent", 92 | parse_mode=ParseMode.HTML 93 | ) 94 | await SmartAIO.delete_message( 95 | chat_id=message.chat.id, 96 | message_id=fetching_msg.message_id 97 | ) 98 | clean_download(file_path) 99 | except Exception as e: 100 | await SmartAIO.edit_message_text( 101 | chat_id=message.chat.id, 102 | message_id=fetching_msg.message_id, 103 | text="Sorry Bro YouTube Thumbnail API Dead", 104 | parse_mode=ParseMode.HTML 105 | ) 106 | if os.path.exists(file_path): 107 | clean_download(file_path) 108 | await Smart_Notify(bot, "/yth", e, message) -------------------------------------------------------------------------------- /bot/modules/spl.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import aiohttp 5 | from aiogram import Bot 6 | from aiogram.filters import Command 7 | from aiogram.types import Message 8 | from aiogram.enums import ParseMode 9 | from aiogram.exceptions import TelegramBadRequest 10 | from bot import dp 11 | from bot.helpers.utils import new_task 12 | from bot.helpers.botutils import send_message, delete_messages, get_args 13 | from bot.helpers.commands import BotCommands 14 | from bot.helpers.logger import LOGGER 15 | from bot.helpers.notify import Smart_Notify 16 | from bot.helpers.defend import SmartDefender 17 | from config import A360APIBASEURL 18 | 19 | async def check_spelling(word): 20 | url = f"{A360APIBASEURL}/eng/spl?word={word}" 21 | try: 22 | async with aiohttp.ClientSession() as session: 23 | async with session.get(url) as response: 24 | response.raise_for_status() 25 | result = await response.json() 26 | if 'response' not in result: 27 | raise ValueError("Invalid API response: 'response' key missing") 28 | LOGGER.info(f"Successfully fetched spelling correction for '{word}'") 29 | return result['response'].strip() 30 | except Exception as e: 31 | LOGGER.error(f"Spelling check API error for word '{word}': {e}") 32 | raise 33 | 34 | @dp.message(Command(commands=["spell"], prefix=BotCommands)) 35 | @new_task 36 | @SmartDefender 37 | async def spell_handler(message: Message, bot: Bot): 38 | LOGGER.info(f"Received /spell command from user: {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 39 | checking_message = None 40 | try: 41 | if message.reply_to_message and message.reply_to_message.text: 42 | word = message.reply_to_message.text.strip() 43 | if len(word.split()) != 1: 44 | checking_message = await send_message( 45 | chat_id=message.chat.id, 46 | text="❌ Reply To A Message With A Single Word", 47 | parse_mode=ParseMode.HTML, 48 | disable_web_page_preview=True 49 | ) 50 | LOGGER.warning(f"Invalid reply format: {word}") 51 | return 52 | else: 53 | command_parts = get_args(message) 54 | if not command_parts or len(command_parts) != 1: 55 | checking_message = await send_message( 56 | chat_id=message.chat.id, 57 | text="❌ Provide A Single Word To Check Spelling", 58 | parse_mode=ParseMode.HTML, 59 | disable_web_page_preview=True 60 | ) 61 | LOGGER.warning(f"Invalid command format: {message.text}") 62 | return 63 | word = command_parts[0].strip() 64 | checking_message = await send_message( 65 | chat_id=message.chat.id, 66 | text="Checking Spelling...✨", 67 | parse_mode=ParseMode.HTML, 68 | disable_web_page_preview=True 69 | ) 70 | corrected_word = await check_spelling(word) 71 | await checking_message.edit_text( 72 | text=f"{corrected_word}", 73 | parse_mode=ParseMode.HTML 74 | ) 75 | LOGGER.info(f"Spelling correction sent for '{word}' in chat {message.chat.id}") 76 | except Exception as e: 77 | LOGGER.error(f"Error processing /spell command for word '{word}': {str(e)}") 78 | await Smart_Notify(bot, "spell", e, message) 79 | error_text = "❌ Sorry Bro Spelling Check API Failed" 80 | if checking_message: 81 | try: 82 | await checking_message.edit_text( 83 | text=error_text, 84 | parse_mode=ParseMode.HTML 85 | ) 86 | LOGGER.info(f"Edited checking message with error in chat {message.chat.id}") 87 | except TelegramBadRequest as edit_e: 88 | LOGGER.error(f"Failed to edit checking message in chat {message.chat.id}: {str(edit_e)}") 89 | await Smart_Notify(bot, "spell", edit_e, message) 90 | await send_message( 91 | chat_id=message.chat.id, 92 | text=error_text, 93 | parse_mode=ParseMode.HTML 94 | ) 95 | else: 96 | await send_message( 97 | chat_id=message.chat.id, 98 | text=error_text, 99 | parse_mode=ParseMode.HTML 100 | ) 101 | LOGGER.info(f"Sent error message to chat {message.chat.id}") -------------------------------------------------------------------------------- /bot/modules/sptxt.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import os 5 | import aiofiles 6 | import asyncio 7 | from aiogram import Bot 8 | from aiogram.filters import Command 9 | from aiogram.types import Message, FSInputFile 10 | from aiogram.enums import ParseMode, ChatType 11 | from bot import dp, SmartAIO 12 | from bot.helpers.utils import new_task, clean_download 13 | from bot.helpers.botutils import send_message, delete_messages, get_args 14 | from bot.helpers.notify import Smart_Notify 15 | from bot.helpers.logger import LOGGER 16 | from bot.helpers.commands import BotCommands 17 | from bot.helpers.defend import SmartDefender 18 | from config import MAX_TXT_SIZE 19 | 20 | logger = LOGGER 21 | 22 | async def process_file(file_path, line_limit): 23 | async with aiofiles.open(file_path, "r", encoding='utf-8', errors='ignore') as file: 24 | lines = await file.readlines() 25 | total_lines = len(lines) 26 | split_files = [] 27 | file_index = 1 28 | for start in range(0, total_lines, line_limit): 29 | end = start + line_limit 30 | split_file_path = f"{file_path}_part_{file_index}.txt" 31 | async with aiofiles.open(split_file_path, "w", encoding='utf-8') as split_file: 32 | await split_file.writelines(lines[start:end]) 33 | split_files.append(split_file_path) 34 | file_index += 1 35 | return split_files 36 | 37 | @dp.message(Command(commands=["sptxt"], prefix=BotCommands)) 38 | @new_task 39 | @SmartDefender 40 | async def split_text(message: Message, bot: Bot): 41 | if message.chat.type != ChatType.PRIVATE: 42 | await send_message( 43 | chat_id=message.chat.id, 44 | text="You only can Split text in private chat⚠️", 45 | parse_mode=ParseMode.HTML 46 | ) 47 | return 48 | user_id = message.from_user.id 49 | logger.info(f"Command received from user {user_id} in chat {message.chat.id}: {message.text}") 50 | if not message.reply_to_message or not message.reply_to_message.document or not message.reply_to_message.document.file_name.endswith(".txt"): 51 | await send_message( 52 | chat_id=message.chat.id, 53 | text="⚠️ Please Reply To A Txt File And Give Amount To Split", 54 | parse_mode=ParseMode.HTML 55 | ) 56 | return 57 | file_size_mb = message.reply_to_message.document.file_size / (1024 * 1024) 58 | if file_size_mb > MAX_TXT_SIZE: 59 | await send_message( 60 | chat_id=message.chat.id, 61 | text="⚠️ File size exceeds the 10MB limit❌", 62 | parse_mode=ParseMode.HTML 63 | ) 64 | return 65 | try: 66 | line_limit = int(get_args(message)[0]) 67 | except (IndexError, ValueError): 68 | await send_message( 69 | chat_id=message.chat.id, 70 | text="⚠️ Please Provide A Valid Line Limit", 71 | parse_mode=ParseMode.HTML 72 | ) 73 | return 74 | processing_msg = await send_message( 75 | chat_id=message.chat.id, 76 | text="Processing Text Split..✨", 77 | parse_mode=ParseMode.HTML 78 | ) 79 | try: 80 | file_id = message.reply_to_message.document.file_id 81 | os.makedirs("./downloads", exist_ok=True) 82 | file_path = f"./downloads/sptxt_{user_id}_{int(asyncio.get_event_loop().time())}.txt" 83 | await bot.download(file=file_id, destination=file_path) 84 | split_files = await process_file(file_path, line_limit) 85 | try: 86 | await delete_messages( 87 | chat_id=message.chat.id, 88 | message_ids=[processing_msg.message_id] 89 | ) 90 | except Exception as e: 91 | logger.warning(f"[{user_id}] Failed to delete processing message: {e}") 92 | for split_file in split_files: 93 | await bot.send_document( 94 | chat_id=message.chat.id, 95 | document=FSInputFile(split_file) 96 | ) 97 | clean_download(split_file) 98 | clean_download(file_path) 99 | except Exception as e: 100 | logger.error(f"[{user_id}] Error processing /sptxt: {e}") 101 | try: 102 | await delete_messages( 103 | chat_id=message.chat.id, 104 | message_ids=[processing_msg.message_id] 105 | ) 106 | except Exception as e: 107 | logger.warning(f"[{user_id}] Failed to delete processing message: {e}") 108 | await send_message( 109 | chat_id=message.chat.id, 110 | text="❌ Error processing text split", 111 | parse_mode=ParseMode.HTML 112 | ) 113 | clean_download(file_path) 114 | await Smart_Notify(bot, "/sptxt", e, message) -------------------------------------------------------------------------------- /bot/modules/gra.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import aiohttp 5 | import asyncio 6 | from aiogram import Bot 7 | from aiogram.filters import Command 8 | from aiogram.types import Message 9 | from aiogram.enums import ParseMode 10 | from aiogram.exceptions import TelegramBadRequest 11 | from bot import dp 12 | from bot.helpers.utils import new_task 13 | from bot.helpers.botutils import send_message, delete_messages, get_args 14 | from bot.helpers.commands import BotCommands 15 | from bot.helpers.logger import LOGGER 16 | from bot.helpers.notify import Smart_Notify 17 | from bot.helpers.defend import SmartDefender 18 | from config import A360APIBASEURL 19 | 20 | async def check_grammar(text): 21 | url = f"{A360APIBASEURL}/eng/gmr?content={text}" 22 | try: 23 | async with aiohttp.ClientSession() as session: 24 | async with session.get(url) as response: 25 | response.raise_for_status() 26 | result = await response.json() 27 | if 'response' not in result: 28 | raise ValueError("Invalid API response: 'response' key missing") 29 | LOGGER.info("Successfully fetched grammar correction") 30 | return result['response'].strip() 31 | except Exception as e: 32 | LOGGER.error(f"Grammar check API error: {str(e)}") 33 | return None 34 | 35 | @dp.message(Command(commands=["gra"], prefix=BotCommands)) 36 | @new_task 37 | @SmartDefender 38 | async def grammar_check(message: Message, bot: Bot): 39 | LOGGER.info(f"Received command: '{message.text}' from user {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 40 | progress_message = None 41 | try: 42 | if message.reply_to_message and message.reply_to_message.text: 43 | user_input = message.reply_to_message.text.strip() 44 | else: 45 | args = get_args(message) 46 | if not args: 47 | progress_message = await send_message( 48 | chat_id=message.chat.id, 49 | text="❌ Provide some text or reply to a message to fix grammar", 50 | parse_mode=ParseMode.HTML 51 | ) 52 | LOGGER.info(f"No text provided in chat {message.chat.id}") 53 | return 54 | user_input = ' '.join(args).strip() 55 | progress_message = await send_message( 56 | chat_id=message.chat.id, 57 | text="Checking And Fixing Grammar Please Wait...✨", 58 | parse_mode=ParseMode.HTML 59 | ) 60 | corrected_text = await check_grammar(user_input) 61 | if not corrected_text: 62 | await delete_messages(message.chat.id, [progress_message.message_id]) 63 | await send_message( 64 | chat_id=message.chat.id, 65 | text="❌ Sorry, Grammar Check API Failed", 66 | parse_mode=ParseMode.HTML 67 | ) 68 | LOGGER.info(f"Failed to fetch grammar correction in chat {message.chat.id}") 69 | return 70 | await delete_messages(message.chat.id, [progress_message.message_id]) 71 | await send_message( 72 | chat_id=message.chat.id, 73 | text=f"Corrected Text: {corrected_text}", 74 | parse_mode=ParseMode.HTML 75 | ) 76 | LOGGER.info(f"Grammar correction sent for text in chat {message.chat.id}") 77 | except (Exception, TelegramBadRequest) as e: 78 | LOGGER.error(f"Error processing grammar check in chat {message.chat.id}: {str(e)}") 79 | await Smart_Notify(bot, "gra", e, message) 80 | if progress_message: 81 | try: 82 | await delete_messages(message.chat.id, [progress_message.message_id]) 83 | await send_message( 84 | chat_id=message.chat.id, 85 | text="❌ Sorry, Grammar Check API Failed", 86 | parse_mode=ParseMode.HTML 87 | ) 88 | LOGGER.info(f"Sent grammar check error message to chat {message.chat.id}") 89 | except TelegramBadRequest as edit_e: 90 | LOGGER.error(f"Failed to delete progress message in chat {message.chat.id}: {str(edit_e)}") 91 | await Smart_Notify(bot, "gra", edit_e, message) 92 | await send_message( 93 | chat_id=message.chat.id, 94 | text="❌ Sorry, Grammar Check API Failed", 95 | parse_mode=ParseMode.HTML 96 | ) 97 | LOGGER.info(f"Sent grammar check error message to chat {message.chat.id}") 98 | else: 99 | await send_message( 100 | chat_id=message.chat.id, 101 | text="❌ Sorry, Grammar Check API Failed", 102 | parse_mode=ParseMode.HTML 103 | ) 104 | LOGGER.info(f"Sent grammar check error message to chat {message.chat.id}") -------------------------------------------------------------------------------- /bot/modules/cyrptx.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import aiohttp 5 | import asyncio 6 | from aiogram import Bot 7 | from aiogram.filters import Command 8 | from aiogram.types import Message 9 | from aiogram.enums import ParseMode 10 | from bot import dp 11 | from bot.helpers.utils import new_task 12 | from bot.helpers.botutils import send_message, delete_messages 13 | from bot.helpers.commands import BotCommands 14 | from bot.helpers.logger import LOGGER 15 | from bot.helpers.notify import Smart_Notify 16 | from bot.helpers.defend import SmartDefender 17 | from config import A360APIBASEURL 18 | 19 | BASE_URL = f"{A360APIBASEURL}/binance/cx" 20 | 21 | price_storage = {} 22 | 23 | async def get_conversion_data(base_coin: str, target_coin: str, amount: float): 24 | try: 25 | url = f"{BASE_URL}?base={base_coin.upper()}&target={target_coin.upper()}&amount={amount}" 26 | async with aiohttp.ClientSession() as session: 27 | async with session.get(url) as response: 28 | response.raise_for_status() 29 | data = await response.json() 30 | if not data.get("success", False): 31 | LOGGER.error(f"API returned success: false for {base_coin} to {target_coin}") 32 | return None 33 | LOGGER.info(f"Successfully fetched conversion data for {base_coin} to {target_coin}") 34 | return data['data'] 35 | except Exception as e: 36 | LOGGER.error(f"Error fetching conversion data for {base_coin} to {target_coin}: {e}") 37 | return None 38 | 39 | def format_response(data: dict) -> str: 40 | return ( 41 | "Smart Binance Convert Successful ✅\n" 42 | "━━━━━━━━━━━━━━━━\n" 43 | f"Base Coin: {data['base_coin']}\n" 44 | f"Target Coin: {data['target_coin']}\n" 45 | f"Amount: {data['amount']:.4f} {data['base_coin']}\n" 46 | f"Total In USDT: {data['total_in_usdt']:.4f} USDT\n" 47 | f"Converted Amount: {data['converted_amount']:.4f} {data['target_coin']}\n" 48 | "━━━━━━━━━━━━━━━━\n" 49 | "Smooth Coin Converter → Activated ✅" 50 | ) 51 | 52 | @dp.message(Command(commands=["cx"], prefix=BotCommands)) 53 | @new_task 54 | @SmartDefender 55 | async def coin_handler(message: Message, bot: Bot): 56 | command = message.text.split() 57 | if len(command) < 4: 58 | await send_message( 59 | chat_id=message.chat.id, 60 | text="Invalid format. Use /cx 10 ton usdt", 61 | parse_mode=ParseMode.HTML 62 | ) 63 | LOGGER.warning(f"Invalid command format: {message.text} in chat {message.chat.id}") 64 | return 65 | try: 66 | amount = float(command[1]) 67 | if amount <= 0: 68 | raise ValueError("Amount must be greater than 0") 69 | except ValueError: 70 | await send_message( 71 | chat_id=message.chat.id, 72 | text="Invalid format. Use /cx 10 ton usdt", 73 | parse_mode=ParseMode.HTML 74 | ) 75 | LOGGER.warning(f"Invalid amount provided: {command[1]} in chat {message.chat.id}") 76 | return 77 | base_coin = command[2].upper() 78 | target_coin = command[3].upper() 79 | progress_message = await send_message( 80 | chat_id=message.chat.id, 81 | text="Fetching Token Price, Please Wait...", 82 | parse_mode=ParseMode.HTML 83 | ) 84 | try: 85 | data = await get_conversion_data(base_coin, target_coin, amount) 86 | if data is None: 87 | await delete_messages(message.chat.id, [progress_message.message_id]) 88 | await send_message( 89 | chat_id=message.chat.id, 90 | text="❌ Failed! This token pair may not exist on Binance.", 91 | parse_mode=ParseMode.HTML 92 | ) 93 | LOGGER.warning(f"Failed to fetch conversion for {base_coin} to {target_coin} in chat {message.chat.id}") 94 | return 95 | price_storage[message.chat.id] = data 96 | await delete_messages(message.chat.id, [progress_message.message_id]) 97 | await send_message( 98 | chat_id=message.chat.id, 99 | text=format_response(data), 100 | parse_mode=ParseMode.HTML 101 | ) 102 | LOGGER.info(f"Coin conversion result sent for {base_coin} to {target_coin}: {data['converted_amount']} {target_coin} in chat {message.chat.id}") 103 | except Exception as e: 104 | await delete_messages(message.chat.id, [progress_message.message_id]) 105 | await send_message( 106 | chat_id=message.chat.id, 107 | text="❌ Failed! This token pair may not exist on Binance.", 108 | parse_mode=ParseMode.HTML 109 | ) 110 | LOGGER.error(f"Error processing /cx for {base_coin} to {target_coin} in chat {message.chat.id}: {e}") 111 | await Smart_Notify(bot, "/cx", e, message) -------------------------------------------------------------------------------- /bot/modules/ss.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import os 5 | import aiohttp 6 | import time 7 | import aiofiles 8 | import asyncio 9 | from aiogram import Bot 10 | from aiogram.filters import Command 11 | from aiogram.types import Message 12 | from aiogram.enums import ParseMode 13 | from pyrogram.enums import ParseMode as SmartParseMode 14 | from pyrogram.types import Message as SmartMessage 15 | from bot import dp, SmartPyro 16 | from bot.helpers.utils import new_task, clean_download 17 | from bot.helpers.botutils import send_message, delete_messages, get_args 18 | from bot.helpers.commands import BotCommands 19 | from bot.helpers.logger import LOGGER 20 | from bot.helpers.notify import Smart_Notify 21 | from bot.helpers.defend import SmartDefender 22 | from config import WEB_SS_KEY 23 | from urllib.parse import quote 24 | 25 | logger = LOGGER 26 | MAX_FILE_SIZE = 5 * 1024 * 1024 27 | 28 | def validate_url(url: str) -> bool: 29 | return '.' in url and len(url) < 2048 30 | 31 | def normalize_url(url: str) -> str: 32 | return url if url.startswith(('http://', 'https://')) else f"https://{url}" 33 | 34 | async def fetch_screenshot(url: str, bot: Bot) -> bytes: 35 | api_url = f"https://api.thumbnail.ws/api/{WEB_SS_KEY}/thumbnail/get?url={quote(url)}&width=1280" 36 | timeout = aiohttp.ClientTimeout(total=10) 37 | try: 38 | async with aiohttp.ClientSession(timeout=timeout) as session: 39 | async with session.get(api_url) as response: 40 | response.raise_for_status() 41 | content_type = response.headers.get('Content-Type', '') 42 | if 'image' not in content_type: 43 | raise ValueError(f"Unexpected content type: {content_type}") 44 | content_length = int(response.headers.get('Content-Length', 0)) 45 | if content_length > MAX_FILE_SIZE: 46 | raise ValueError(f"Screenshot too large ({content_length / 1024 / 1024:.1f}MB)") 47 | return await response.read() 48 | except (aiohttp.ClientError, asyncio.TimeoutError, ValueError) as e: 49 | logger.error(f"Failed to fetch screenshot for {url}: {e}") 50 | await Smart_Notify(bot, f"{BotCommands}ss", e, None) 51 | return None 52 | 53 | async def save_screenshot(url: str, timestamp: int, bot: Bot) -> str: 54 | screenshot_bytes = await fetch_screenshot(url, bot) 55 | if not screenshot_bytes: 56 | return None 57 | temp_file = f"screenshot_{timestamp}_{hash(url)}.jpg" 58 | async with aiofiles.open(temp_file, 'wb') as file: 59 | await file.write(screenshot_bytes) 60 | file_size = os.path.getsize(temp_file) 61 | if file_size > MAX_FILE_SIZE: 62 | clean_download(temp_file) 63 | return None 64 | return temp_file 65 | 66 | async def capture_screenshots(message: Message, bot: Bot, urls: list) -> None: 67 | user_id = message.from_user.id if message.from_user else None 68 | if not urls: 69 | await send_message( 70 | chat_id=message.chat.id, 71 | text="❌ Please provide at least one URL after the command", 72 | parse_mode=ParseMode.HTML 73 | ) 74 | return 75 | for url in urls: 76 | if not validate_url(url): 77 | await send_message( 78 | chat_id=message.chat.id, 79 | text=f"❌ Invalid URL format: {url}", 80 | parse_mode=ParseMode.HTML 81 | ) 82 | return 83 | processing_msg = await send_message( 84 | chat_id=message.chat.id, 85 | text="Capturing ScreenShots Please Wait", 86 | parse_mode=ParseMode.HTML 87 | ) 88 | timestamp = int(time.time()) 89 | tasks = [save_screenshot(normalize_url(url), timestamp, bot) for url in urls] 90 | temp_files = await asyncio.gather(*tasks, return_exceptions=True) 91 | try: 92 | for i, temp_file in enumerate(temp_files): 93 | if isinstance(temp_file, Exception): 94 | logger.error(f"Error processing {urls[i]}: {temp_file}") 95 | continue 96 | if temp_file: 97 | async with aiofiles.open(temp_file, 'rb'): 98 | await SmartPyro.send_photo( 99 | chat_id=message.chat.id, 100 | photo=temp_file, 101 | parse_mode=SmartParseMode.HTML 102 | ) 103 | clean_download(temp_file) 104 | await delete_messages(message.chat.id, [processing_msg.message_id]) 105 | except Exception as e: 106 | logger.error(f"Error in capture_screenshots: {e}") 107 | await Smart_Notify(bot, f"{BotCommands}ss", e, processing_msg) 108 | await processing_msg.edit_text("Sorry Bro SS Capture API Dead", parse_mode=ParseMode.HTML) 109 | 110 | @dp.message(Command(commands=["ss"], prefix=BotCommands)) 111 | @new_task 112 | @SmartDefender 113 | async def ss_command(message: Message, bot: Bot): 114 | urls = get_args(message) 115 | await capture_screenshots(message, bot, urls) -------------------------------------------------------------------------------- /bot/modules/topbn.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from aiogram import Bot 5 | from aiogram.filters import Command, BaseFilter 6 | from aiogram.types import Message 7 | from aiogram.enums import ParseMode 8 | from aiogram.exceptions import TelegramBadRequest 9 | from bot import dp 10 | from bot.helpers.utils import new_task, clean_download 11 | from bot.helpers.botutils import send_message, delete_messages 12 | from bot.helpers.commands import BotCommands 13 | from bot.helpers.buttons import SmartButtons 14 | from bot.helpers.logger import LOGGER 15 | from bot.helpers.notify import Smart_Notify 16 | from bot.helpers.defend import SmartDefender 17 | from config import UPDATE_CHANNEL_URL, MAX_TXT_SIZE 18 | from collections import Counter 19 | import os 20 | import time 21 | import asyncio 22 | 23 | class TopBinCommandFilter(BaseFilter): 24 | async def __call__(self, message: Message): 25 | if not message.text: 26 | return False 27 | for prefix in BotCommands: 28 | if message.text.lower().startswith(f"{prefix}topbin"): 29 | return True 30 | return False 31 | 32 | @dp.message(TopBinCommandFilter()) 33 | @new_task 34 | @SmartDefender 35 | async def handle_topbin_command(message: Message, bot: Bot): 36 | progress_message = None 37 | file_path = None 38 | try: 39 | if not message.reply_to_message or not message.reply_to_message.document or not message.reply_to_message.document.file_name.endswith('.txt'): 40 | progress_message = await send_message( 41 | chat_id=message.chat.id, 42 | text="⚠️ Reply to a text file containing credit cards to check top bins❌", 43 | parse_mode=ParseMode.HTML 44 | ) 45 | return 46 | file_size_mb = message.reply_to_message.document.file_size / (1024 * 1024) 47 | if file_size_mb > MAX_TXT_SIZE: 48 | progress_message = await send_message( 49 | chat_id=message.chat.id, 50 | text=f"⚠️ File size exceeds the {MAX_TXT_SIZE}MB limit❌", 51 | parse_mode=ParseMode.HTML 52 | ) 53 | return 54 | progress_message = await send_message( 55 | chat_id=message.chat.id, 56 | text="Finding Top Bins...✨", 57 | parse_mode=ParseMode.HTML 58 | ) 59 | start_time = time.time() 60 | file_id = message.reply_to_message.document.file_id 61 | file_info = await bot.get_file(file_id) 62 | file_path = f"downloads/{file_id}.txt" 63 | os.makedirs('downloads', exist_ok=True) 64 | await bot.download_file(file_info.file_path, file_path) 65 | with open(file_path, 'r') as file: 66 | content = file.readlines() 67 | bin_counter = Counter([line.strip()[:6] for line in content if len(line.strip()) >= 6]) 68 | top_bins = bin_counter.most_common(20) 69 | end_time = time.time() 70 | time_taken = end_time - start_time 71 | if not top_bins: 72 | await progress_message.edit_text( 73 | text="❌ No BIN data found in the file.", 74 | parse_mode=ParseMode.HTML 75 | ) 76 | return 77 | response_message = ( 78 | "Smart Top Bin Find → Successful ✅\n" 79 | "━━━━━━━━━━━━━━━━━\n" + 80 | "\n".join(f"⊗ BIN: {bin} - Amount: {count}" for bin, count in top_bins) + "\n" + 81 | "━━━━━━━━━━━━━━━━━\n" 82 | "Smart Top Bin Finder → Activated ✅" 83 | ) 84 | buttons = SmartButtons() 85 | buttons.button(text="Join For Updates", url=UPDATE_CHANNEL_URL) 86 | await delete_messages(message.chat.id, progress_message.message_id) 87 | await send_message( 88 | chat_id=message.chat.id, 89 | text=response_message, 90 | parse_mode=ParseMode.HTML, 91 | disable_web_page_preview=True, 92 | reply_markup=buttons.build_menu(b_cols=1) 93 | ) 94 | except Exception as e: 95 | await Smart_Notify(bot, "topbin", e, message) 96 | if progress_message: 97 | try: 98 | await progress_message.edit_text( 99 | text="❌ Sorry, an error occurred while finding top BINs", 100 | parse_mode=ParseMode.HTML 101 | ) 102 | except TelegramBadRequest as edit_e: 103 | await Smart_Notify(bot, "topbin", edit_e, message) 104 | await send_message( 105 | chat_id=message.chat.id, 106 | text="❌ Sorry, an error occurred while finding top BINs", 107 | parse_mode=ParseMode.HTML 108 | ) 109 | else: 110 | await send_message( 111 | chat_id=message.chat.id, 112 | text="❌ Sorry, an error occurred while finding top BINs", 113 | parse_mode=ParseMode.HTML 114 | ) 115 | finally: 116 | clean_download() -------------------------------------------------------------------------------- /bot/modules/syn.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import aiohttp 5 | from aiogram import Bot 6 | from aiogram.filters import Command 7 | from aiogram.types import Message 8 | from aiogram.enums import ParseMode 9 | from aiogram.exceptions import TelegramBadRequest 10 | from bot import dp 11 | from bot.helpers.utils import new_task 12 | from bot.helpers.botutils import send_message, delete_messages, get_args 13 | from bot.helpers.commands import BotCommands 14 | from bot.helpers.logger import LOGGER 15 | from bot.helpers.notify import Smart_Notify 16 | from bot.helpers.defend import SmartDefender 17 | from config import A360APIBASEURL 18 | 19 | async def fetch_synonyms_antonyms(word): 20 | synonyms_url = f"{A360APIBASEURL}/eng/syn?word={word}" 21 | antonyms_url = f"{A360APIBASEURL}/eng/ant?word={word}" 22 | try: 23 | async with aiohttp.ClientSession() as session: 24 | async with session.get(synonyms_url) as syn_response, session.get(antonyms_url) as ant_response: 25 | syn_response.raise_for_status() 26 | ant_response.raise_for_status() 27 | synonyms = await syn_response.json() 28 | antonyms = await ant_response.json() 29 | synonyms = synonyms['response'] 30 | antonyms = antonyms['response'] 31 | LOGGER.info(f"Successfully fetched synonyms and antonyms for '{word}'") 32 | return synonyms, antonyms 33 | except (aiohttp.ClientError, ValueError, KeyError) as e: 34 | LOGGER.error(f"A360 API error for word '{word}': {e}") 35 | raise 36 | 37 | @dp.message(Command(commands=["syn", "synonym"], prefix=BotCommands)) 38 | @new_task 39 | @SmartDefender 40 | async def syn_handler(message: Message, bot: Bot): 41 | LOGGER.info(f"Received /syn or /synonym command from user: {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 42 | loading_message = None 43 | try: 44 | if message.reply_to_message and message.reply_to_message.text: 45 | word = message.reply_to_message.text.strip() 46 | if len(word.split()) != 1: 47 | loading_message = await send_message( 48 | chat_id=message.chat.id, 49 | text="❌ Reply To A Message With A Single Word", 50 | parse_mode=ParseMode.HTML, 51 | disable_web_page_preview=True 52 | ) 53 | LOGGER.warning(f"Invalid reply format: {word}") 54 | return 55 | else: 56 | command_parts = get_args(message) 57 | if not command_parts or len(command_parts) != 1: 58 | loading_message = await send_message( 59 | chat_id=message.chat.id, 60 | text="❌ Provide A Single Word To Get Synonyms And Antonyms", 61 | parse_mode=ParseMode.HTML, 62 | disable_web_page_preview=True 63 | ) 64 | LOGGER.warning(f"Invalid command format: {message.text}") 65 | return 66 | word = command_parts[0].strip() 67 | loading_message = await send_message( 68 | chat_id=message.chat.id, 69 | text="Fetching Synonyms and Antonyms...✨", 70 | parse_mode=ParseMode.HTML, 71 | disable_web_page_preview=True 72 | ) 73 | synonyms, antonyms = await fetch_synonyms_antonyms(word) 74 | synonyms_text = ", ".join(synonyms) if synonyms else "No synonyms found" 75 | antonyms_text = ", ".join(antonyms) if antonyms else "No antonyms found" 76 | response_text = ( 77 | f"Synonyms:\n{synonyms_text}\n\n" 78 | f"Antonyms:\n{antonyms_text}" 79 | ) 80 | await loading_message.edit_text( 81 | text=response_text, 82 | parse_mode=ParseMode.HTML 83 | ) 84 | LOGGER.info(f"Sent synonyms and antonyms for '{word}' in chat {message.chat.id}") 85 | except Exception as e: 86 | LOGGER.error(f"Error processing /syn or /synonym command for word '{word}': {str(e)}") 87 | await Smart_Notify(bot, "syn", e, message) 88 | error_text = "❌ Sorry Bro Synonym/Antonym API Failed" 89 | if loading_message: 90 | try: 91 | await loading_message.edit_text( 92 | text=error_text, 93 | parse_mode=ParseMode.HTML 94 | ) 95 | LOGGER.info(f"Edited loading message with error in chat {message.chat.id}") 96 | except TelegramBadRequest as edit_e: 97 | LOGGER.error(f"Failed to edit loading message in chat {message.chat.id}: {str(edit_e)}") 98 | await Smart_Notify(bot, "syn", edit_e, message) 99 | await send_message( 100 | chat_id=message.chat.id, 101 | text=error_text, 102 | parse_mode=ParseMode.HTML 103 | ) 104 | else: 105 | await send_message( 106 | chat_id=message.chat.id, 107 | text=error_text, 108 | parse_mode=ParseMode.HTML 109 | ) 110 | LOGGER.info(f"Sent error message to chat {message.chat.id}") -------------------------------------------------------------------------------- /bot/modules/ai.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from aiogram import Bot 5 | from aiogram.filters import Command 6 | from aiogram.types import Message 7 | from aiogram.enums import ParseMode 8 | from aiogram.exceptions import TelegramBadRequest 9 | from bot import dp 10 | from bot.helpers.botutils import send_message, delete_messages 11 | from bot.helpers.commands import BotCommands 12 | from bot.helpers.logger import LOGGER 13 | from bot.helpers.utils import new_task 14 | from bot.helpers.notify import Smart_Notify 15 | from bot.helpers.defend import SmartDefender 16 | from config import A360APIBASEURL 17 | import aiohttp 18 | 19 | @dp.message(Command(commands=["ai"], prefix=BotCommands)) 20 | @new_task 21 | @SmartDefender 22 | async def ai_handler(message: Message, bot: Bot): 23 | LOGGER.info(f"Received command: '{message.text}' from user {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 24 | progress_message = None 25 | try: 26 | progress_message = await send_message( 27 | chat_id=message.chat.id, 28 | text="🔍 SmartAI is thinking, Please Wait ✨", 29 | parse_mode=ParseMode.HTML 30 | ) 31 | prompt = None 32 | command_text = message.text.split(maxsplit=1) 33 | if message.reply_to_message and message.reply_to_message.text: 34 | prompt = message.reply_to_message.text 35 | elif len(command_text) > 1: 36 | prompt = command_text[1] 37 | if not prompt: 38 | await progress_message.edit_text( 39 | text="Please Provide A Prompt For SmartAI ✨ Response", 40 | parse_mode=ParseMode.HTML 41 | ) 42 | LOGGER.info(f"Prompt missing for SmartAI command in chat {message.chat.id}") 43 | return 44 | async with aiohttp.ClientSession() as session: 45 | async with session.get(f"{A360APIBASEURL}/ai/smartai?prompt={prompt}") as resp: 46 | if resp.status == 200: 47 | data = await resp.json() 48 | response_text = data.get("response", "No response received") 49 | else: 50 | response_text = "❌ Sorry Bro SmartAI API Error" 51 | LOGGER.error(f"SmartAI API request failed with status {resp.status}: {await resp.text()}") 52 | await Smart_Notify(bot, "ai", f"API request failed with status {resp.status}", message) 53 | if len(response_text) > 4000: 54 | await delete_messages(message.chat.id, progress_message.message_id) 55 | parts = [response_text[i:i+4000] for i in range(0, len(response_text), 4000)] 56 | for part in parts: 57 | await send_message( 58 | chat_id=message.chat.id, 59 | text=part, 60 | parse_mode=ParseMode.HTML 61 | ) 62 | LOGGER.info(f"Successfully sent SmartAI response (split) to chat {message.chat.id}") 63 | else: 64 | try: 65 | await progress_message.edit_text( 66 | text=response_text, 67 | parse_mode=ParseMode.HTML 68 | ) 69 | LOGGER.info(f"Successfully sent SmartAI response to chat {message.chat.id}") 70 | except TelegramBadRequest as edit_e: 71 | LOGGER.error(f"Failed to edit progress message in chat {message.chat.id}: {str(edit_e)}") 72 | await Smart_Notify(bot, "ai", edit_e, message) 73 | await delete_messages(message.chat.id, progress_message.message_id) 74 | await send_message( 75 | chat_id=message.chat.id, 76 | text=response_text, 77 | parse_mode=ParseMode.HTML 78 | ) 79 | LOGGER.info(f"Successfully sent SmartAI response to chat {message.chat.id}") 80 | except Exception as e: 81 | LOGGER.error(f"SmartAI error in chat {message.chat.id}: {str(e)}") 82 | await Smart_Notify(bot, "ai", e, message) 83 | if progress_message: 84 | try: 85 | await progress_message.edit_text( 86 | text="❌ Sorry Bro SmartAI API Error", 87 | parse_mode=ParseMode.HTML 88 | ) 89 | LOGGER.info(f"Edited progress message with SmartAI error in chat {message.chat.id}") 90 | except TelegramBadRequest as edit_e: 91 | LOGGER.error(f"Failed to edit progress message in chat {message.chat.id}: {str(edit_e)}") 92 | await Smart_Notify(bot, "ai", edit_e, message) 93 | await send_message( 94 | chat_id=message.chat.id, 95 | text="❌ Sorry Bro SmartAI API Error", 96 | parse_mode=ParseMode.HTML 97 | ) 98 | LOGGER.info(f"Sent SmartAI error message to chat {message.chat.id}") 99 | else: 100 | await send_message( 101 | chat_id=message.chat.id, 102 | text="❌ Sorry Bro SmartAI API Error", 103 | parse_mode=ParseMode.HTML 104 | ) 105 | LOGGER.info(f"Sent SmartAI error message to chat {message.chat.id}") -------------------------------------------------------------------------------- /bot/modules/bin.py: -------------------------------------------------------------------------------- 1 | from aiogram import Bot 2 | from aiogram.filters import Command 3 | from aiogram.types import Message 4 | from aiogram.enums import ParseMode 5 | from aiogram.exceptions import TelegramBadRequest 6 | from bot import dp 7 | from bot.helpers.utils import new_task 8 | from bot.helpers.botutils import send_message, delete_messages, get_args 9 | from bot.helpers.commands import BotCommands 10 | from bot.helpers.logger import LOGGER 11 | from bot.helpers.notify import Smart_Notify 12 | from bot.helpers.defend import SmartDefender 13 | from bot.helpers.bindb import smartdb 14 | import pycountry 15 | 16 | async def get_bin_info(bin: str, bot: Bot, message: Message): 17 | try: 18 | result = await smartdb.get_bin_info(bin) 19 | if result.get("status") == "SUCCESS" and result.get("data") and isinstance(result["data"], list) and len(result["data"]) > 0: 20 | return result 21 | else: 22 | LOGGER.error(f"SmartBinDB returned invalid response: {result}") 23 | await Smart_Notify(bot, "bin", f"SmartBinDB invalid response: {result}", message) 24 | return None 25 | except Exception as e: 26 | LOGGER.error(f"Error fetching BIN info from SmartBinDB: {str(e)}") 27 | await Smart_Notify(bot, "bin", e, message) 28 | return None 29 | 30 | def get_flag(country_code: str): 31 | try: 32 | if not country_code or len(country_code) < 2: 33 | return "Unknown", "" 34 | country_code = country_code.upper() 35 | if country_code in ['US1', 'US2']: 36 | country_code = 'US' 37 | country = pycountry.countries.get(alpha_2=country_code) 38 | if not country: 39 | return "Unknown", "" 40 | country_name = country.name 41 | flag_emoji = chr(0x1F1E6 + ord(country_code[0]) - ord('A')) + chr(0x1F1E6 + ord(country_code[1]) - ord('A')) 42 | return country_name, flag_emoji 43 | except Exception: 44 | return "Unknown", "" 45 | 46 | @dp.message(Command(commands=["bin"], prefix=BotCommands)) 47 | @new_task 48 | @SmartDefender 49 | async def bin_handler(message: Message, bot: Bot): 50 | LOGGER.info(f"Received command: '{message.text}' from user {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 51 | progress_message = None 52 | try: 53 | args = get_args(message) 54 | if not args: 55 | progress_message = await send_message( 56 | chat_id=message.chat.id, 57 | text="Provide a valid BIN ❌", 58 | parse_mode=ParseMode.HTML 59 | ) 60 | LOGGER.info(f"No BIN provided in chat {message.chat.id}") 61 | return 62 | progress_message = await send_message( 63 | chat_id=message.chat.id, 64 | text="Fetching Bin Details...", 65 | parse_mode=ParseMode.HTML 66 | ) 67 | bin = args[0][:6] 68 | bin_info = await get_bin_info(bin, bot, message) 69 | if not bin_info: 70 | await progress_message.edit_text( 71 | text="Invalid BIN provided ❌", 72 | parse_mode=ParseMode.HTML 73 | ) 74 | LOGGER.info(f"Invalid BIN {bin} in chat {message.chat.id}") 75 | return 76 | bank = bin_info["data"][0].get("issuer", "Unknown") 77 | card_type = bin_info["data"][0].get("type", "Unknown") 78 | card_scheme = bin_info["data"][0].get("brand", "Unknown") 79 | bank_text = bank.upper() if bank else "Unknown" 80 | country_code = bin_info["data"][0].get("country_code", "") 81 | country_name, flag_emoji = get_flag(country_code) 82 | bin_info_text = ( 83 | f"🔍 BIN Details From Smart Database 📋\n" 84 | f"━━━━━━━━━━━━━━━━━━\n" 85 | f"• BIN: {bin}\n" 86 | f"• INFO: {card_scheme.upper()} - {card_type.upper()}\n" 87 | f"• BANK: {bank_text}\n" 88 | f"• COUNTRY: {country_name.upper()} {flag_emoji}\n" 89 | f"━━━━━━━━━━━━━━━━━━\n" 90 | f"🔍 Smart Bin Checker → Activated ✅" 91 | ) 92 | await progress_message.edit_text( 93 | text=bin_info_text, 94 | parse_mode=ParseMode.HTML 95 | ) 96 | LOGGER.info(f"Successfully sent BIN details for {bin} to chat {message.chat.id}") 97 | except Exception as e: 98 | LOGGER.error(f"Error processing BIN command in chat {message.chat.id}: {str(e)}") 99 | await Smart_Notify(bot, "bin", e, message) 100 | if progress_message: 101 | try: 102 | await progress_message.edit_text( 103 | text="❌ Sorry Bro BIN API Error", 104 | parse_mode=ParseMode.HTML 105 | ) 106 | LOGGER.info(f"Edited progress message with BIN error in chat {message.chat.id}") 107 | except TelegramBadRequest as edit_e: 108 | LOGGER.error(f"Failed to edit progress message in chat {message.chat.id}: {str(edit_e)}") 109 | await Smart_Notify(bot, "bin", edit_e, message) 110 | await send_message( 111 | chat_id=message.chat.id, 112 | text="❌ Sorry Bro BIN API Error", 113 | parse_mode=ParseMode.HTML 114 | ) 115 | LOGGER.info(f"Sent BIN error message to chat {message.chat.id}") 116 | else: 117 | await send_message( 118 | chat_id=message.chat.id, 119 | text="❌ Sorry Bro BIN API Error", 120 | parse_mode=ParseMode.HTML 121 | ) 122 | LOGGER.info(f"Sent BIN error message to chat {message.chat.id}") -------------------------------------------------------------------------------- /bot/modules/fake.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import pycountry 3 | from aiogram import Bot 4 | from aiogram.filters import Command 5 | from aiogram.types import Message, CallbackQuery 6 | from aiogram.enums import ParseMode 7 | from bot import dp 8 | from bot.helpers.utils import new_task 9 | from bot.helpers.botutils import send_message, delete_messages, get_args 10 | from bot.helpers.commands import BotCommands 11 | from bot.helpers.buttons import SmartButtons 12 | from bot.helpers.logger import LOGGER 13 | from bot.helpers.notify import Smart_Notify 14 | from bot.helpers.defend import SmartDefender 15 | from smartfaker import Faker 16 | 17 | fake = Faker() 18 | 19 | def get_flag(country_code): 20 | try: 21 | country = pycountry.countries.get(alpha_2=country_code) 22 | if not country: 23 | return "Unknown", "" 24 | name = country.name 25 | flag = chr(0x1F1E6 + ord(country_code[0]) - ord('A')) + chr(0x1F1E6 + ord(country_code[1]) - ord('A')) 26 | return name, flag 27 | except: 28 | return "Unknown", "" 29 | 30 | def resolve_country(inp): 31 | inp = inp.strip().upper() 32 | maps = { 33 | "UK": ("GB", "United Kingdom"), 34 | "UAE": ("AE", "United Arab Emirates"), 35 | "AE": ("AE", "United Arab Emirates"), 36 | "UNITED KINGDOM": ("GB", "United Kingdom"), 37 | "UNITED ARAB EMIRATES": ("AE", "United Arab Emirates") 38 | } 39 | if inp in maps: 40 | return maps[inp] 41 | if len(inp) == 2: 42 | c = pycountry.countries.get(alpha_2=inp) 43 | if c: 44 | return c.alpha_2, c.name 45 | try: 46 | c = pycountry.countries.search_fuzzy(inp)[0] 47 | return c.alpha_2, c.name 48 | except: 49 | return None, None 50 | 51 | async def fetch_fake_address(code): 52 | try: 53 | res = await fake.address(code, 1) 54 | if isinstance(res, dict) and "country" in res: 55 | return res 56 | LOGGER.error(f"Faker invalid response: {res}") 57 | return None 58 | except Exception as e: 59 | LOGGER.error(f"Faker error: {e}") 60 | return None 61 | 62 | async def render_address(chat_id, code, user_id, bot, edit_msg=None): 63 | data = await fetch_fake_address(code) 64 | if not data: 65 | txt = "Failed to generate address" 66 | if edit_msg: 67 | await edit_msg.edit_text(txt, parse_mode=ParseMode.HTML) 68 | else: 69 | await send_message(chat_id, txt, ParseMode.HTML) 70 | return 71 | name, flag = get_flag(code) 72 | txt = ( 73 | f"Address for {name} {flag}\n" 74 | f"━━━━━━━━━━━━━\n" 75 | f"- Street : {data['building_number']} {data['street_name']}\n" 76 | f"- Street Name : {data['street_name']}\n" 77 | f"- Currency : {data['currency']}\n" 78 | f"- Full Name : {data['person_name']}\n" 79 | f"- City/Town/Village : {data['city']}\n" 80 | f"- Gender : {data['gender']}\n" 81 | f"- Postal Code : {data['postal_code']}\n" 82 | f"- Phone Number : {data['phone_number']}\n" 83 | f"- State : {data['state']}\n" 84 | f"- Country : {data['country']}\n" 85 | f"━━━━━━━━━━━━━\n" 86 | f"Click Below Button" 87 | ) 88 | btn = SmartButtons() 89 | cb = f"fake_regen|{code}|{user_id}" 90 | btn.button("Re-Generate", callback_data=cb) 91 | markup = btn.build_menu(b_cols=1) 92 | if edit_msg: 93 | await edit_msg.edit_text(txt, parse_mode=ParseMode.HTML, reply_markup=markup) 94 | else: 95 | await send_message(chat_id, txt, ParseMode.HTML, reply_markup=markup) 96 | 97 | @dp.message(Command(commands=["fake", "rnd"], prefix=BotCommands)) 98 | @new_task 99 | @SmartDefender 100 | async def fake_cmd(message: Message, bot: Bot): 101 | LOGGER.info(f"fake command from {message.from_user.id} in {message.chat.id}") 102 | prog = None 103 | try: 104 | args = get_args(message) 105 | if not args: 106 | prog = await send_message(message.chat.id, "Please provide country", ParseMode.HTML) 107 | return 108 | code, _ = resolve_country(args[0]) 109 | if not code or len(code) != 2: 110 | prog = await send_message(message.chat.id, "Invalid country", ParseMode.HTML) 111 | return 112 | prog = await send_message(message.chat.id, "Generating address...", ParseMode.HTML) 113 | uid = message.from_user.id if message.from_user else 0 114 | await delete_messages(message.chat.id, [prog.message_id]) 115 | await render_address(message.chat.id, code, uid, bot) 116 | except Exception as e: 117 | LOGGER.error(f"fake_cmd error: {e}") 118 | await Smart_Notify(bot, "fake", e, message) 119 | if prog: 120 | await delete_messages(message.chat.id, [prog.message_id]) 121 | await send_message(message.chat.id, "Generation failed", ParseMode.HTML) 122 | 123 | @dp.callback_query(lambda c: c.data and c.data.startswith("fake_regen|")) 124 | @new_task 125 | async def fake_regen_cb(callback_query: CallbackQuery, bot: Bot): 126 | LOGGER.info(f"fake_regen callback {callback_query.data}") 127 | try: 128 | _, code, uid_str = callback_query.data.split("|", 2) 129 | uid = int(uid_str) 130 | if callback_query.from_user.id != uid: 131 | await callback_query.answer("This Is Not Your's Kid", show_alert=True) 132 | return 133 | await render_address(callback_query.message.chat.id, code, uid, bot, edit_msg=callback_query.message) 134 | await callback_query.answer() 135 | except Exception as e: 136 | LOGGER.error(f"fake_regen_cb error: {e}") 137 | await Smart_Notify(bot, "fake_regen", e, callback_query.message) 138 | await callback_query.answer("Regen failed", show_alert=True) -------------------------------------------------------------------------------- /bot/modules/speedtest.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import asyncio 5 | import subprocess 6 | import json 7 | from concurrent.futures import ThreadPoolExecutor 8 | from aiogram import Bot 9 | from aiogram.filters import Command 10 | from aiogram.types import Message, CallbackQuery 11 | from pyrogram.enums import ParseMode as SmartParseMode 12 | from bot import dp, SmartPyro 13 | from bot.helpers.botutils import send_message, get_args 14 | from bot.helpers.commands import BotCommands 15 | from bot.helpers.buttons import SmartButtons 16 | from bot.helpers.logger import LOGGER 17 | from bot.helpers.notify import Smart_Notify 18 | from bot.helpers.guard import admin_only 19 | from config import UPDATE_CHANNEL_URL 20 | 21 | def speed_convert(size: float, is_mbps: bool = False) -> str: 22 | if is_mbps: 23 | return f"{size:.2f} Mbps" 24 | power = 2**10 25 | n = 0 26 | power_labels = {0: '', 1: 'K', 2: 'M', 3: 'G', 4: 'T'} 27 | while size > power: 28 | size /= power 29 | n += 1 30 | return f"{size:.2f} {power_labels[n]}bps" 31 | 32 | def get_readable_file_size(size_in_bytes: int) -> str: 33 | if size_in_bytes < 1024: 34 | return f"{size_in_bytes} B" 35 | power = 1024 36 | n = 0 37 | power_labels = {0: 'B', 1: 'KB', 2: 'MB', 3: 'GB', 4: 'TB'} 38 | while size_in_bytes >= power: 39 | size_in_bytes /= power 40 | n += 1 41 | return f"{size_in_bytes:.2f} {power_labels[n]}" 42 | 43 | def run_speedtest(): 44 | try: 45 | result = subprocess.run(["speedtest-cli", "--secure", "--json"], capture_output=True, text=True) 46 | if result.returncode != 0: 47 | raise Exception("Speedtest failed.") 48 | data = json.loads(result.stdout) 49 | return data 50 | except Exception as e: 51 | LOGGER.error(f"Speedtest error: {e}") 52 | return {"error": str(e)} 53 | 54 | def validate_message(func): 55 | async def wrapper(message: Message, bot: Bot): 56 | if not message or not message.from_user: 57 | LOGGER.error("Invalid message received") 58 | return 59 | return await func(message, bot) 60 | return wrapper 61 | 62 | async def run_speedtest_task(bot: Bot, chat_id: int, status_message_id: int): 63 | with ThreadPoolExecutor() as pool: 64 | try: 65 | result = await asyncio.get_running_loop().run_in_executor(pool, run_speedtest) 66 | except Exception as e: 67 | LOGGER.error(f"Error running speedtest task: {e}") 68 | try: 69 | await bot.edit_message_text( 70 | chat_id=chat_id, 71 | message_id=status_message_id, 72 | text="Speed Test API Dead ❌ ", 73 | parse_mode=SmartParseMode.HTML 74 | ) 75 | except Exception as edit_error: 76 | await Smart_Notify(bot, "run_speedtest_task", edit_error) 77 | LOGGER.error(f"Failed to edit speedtest message: {edit_error}") 78 | return 79 | 80 | if "error" in result: 81 | try: 82 | await bot.edit_message_text( 83 | chat_id=chat_id, 84 | message_id=status_message_id, 85 | text="Speed Test Failed ❌ ", 86 | parse_mode=SmartParseMode.HTML 87 | ) 88 | except Exception as edit_error: 89 | await Smart_Notify(bot, "run_speedtest_task", edit_error) 90 | LOGGER.error(f"Failed to edit speedtest failed message: {edit_error}") 91 | return 92 | 93 | response_text = ( 94 | "Smart Speedtest Check → Successful ✅\n" 95 | "━━━━━━━━━━━━━━━━━\n" 96 | f"⊗ Download: {speed_convert(result['download'])}\n" 97 | f"⊗ Upload: {speed_convert(result['upload'])}\n" 98 | f"⊗ Ping: {result['ping']:.2f} ms\n" 99 | f"⊗ Internet Provider: {result['client']['isp']}\n" 100 | "━━━━━━━━━━━━━━━━━\n" 101 | "Smart SpeedTester → Activated ✅" 102 | ) 103 | 104 | buttons = SmartButtons() 105 | buttons.button(text="More Info", url=UPDATE_CHANNEL_URL) 106 | reply_markup = buttons.build_menu(b_cols=1) 107 | 108 | try: 109 | await bot.edit_message_text( 110 | chat_id=chat_id, 111 | message_id=status_message_id, 112 | text=response_text, 113 | parse_mode=SmartParseMode.HTML, 114 | reply_markup=reply_markup 115 | ) 116 | except Exception as edit_error: 117 | await Smart_Notify(bot, "run_speedtest_task", edit_error) 118 | LOGGER.error(f"Failed to edit speedtest result message: {edit_error}") 119 | 120 | @dp.message(Command(commands=["speedtest"], prefix=BotCommands)) 121 | @validate_message 122 | @admin_only 123 | async def speedtest_handler(message: Message, bot: Bot): 124 | try: 125 | status_message = await send_message( 126 | chat_id=message.chat.id, 127 | text="Processing SpeedTest Please Wait....", 128 | parse_mode=SmartParseMode.HTML 129 | ) 130 | 131 | if status_message: 132 | asyncio.create_task(run_speedtest_task(bot, message.chat.id, status_message.message_id)) 133 | LOGGER.info(f"Speedtest command initiated by user_id {message.from_user.id}") 134 | else: 135 | await send_message( 136 | chat_id=message.chat.id, 137 | text="❌ Failed to start speedtest!", 138 | parse_mode=SmartParseMode.HTML 139 | ) 140 | LOGGER.error(f"Failed to send initial speedtest message for user_id {message.from_user.id}") 141 | 142 | except Exception as e: 143 | await Smart_Notify(bot, "speedtest_handler", e, message) 144 | LOGGER.error(f"Failed to handle speedtest command for user_id {message.from_user.id}: {e}") 145 | await send_message( 146 | chat_id=message.chat.id, 147 | text="❌ Failed to initiate speedtest!", 148 | parse_mode=SmartParseMode.HTML 149 | ) -------------------------------------------------------------------------------- /bot/modules/audio.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import os 5 | import time 6 | import asyncio 7 | from concurrent.futures import ThreadPoolExecutor 8 | from aiogram import Bot 9 | from aiogram.filters import Command 10 | from aiogram.types import Message 11 | from aiogram.enums import ParseMode 12 | from aiogram.exceptions import TelegramBadRequest 13 | from pyrogram.enums import ParseMode as SmartParseMode 14 | from bot import dp, SmartPyro 15 | from bot.helpers.utils import new_task, clean_download 16 | from bot.helpers.botutils import send_message, delete_messages, get_args 17 | from bot.helpers.commands import BotCommands 18 | from bot.helpers.logger import LOGGER 19 | from bot.helpers.notify import Smart_Notify 20 | from bot.helpers.defend import SmartDefender 21 | 22 | DOWNLOAD_DIRECTORY = "./downloads/" 23 | 24 | if not os.path.exists(DOWNLOAD_DIRECTORY): 25 | os.makedirs(DOWNLOAD_DIRECTORY) 26 | 27 | executor = ThreadPoolExecutor(max_workers=5) 28 | 29 | def convert_video_to_audio(video_file_path, audio_file_path): 30 | import subprocess 31 | process = subprocess.run( 32 | ["ffmpeg", "-i", video_file_path, audio_file_path], 33 | stdout=subprocess.PIPE, 34 | stderr=subprocess.PIPE 35 | ) 36 | if process.returncode != 0: 37 | raise Exception(f"ffmpeg error: {process.stderr.decode()}") 38 | 39 | @dp.message(Command(commands=["aud", "convert"], prefix=BotCommands)) 40 | @new_task 41 | @SmartDefender 42 | async def aud_handler(message: Message, bot: Bot): 43 | LOGGER.info(f"Received /aud or /convert command from user: {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 44 | 45 | # Initialize all variables before try block 46 | progress_message = None 47 | video_file_path = None 48 | audio_file_path = None 49 | 50 | try: 51 | if not message.reply_to_message or not message.reply_to_message.video: 52 | progress_message = await send_message( 53 | chat_id=message.chat.id, 54 | text="❌ Reply To A Video With The Command", 55 | parse_mode=ParseMode.HTML, 56 | disable_web_page_preview=True 57 | ) 58 | LOGGER.warning("No valid video provided for /aud or /convert command") 59 | return 60 | 61 | command_parts = get_args(message) 62 | if not command_parts: 63 | progress_message = await send_message( 64 | chat_id=message.chat.id, 65 | text="❌ Provide Name For The File", 66 | parse_mode=ParseMode.HTML, 67 | disable_web_page_preview=True 68 | ) 69 | LOGGER.warning("No audio file name provided for /aud or /convert command") 70 | return 71 | 72 | audio_file_name = command_parts[0] 73 | progress_message = await send_message( 74 | chat_id=message.chat.id, 75 | text="Downloading Your File...✨", 76 | parse_mode=ParseMode.HTML, 77 | disable_web_page_preview=True 78 | ) 79 | 80 | video_file_id = message.reply_to_message.video.file_id 81 | video_file_path = os.path.join(DOWNLOAD_DIRECTORY, f"video_{message.chat.id}.mp4") 82 | await SmartPyro.download_media( 83 | message=video_file_id, 84 | file_name=video_file_path 85 | ) 86 | LOGGER.info(f"Downloaded video file to {video_file_path}") 87 | 88 | await progress_message.edit_text( 89 | text="Converting To Mp3...✨", 90 | parse_mode=ParseMode.HTML 91 | ) 92 | 93 | audio_file_path = os.path.join(DOWNLOAD_DIRECTORY, f"{audio_file_name}.mp3") 94 | loop = asyncio.get_event_loop() 95 | await loop.run_in_executor(executor, convert_video_to_audio, video_file_path, audio_file_path) 96 | LOGGER.info(f"Converted video to audio at {audio_file_path}") 97 | 98 | start_time = time.time() 99 | last_update_time = [start_time] 100 | await SmartPyro.send_audio( 101 | chat_id=message.chat.id, 102 | audio=audio_file_path, 103 | caption=f"{audio_file_name}", 104 | parse_mode=SmartParseMode.HTML 105 | ) 106 | LOGGER.info("Audio file uploaded successfully") 107 | 108 | await delete_messages(message.chat.id, progress_message.message_id) 109 | LOGGER.info(f"Successfully processed /aud command for user {message.from_user.id} in chat {message.chat.id}") 110 | 111 | except Exception as e: 112 | LOGGER.error(f"Error processing /aud or /convert command in chat {message.chat.id}: {str(e)}") 113 | await Smart_Notify(bot, "aud/convert", e, message) 114 | error_text = "❌ Sorry Bro Converter API Error" 115 | 116 | if progress_message: 117 | try: 118 | await progress_message.edit_text( 119 | text=error_text, 120 | parse_mode=ParseMode.HTML 121 | ) 122 | LOGGER.info(f"Edited progress message with error in chat {message.chat.id}") 123 | except TelegramBadRequest as edit_e: 124 | LOGGER.error(f"Failed to edit progress message in chat {message.chat.id}: {str(edit_e)}") 125 | await Smart_Notify(bot, "aud/convert", edit_e, message) 126 | await send_message( 127 | chat_id=message.chat.id, 128 | text=error_text, 129 | parse_mode=ParseMode.HTML 130 | ) 131 | LOGGER.info(f"Sent error message to chat {message.chat.id}") 132 | else: 133 | await send_message( 134 | chat_id=message.chat.id, 135 | text=error_text, 136 | parse_mode=ParseMode.HTML 137 | ) 138 | LOGGER.info(f"Sent error message to chat {message.chat.id}") 139 | finally: 140 | 141 | if video_file_path and os.path.exists(video_file_path): 142 | try: 143 | os.remove(video_file_path) 144 | except: 145 | pass 146 | if audio_file_path and os.path.exists(audio_file_path): 147 | try: 148 | os.remove(audio_file_path) 149 | except: 150 | pass 151 | -------------------------------------------------------------------------------- /bot/modules/getusr.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | from aiogram import Bot 5 | from aiogram.filters import Command 6 | from aiogram.types import Message, FSInputFile 7 | from aiogram.enums import ParseMode, ChatType 8 | from bot import dp 9 | from bot.helpers.utils import new_task, clean_download 10 | from bot.helpers.botutils import send_message, delete_messages, get_args 11 | from bot.helpers.commands import BotCommands 12 | from bot.helpers.logger import LOGGER 13 | from bot.helpers.notify import Smart_Notify 14 | from bot.helpers.defend import SmartDefender 15 | from config import A360APIBASEURL 16 | import aiohttp 17 | import aiofiles 18 | import json 19 | from typing import Optional 20 | 21 | @dp.message(Command(commands=["getusers"], prefix=BotCommands)) 22 | @new_task 23 | @SmartDefender 24 | async def get_users(message: Message, bot: Bot) -> None: 25 | user_id = message.from_user.id 26 | chat_id = message.chat.id 27 | LOGGER.info(f"User {user_id} initiated /getusers command in chat {chat_id}") 28 | 29 | if message.chat.type != ChatType.PRIVATE: 30 | LOGGER.info(f"User {user_id} attempted /getusers in non-private chat {chat_id}") 31 | await send_message( 32 | chat_id=chat_id, 33 | text="❌ This command is only available in private chats.", 34 | parse_mode=ParseMode.HTML 35 | ) 36 | return 37 | 38 | args = get_args(message) 39 | if not args: 40 | LOGGER.error(f"User {user_id} provided no bot token") 41 | await send_message( 42 | chat_id=chat_id, 43 | text="❌ Please provide a valid bot token after the command.", 44 | parse_mode=ParseMode.HTML 45 | ) 46 | return 47 | 48 | bot_token = args[0].strip() 49 | loading_message = await send_message( 50 | chat_id=chat_id, 51 | text="Fetching user data...", 52 | parse_mode=ParseMode.HTML 53 | ) 54 | 55 | LOGGER.info(f"Validating bot token ending in {bot_token[-4:]}") 56 | bot_info = await validate_bot_token(bot_token) 57 | if bot_info is None: 58 | LOGGER.error(f"Invalid bot token provided by user {user_id}") 59 | await loading_message.edit_text( 60 | text="❌ Invalid Bot Token Provided", 61 | parse_mode=ParseMode.HTML, 62 | disable_web_page_preview=True 63 | ) 64 | return 65 | 66 | LOGGER.info(f"Fetching data for bot {bot_info.get('username', 'N/A')}") 67 | data = await fetch_bot_data(bot_token) 68 | if data is None: 69 | LOGGER.error(f"Failed to fetch user data for user {user_id}") 70 | await loading_message.edit_text( 71 | text="❌ Failed to fetch user data", 72 | parse_mode=ParseMode.HTML, 73 | disable_web_page_preview=True 74 | ) 75 | return 76 | 77 | file_path = f"users_{user_id}.json" 78 | temp_files = [file_path] 79 | try: 80 | await save_and_send_data(bot, chat_id, data, file_path) 81 | LOGGER.info(f"Successfully sent user data to user {user_id} in chat {chat_id}") 82 | await delete_messages(chat_id, loading_message.message_id) 83 | except Exception as e: 84 | LOGGER.exception(f"Error processing data for user {user_id}: {str(e)}") 85 | await Smart_Notify(bot, "/getusers", e, message) 86 | await loading_message.edit_text( 87 | text="❌ Error processing data", 88 | parse_mode=ParseMode.HTML, 89 | disable_web_page_preview=True 90 | ) 91 | finally: 92 | clean_download(*temp_files) 93 | 94 | async def validate_bot_token(bot_token: str) -> Optional[dict]: 95 | try: 96 | async with aiohttp.ClientSession() as session: 97 | async with session.get(f"https://api.telegram.org/bot{bot_token}/getMe") as resp: 98 | if resp.status != 200: 99 | LOGGER.warning(f"Telegram API returned status {resp.status} for bot token") 100 | return None 101 | data = await resp.json() 102 | if not data.get("ok", False) or "result" not in data: 103 | LOGGER.warning(f"Invalid Telegram API response: {data}") 104 | return None 105 | return data["result"] 106 | except aiohttp.ClientError as e: 107 | LOGGER.error(f"Telegram API request failed: {str(e)}") 108 | return None 109 | 110 | async def fetch_bot_data(bot_token: str) -> Optional[dict]: 111 | try: 112 | async with aiohttp.ClientSession() as session: 113 | async with session.get(f"{A360APIBASEURL}/tgusers?token={bot_token}") as resp: 114 | if resp.status != 200: 115 | LOGGER.warning(f"API returned status {resp.status} for bot token") 116 | return None 117 | data = await resp.json() 118 | if not isinstance(data, dict) or "bot_info" not in data or "users" not in data or "chats" not in data: 119 | LOGGER.error(f"Invalid API response structure for bot token") 120 | return None 121 | return data 122 | except aiohttp.ClientError as e: 123 | LOGGER.error(f"API request failed: {str(e)}") 124 | return None 125 | 126 | async def save_and_send_data(bot: Bot, chat_id: int, data: dict, file_path: str) -> None: 127 | async with aiofiles.open(file_path, mode='w') as f: 128 | await f.write(json.dumps(data, indent=4)) 129 | LOGGER.debug(f"Saved data to {file_path}") 130 | 131 | bot_info = data.get("bot_info", {}) 132 | total_users = data.get("total_users", 0) 133 | total_chats = data.get("total_chats", 0) 134 | 135 | caption = ( 136 | "📌 Requested Users\n" 137 | "━━━━━━━━\n" 138 | f"👤 Username: {bot_info.get('username', 'N/A')}\n" 139 | f"👥 Total Users: {total_users}\n" 140 | f"👥 Total Chats: {total_chats}\n" 141 | "━━━━━━━━\n" 142 | "📂 File contains user & chat IDs." 143 | ) 144 | 145 | await bot.send_document( 146 | chat_id=chat_id, 147 | document=FSInputFile(file_path), 148 | caption=caption, 149 | parse_mode=ParseMode.HTML 150 | ) 151 | LOGGER.info(f"Sent document to chat {chat_id}") -------------------------------------------------------------------------------- /bot/modules/voice.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import os 5 | import time 6 | import asyncio 7 | from aiogram import Bot 8 | from aiogram.filters import Command 9 | from aiogram.types import Message 10 | from aiogram.enums import ParseMode 11 | from aiogram.exceptions import TelegramBadRequest 12 | from pyrogram.enums import ParseMode as SmartParseMode 13 | from bot import dp, SmartPyro 14 | from bot.helpers.utils import new_task, clean_download 15 | from bot.helpers.botutils import send_message, delete_messages, get_args 16 | from bot.helpers.commands import BotCommands 17 | from bot.helpers.logger import LOGGER 18 | from bot.helpers.notify import Smart_Notify 19 | from bot.helpers.defend import SmartDefender 20 | from pydub import AudioSegment 21 | 22 | DOWNLOAD_DIRECTORY = "./downloads/" 23 | if not os.path.exists(DOWNLOAD_DIRECTORY): 24 | os.makedirs(DOWNLOAD_DIRECTORY) 25 | 26 | async def convert_audio(input_path, output_path): 27 | audio = AudioSegment.from_file(input_path) 28 | audio.export(output_path, format="ogg", codec="libopus") 29 | 30 | @dp.message(Command(commands=["voice"], prefix=BotCommands)) 31 | @new_task 32 | @SmartDefender 33 | async def voice_handler(message: Message, bot: Bot): 34 | LOGGER.info(f"Received /voice command from user: {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 35 | 36 | # Initialize all variables before try block 37 | progress_message = None 38 | input_path = None 39 | output_path = None 40 | 41 | try: 42 | if not message.reply_to_message or not (message.reply_to_message.audio or message.reply_to_message.voice or message.reply_to_message.document): 43 | progress_message = await send_message( 44 | chat_id=message.chat.id, 45 | text="❌ Reply To An Audio Or Voice Message", 46 | parse_mode=ParseMode.HTML, 47 | disable_web_page_preview=True 48 | ) 49 | LOGGER.warning("No valid audio/voice provided for /voice command") 50 | return 51 | 52 | file_id = None 53 | file_extension = "" 54 | 55 | if message.reply_to_message.audio and message.reply_to_message.audio.file_name: 56 | file_id = message.reply_to_message.audio.file_id 57 | file_extension = message.reply_to_message.audio.file_name.split('.')[-1].lower() 58 | elif message.reply_to_message.voice: 59 | file_id = message.reply_to_message.voice.file_id 60 | file_extension = "ogg" 61 | elif message.reply_to_message.document and message.reply_to_message.document.file_name: 62 | file_id = message.reply_to_message.document.file_id 63 | file_extension = message.reply_to_message.document.file_name.split('.')[-1].lower() 64 | 65 | valid_audio_extensions = ['mp3', 'wav', 'ogg', 'm4a'] 66 | if file_extension and file_extension not in valid_audio_extensions: 67 | progress_message = await send_message( 68 | chat_id=message.chat.id, 69 | text="❌ Reply To A Valid Audio File (mp3, wav, ogg, m4a)", 70 | parse_mode=ParseMode.HTML, 71 | disable_web_page_preview=True 72 | ) 73 | LOGGER.warning(f"Invalid audio format provided: {file_extension}") 74 | return 75 | 76 | progress_message = await send_message( 77 | chat_id=message.chat.id, 78 | text="Converting To Voice Message...✨", 79 | parse_mode=ParseMode.HTML, 80 | disable_web_page_preview=True 81 | ) 82 | 83 | input_path = os.path.join(DOWNLOAD_DIRECTORY, f"input_{message.chat.id}.{file_extension if file_extension else 'ogg'}") 84 | output_path = os.path.join(DOWNLOAD_DIRECTORY, f"output_{message.chat.id}.ogg") 85 | 86 | await SmartPyro.download_media( 87 | message=file_id, 88 | file_name=input_path 89 | ) 90 | LOGGER.info(f"Downloaded audio file to {input_path}") 91 | 92 | await convert_audio(input_path, output_path) 93 | LOGGER.info(f"Converted audio to voice at {output_path}") 94 | 95 | await SmartPyro.send_voice( 96 | chat_id=message.chat.id, 97 | voice=output_path, 98 | caption="", 99 | parse_mode=SmartParseMode.HTML 100 | ) 101 | LOGGER.info("Voice message uploaded successfully") 102 | 103 | await delete_messages(message.chat.id, progress_message.message_id) 104 | LOGGER.info(f"Successfully processed /voice command for user {message.from_user.id} in chat {message.chat.id}") 105 | 106 | except Exception as e: 107 | LOGGER.error(f"Error processing /voice command in chat {message.chat.id}: {str(e)}") 108 | await Smart_Notify(bot, "voice", e, message) 109 | error_text = "❌ Sorry Bro Converter API Error" 110 | 111 | if progress_message: 112 | try: 113 | await progress_message.edit_text( 114 | text=error_text, 115 | parse_mode=ParseMode.HTML 116 | ) 117 | LOGGER.info(f"Edited progress message with error in chat {message.chat.id}") 118 | except TelegramBadRequest as edit_e: 119 | LOGGER.error(f"Failed to edit progress message in chat {message.chat.id}: {str(edit_e)}") 120 | await Smart_Notify(bot, "voice", edit_e, message) 121 | await send_message( 122 | chat_id=message.chat.id, 123 | text=error_text, 124 | parse_mode=ParseMode.HTML 125 | ) 126 | LOGGER.info(f"Sent error message to chat {message.chat.id}") 127 | else: 128 | await send_message( 129 | chat_id=message.chat.id, 130 | text=error_text, 131 | parse_mode=ParseMode.HTML 132 | ) 133 | LOGGER.info(f"Sent error message to chat {message.chat.id}") 134 | finally: 135 | 136 | if input_path and os.path.exists(input_path): 137 | try: 138 | os.remove(input_path) 139 | except: 140 | pass 141 | if output_path and os.path.exists(output_path): 142 | try: 143 | os.remove(output_path) 144 | except: 145 | pass 146 | -------------------------------------------------------------------------------- /bot/modules/dmn.py: -------------------------------------------------------------------------------- 1 | import aiohttp 2 | import asyncio 3 | from aiogram import Bot 4 | from aiogram.filters import Command 5 | from aiogram.types import Message 6 | from aiogram.enums import ParseMode, ChatType 7 | from bot import dp, SmartAIO 8 | from bot.helpers.utils import new_task 9 | from bot.helpers.botutils import send_message, delete_messages, get_args 10 | from bot.helpers.notify import Smart_Notify 11 | from bot.helpers.logger import LOGGER 12 | from bot.helpers.commands import BotCommands 13 | from bot.helpers.defend import SmartDefender 14 | from config import A360APIBASEURL, DOMAIN_CHK_LIMIT 15 | 16 | logger = LOGGER 17 | 18 | async def get_domain_info(domain: str, bot: Bot) -> str: 19 | url = f"{A360APIBASEURL}/dmn" 20 | params = {"domain": domain} 21 | try: 22 | async with aiohttp.ClientSession() as session: 23 | async with session.get(url, params=params) as response: 24 | response.raise_for_status() 25 | data = await response.json() 26 | logger.info(f"Response for domain {domain}: {data}") 27 | domain_name = data.get("domain", domain) 28 | if data.get("registered_on") is None: 29 | return ( 30 | f"Smart A360 Domain Check Results...✅\n" 31 | f"━━━━━━━━━━━━━━━━━━\n" 32 | f"Domain : {domain_name}\n" 33 | f"Congrats !🥳 This Domain Is Available. ✅\n" 34 | f"━━━━━━━━━━━━━━━━━━" 35 | ) 36 | else: 37 | registrar = data.get("registrar", "Unknown") 38 | registered_on = data.get("registered_on", "Unknown") 39 | expires_on = data.get("expires_on", "Unknown") 40 | return ( 41 | f"Smart A360 Domain Check Results...✅\n" 42 | f"━━━━━━━━━━━━━━━━━━\n" 43 | f"Domain : {domain_name}\n" 44 | f"Registrar : {registrar}\n" 45 | f"Registration Date : {registered_on}\n" 46 | f"Expiration Date : {expires_on}\n" 47 | f"━━━━━━━━━━━━━━━━━━" 48 | ) 49 | except aiohttp.ClientError as e: 50 | logger.error(f"Failed to fetch info for domain {domain}: {e}") 51 | await Smart_Notify(bot, "/dmn", e, None) 52 | return f"❌ Sorry Bro Domain API Dead" 53 | except Exception as e: 54 | logger.error(f"Exception occurred while fetching info for domain {domain}: {e}") 55 | await Smart_Notify(bot, "/dmn", e, None) 56 | return f"❌ Sorry Bro Domain Check API Dead" 57 | 58 | @dp.message(Command(commands=["dmn", ".dmn"], prefix=BotCommands)) 59 | @new_task 60 | @SmartDefender 61 | async def domain_info(message: Message, bot: Bot): 62 | if message.chat.type not in [ChatType.PRIVATE, ChatType.GROUP, ChatType.SUPERGROUP]: 63 | await send_message( 64 | chat_id=message.chat.id, 65 | text="❌ This command only works in private or group chats", 66 | parse_mode=ParseMode.HTML 67 | ) 68 | return 69 | user_id = message.from_user.id 70 | logger.info(f"Command received from user {user_id} in chat {message.chat.id}: {message.text}") 71 | domains = get_args(message) 72 | if not domains: 73 | await send_message( 74 | chat_id=message.chat.id, 75 | text="❌ Please provide at least one valid domain name.", 76 | parse_mode=ParseMode.HTML 77 | ) 78 | return 79 | if len(domains) > DOMAIN_CHK_LIMIT: 80 | await send_message( 81 | chat_id=message.chat.id, 82 | text=f"❌ You can check up to {DOMAIN_CHK_LIMIT} domains at a time.", 83 | parse_mode=ParseMode.HTML 84 | ) 85 | return 86 | progress_message = await send_message( 87 | chat_id=message.chat.id, 88 | text="Fetching domain information...✨", 89 | parse_mode=ParseMode.HTML 90 | ) 91 | try: 92 | results = await asyncio.gather(*[get_domain_info(domain, bot) for domain in domains], return_exceptions=True) 93 | result_message = [] 94 | for domain, result in zip(domains, results): 95 | if isinstance(result, Exception): 96 | logger.error(f"Error processing domain {domain}: {result}") 97 | await Smart_Notify(bot, "/dmn", result, message) 98 | result_message.append(f"❌ {domain}: Failed to check domain") 99 | else: 100 | result_message.append(result) 101 | if message.from_user: 102 | user_full_name = f"{message.from_user.first_name} {message.from_user.last_name or ''}".strip() 103 | user_info = f"\nDomain Info Grab By : {user_full_name}" 104 | else: 105 | group_name = message.chat.title or "this group" 106 | group_url = f"https://t.me/{message.chat.username}" if message.chat.username else "this group" 107 | user_info = f"\nDomain Info Grab By : {group_name}" 108 | result_message = "\n\n".join(result_message) + user_info 109 | try: 110 | await progress_message.edit_text( 111 | text=result_message, 112 | parse_mode=ParseMode.HTML 113 | ) 114 | except Exception: 115 | await delete_messages( 116 | chat_id=message.chat.id, 117 | message_ids=[progress_message.message_id] 118 | ) 119 | await send_message( 120 | chat_id=message.chat.id, 121 | text=result_message, 122 | parse_mode=ParseMode.HTML 123 | ) 124 | except Exception as e: 125 | logger.error(f"Error processing domain check: {e}") 126 | await Smart_Notify(bot, "/dmn", e, message) 127 | try: 128 | await progress_message.edit_text( 129 | text="❌ Sorry Bro Domain Check API Dead", 130 | parse_mode=ParseMode.HTML 131 | ) 132 | except Exception: 133 | await delete_messages( 134 | chat_id=message.chat.id, 135 | message_ids=[progress_message.message_id] 136 | ) 137 | await send_message( 138 | chat_id=message.chat.id, 139 | text="❌ Sorry Bro Domain Check API Dead", 140 | parse_mode=ParseMode.HTML 141 | ) -------------------------------------------------------------------------------- /bot/modules/crypt.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import aiohttp 5 | import asyncio 6 | from aiogram import Bot 7 | from aiogram.filters import Command, BaseFilter 8 | from aiogram.types import Message, CallbackQuery 9 | from aiogram.enums import ParseMode 10 | from bot import dp 11 | from bot.helpers.utils import new_task 12 | from bot.helpers.botutils import send_message, delete_messages 13 | from bot.helpers.commands import BotCommands 14 | from bot.helpers.buttons import SmartButtons 15 | from bot.helpers.logger import LOGGER 16 | from bot.helpers.notify import Smart_Notify 17 | from bot.helpers.defend import SmartDefender 18 | from config import A360APIBASEURL 19 | BASE_URL = f"{A360APIBASEURL}/binance/24h" 20 | async def fetch_crypto_data(): 21 | try: 22 | async with aiohttp.ClientSession() as session: 23 | async with session.get(BASE_URL) as response: 24 | response.raise_for_status() 25 | data = await response.json() 26 | if not data.get("success", False): 27 | LOGGER.error("API returned success: false") 28 | raise Exception("API returned success: false") 29 | LOGGER.info("Successfully fetched crypto data from A360 API") 30 | return data['data'] 31 | except Exception as e: 32 | LOGGER.error(f"Error fetching crypto data: {e}") 33 | raise Exception("Unable to fetch data from A360 API") 34 | def get_top_gainers(data, top_n=5): 35 | return sorted(data, key=lambda x: float(x['priceChangePercent']), reverse=True)[:top_n] 36 | def get_top_losers(data, top_n=5): 37 | return sorted(data, key=lambda x: float(x['priceChangePercent']))[:top_n] 38 | def format_crypto_info(data, start_index=0): 39 | result = "" 40 | for idx, item in enumerate(data, start=start_index + 1): 41 | result += ( 42 | f"{idx}. Symbol: {item['symbol']}\n" 43 | f" Change: {item['priceChangePercent']}%\n" 44 | f" Last Price: {item['lastPrice']}\n" 45 | f" 24h High: {item['highPrice']}\n" 46 | f" 24h Low: {item['lowPrice']}\n" 47 | f" 24h Volume: {item['volume']}\n" 48 | f" 24h Quote Volume: {item['quoteVolume']}\n\n" 49 | ) 50 | return result 51 | class CryptoCallbackFilter(BaseFilter): 52 | async def __call__(self, callback_query: CallbackQuery): 53 | return callback_query.data.startswith(("gainers_", "losers_")) 54 | @dp.message(Command(commands=["gainers", "losers"], prefix=BotCommands)) 55 | @new_task 56 | @SmartDefender 57 | async def crypto_handle_command(message: Message, bot: Bot): 58 | command_text = message.text.split()[0] 59 | command = None 60 | for prefix in BotCommands: 61 | if command_text.startswith(prefix): 62 | command = command_text[len(prefix):].lower() 63 | break 64 | if not command: 65 | command = command_text.lower() 66 | progress_message = await send_message( 67 | chat_id=message.chat.id, 68 | text=f"Fetching Top ⚡️ {command}...", 69 | parse_mode=ParseMode.HTML 70 | ) 71 | try: 72 | data = await fetch_crypto_data() 73 | top_n = 5 74 | if command == "gainers": 75 | top_cryptos = get_top_gainers(data, top_n) 76 | title = "Gainers" 77 | else: 78 | top_cryptos = get_top_losers(data, top_n) 79 | title = "Losers" 80 | formatted_info = format_crypto_info(top_cryptos) 81 | response_message = f"List Of Top {title}:\n\n{formatted_info}" 82 | buttons = SmartButtons() 83 | buttons.button(text="➡️ Next", callback_data=f"{command}_1") 84 | await delete_messages(message.chat.id, [progress_message.message_id]) 85 | await send_message( 86 | chat_id=message.chat.id, 87 | text=response_message, 88 | parse_mode=ParseMode.HTML, 89 | reply_markup=buttons.build_menu(b_cols=1) 90 | ) 91 | LOGGER.info(f"Sent top {title.lower()} to chat {message.chat.id}") 92 | except Exception as e: 93 | await delete_messages(message.chat.id, [progress_message.message_id]) 94 | await send_message( 95 | chat_id=message.chat.id, 96 | text="❌ Error: Unable to fetch data from A360 API", 97 | parse_mode=ParseMode.HTML 98 | ) 99 | LOGGER.error(f"Error processing /{command}: {e}") 100 | await Smart_Notify(bot, f"/{command}", e, message) 101 | @dp.callback_query(CryptoCallbackFilter()) 102 | @new_task 103 | @SmartDefender 104 | async def crypto_handle_pagination(callback_query: CallbackQuery, bot: Bot): 105 | command, page = callback_query.data.split('_') 106 | page = int(page) 107 | next_page = page + 1 108 | prev_page = page - 1 109 | try: 110 | data = await fetch_crypto_data() 111 | top_n = 5 112 | if command == "gainers": 113 | top_cryptos = get_top_gainers(data, top_n * next_page)[page*top_n:(page+1)*top_n] 114 | title = "Gainers" 115 | else: 116 | top_cryptos = get_top_losers(data, top_n * next_page)[page*top_n:(page+1)*top_n] 117 | title = "Losers" 118 | if not top_cryptos: 119 | await callback_query.answer(f"No more {title.lower()} to display", show_alert=True) 120 | LOGGER.info(f"No more {title.lower()} for page {page} in chat {callback_query.message.chat.id}") 121 | return 122 | formatted_info = format_crypto_info(top_cryptos, start_index=page*top_n) 123 | response_message = f"List Of Top {title} (Page {page + 1}):\n\n{formatted_info}" 124 | buttons = SmartButtons() 125 | if prev_page >= 0: 126 | buttons.button(text="⬅️ Previous", callback_data=f"{command}_{prev_page}") 127 | if len(top_cryptos) == top_n: 128 | buttons.button(text="➡️ Next", callback_data=f"{command}_{next_page}") 129 | await callback_query.message.edit_text( 130 | text=response_message, 131 | parse_mode=ParseMode.HTML, 132 | reply_markup=buttons.build_menu(b_cols=2) 133 | ) 134 | await callback_query.answer() 135 | LOGGER.info(f"Updated pagination for {command} (page {page + 1}) in chat {callback_query.message.chat.id}") 136 | except Exception as e: 137 | await callback_query.answer("❌ Error fetching data", show_alert=True) 138 | LOGGER.error(f"Error in pagination for {command} (page {page + 1}): {e}") 139 | await Smart_Notify(bot, f"/{command} pagination", e, callback_query.message) -------------------------------------------------------------------------------- /bot/modules/m2t.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | from datetime import datetime 4 | from pathlib import Path 5 | from typing import Optional 6 | 7 | from aiogram import Bot 8 | from aiogram.filters import Command 9 | from aiogram.types import Message, FSInputFile 10 | from aiogram.enums import ParseMode 11 | 12 | from bot import dp 13 | from bot.helpers.botutils import send_message, delete_messages, get_args 14 | from bot.helpers.commands import BotCommands 15 | from bot.helpers.logger import LOGGER 16 | from bot.helpers.utils import new_task, clean_download 17 | from bot.helpers.notify import Smart_Notify 18 | from bot.helpers.defend import SmartDefender 19 | 20 | TEMP_DIR = Path("./downloads") 21 | MAX_MESSAGES = 25 22 | TEMP_DIR.mkdir(exist_ok=True) 23 | 24 | def sanitize_filename(filename: str) -> str: 25 | invalid_chars = '<>:"/\\|?*' 26 | for char in invalid_chars: 27 | filename = filename.replace(char, '_') 28 | return filename.strip()[:100] 29 | 30 | async def extract_text_from_message(message: Message) -> Optional[str]: 31 | text_content = [] 32 | 33 | if message.text: 34 | text_content.append(message.text) 35 | elif message.caption: 36 | text_content.append(message.caption) 37 | 38 | if message.entities: 39 | for entity in message.entities: 40 | if entity.type in ["url", "text_link"]: 41 | if entity.type == "text_link": 42 | text_content.append(f"\n{entity.url}") 43 | 44 | if message.caption_entities: 45 | for entity in message.caption_entities: 46 | if entity.type in ["url", "text_link"]: 47 | if entity.type == "text_link": 48 | text_content.append(f"\n{entity.url}") 49 | 50 | return "\n".join(text_content) if text_content else None 51 | 52 | async def collect_messages_chain(message: Message, count: int) -> list: 53 | collected = [] 54 | current_message = message.reply_to_message 55 | 56 | if not current_message: 57 | return collected 58 | 59 | for i in range(count): 60 | if not current_message: 61 | break 62 | 63 | text = await extract_text_from_message(current_message) 64 | if text: 65 | collected.append({'text': text}) 66 | 67 | if current_message.reply_to_message: 68 | current_message = current_message.reply_to_message 69 | else: 70 | break 71 | 72 | return list(reversed(collected)) 73 | 74 | async def create_text_file(messages: list, filename: str) -> tuple: 75 | timestamp = int(time.time()) 76 | safe_filename = sanitize_filename(filename) 77 | if not safe_filename.endswith('.txt'): 78 | safe_filename += '.txt' 79 | 80 | filepath = TEMP_DIR / f"{safe_filename.rsplit('.', 1)[0]}_{timestamp}.txt" 81 | 82 | total_lines = 0 83 | total_chars = 0 84 | 85 | with open(filepath, 'w', encoding='utf-8') as f: 86 | for idx, msg in enumerate(messages, 1): 87 | f.write(msg['text']) 88 | if idx < len(messages): 89 | f.write("\n\n") 90 | 91 | total_lines += msg['text'].count('\n') + 1 92 | total_chars += len(msg['text']) 93 | 94 | return str(filepath), total_lines, total_chars 95 | 96 | @dp.message(Command(commands=["m2t"], prefix=BotCommands)) 97 | @new_task 98 | @SmartDefender 99 | async def message_to_text_handler(message: Message, bot: Bot): 100 | user_id = message.from_user.id 101 | 102 | if not message.reply_to_message: 103 | await send_message( 104 | chat_id=message.chat.id, 105 | text="Reply to a text message to convert → file", 106 | parse_mode=ParseMode.HTML 107 | ) 108 | LOGGER.info(f"User {user_id} used /m2t without replying to a message") 109 | return 110 | 111 | LOGGER.info(f"User {user_id} started /m2t command") 112 | 113 | try: 114 | args = get_args(message) 115 | 116 | filename = f"message_{int(time.time())}" 117 | count = 1 118 | 119 | if args: 120 | for arg in args: 121 | try: 122 | num = int(arg) 123 | count = min(max(num, 1), MAX_MESSAGES) 124 | except ValueError: 125 | filename = arg 126 | 127 | progress_msg = await send_message( 128 | chat_id=message.chat.id, 129 | text=f"📥 Collecting up to {count} message(s)...", 130 | parse_mode=ParseMode.HTML 131 | ) 132 | 133 | messages = await collect_messages_chain(message, count) 134 | 135 | if not messages: 136 | await delete_messages(message.chat.id, progress_msg.message_id) 137 | await send_message( 138 | chat_id=message.chat.id, 139 | text="❌ No text content found in the replied message(s)!", 140 | parse_mode=ParseMode.HTML 141 | ) 142 | LOGGER.warning(f"User {user_id} tried to convert messages with no text content") 143 | return 144 | 145 | actual_count = len(messages) 146 | 147 | await progress_msg.edit_text( 148 | f"📝 Creating text file from {actual_count} message(s)...", 149 | parse_mode=ParseMode.HTML 150 | ) 151 | 152 | filepath, total_lines, total_chars = await create_text_file(messages, filename) 153 | 154 | await progress_msg.edit_text( 155 | "📤 Uploading text file...", 156 | parse_mode=ParseMode.HTML 157 | ) 158 | 159 | caption = ( 160 | f"Message To Text Convert\n" 161 | f"━━━━━━━━━━━━━━\n" 162 | f"Messages: {actual_count}\n" 163 | f"Lines: {total_lines}\n" 164 | f"Characters: {total_chars}\n" 165 | f"━━━━━━━━━━━━━━\n" 166 | f"Thanks For Using SmartUtilBot 🤖" 167 | ) 168 | 169 | await bot.send_document( 170 | chat_id=message.chat.id, 171 | document=FSInputFile(filepath, filename=os.path.basename(filepath)), 172 | caption=caption, 173 | parse_mode=ParseMode.HTML 174 | ) 175 | 176 | await delete_messages(message.chat.id, progress_msg.message_id) 177 | 178 | clean_download(filepath) 179 | 180 | LOGGER.info(f"User {user_id} successfully exported {actual_count} message(s) to text file") 181 | 182 | except Exception as e: 183 | await Smart_Notify(bot, "message_to_text_handler", e, message) 184 | LOGGER.error(f"Failed to convert messages to text for user {user_id}: {e}") 185 | await send_message( 186 | chat_id=message.chat.id, 187 | text="❌ Failed to convert messages to text!", 188 | parse_mode=ParseMode.HTML 189 | ) -------------------------------------------------------------------------------- /bot/modules/decoders.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import os 5 | import asyncio 6 | import base64 7 | import binascii 8 | from aiogram import Bot 9 | from aiogram.filters import Command, BaseFilter 10 | from aiogram.types import Message, FSInputFile 11 | from aiogram.enums import ParseMode 12 | from aiogram.exceptions import TelegramBadRequest 13 | from bot import dp 14 | from bot.helpers.utils import new_task, clean_download 15 | from bot.helpers.botutils import send_message, delete_messages 16 | from bot.helpers.commands import BotCommands 17 | from bot.helpers.logger import LOGGER 18 | from bot.helpers.notify import Smart_Notify 19 | from bot.helpers.defend import SmartDefender 20 | from config import COMMAND_PREFIX, MAX_TXT_SIZE 21 | 22 | commands = { 23 | "b64en": lambda text: base64.b64encode(text.encode()).decode(), 24 | "b64de": lambda text: base64.b64decode(text).decode(), 25 | "b32en": lambda text: base64.b32encode(text.encode()).decode(), 26 | "b32de": lambda text: base64.b32decode(text).decode(), 27 | "binen": lambda text: ' '.join(format(ord(char), '08b') for char in text), 28 | "binde": lambda text: ''.join(chr(int(b, 2)) for b in text.split()), 29 | "hexen": lambda text: binascii.hexlify(text.encode()).decode(), 30 | "hexde": lambda text: binascii.unhexlify(text).decode(), 31 | "octen": lambda text: ' '.join(format(ord(char), '03o') for char in text), 32 | "octde": lambda text: ''.join(chr(int(o, 8)) for o in text.split()), 33 | "trev": lambda text: text[::-1], 34 | "tcap": lambda text: text.upper(), 35 | "tsm": lambda text: text.lower(), 36 | "wc": lambda text: ( 37 | "📊 Text Counter\n\n" + 38 | "✅ Words: " + str(len(text.split())) + "\n" + 39 | "✅ Characters: " + str(len(text)) + "\n" + 40 | "✅ Sentences: " + str(text.count('.') + text.count('!') + text.count('?')) + "\n" + 41 | "✅ Paragraphs: " + str(text.count('\n') + 1) + "" 42 | ) 43 | } 44 | 45 | class DecoderCommandFilter(BaseFilter): 46 | async def __call__(self, message: Message): 47 | if not message.text: 48 | return False 49 | return message.text.split()[0][1:] in commands 50 | 51 | @dp.message(DecoderCommandFilter()) 52 | @new_task 53 | @SmartDefender 54 | async def handle_command(message: Message, bot: Bot): 55 | file_path = None 56 | file_name = None 57 | try: 58 | command = message.text.split()[0][1:] 59 | func = commands[command] 60 | processing_msg = await send_message( 61 | chat_id=message.chat.id, 62 | text="Processing Your Input...✨", 63 | parse_mode=ParseMode.HTML 64 | ) 65 | text = None 66 | if message.reply_to_message: 67 | if message.reply_to_message.document: 68 | if message.reply_to_message.document.file_size > MAX_TXT_SIZE: 69 | await send_message( 70 | chat_id=message.chat.id, 71 | text=f"❌ File too large! Max size is {MAX_TXT_SIZE // 1024 // 1024}MB", 72 | parse_mode=ParseMode.HTML 73 | ) 74 | await delete_messages(message.chat.id, [processing_msg.message_id]) 75 | LOGGER.warning(f"File too large for /{command} in chat {message.chat.id}") 76 | return 77 | os.makedirs("./downloads", exist_ok=True) 78 | file_path = os.path.join("./downloads", message.reply_to_message.document.file_name or f"{command}_input.txt") 79 | await bot.download(message.reply_to_message.document, destination=file_path) 80 | with open(file_path, "r", encoding="utf-8") as file: 81 | text = file.read() 82 | else: 83 | text = message.reply_to_message.text 84 | else: 85 | text = message.text.split(maxsplit=1)[1] if len(message.text.split()) > 1 else None 86 | if not text: 87 | await send_message( 88 | chat_id=message.chat.id, 89 | text="⚠️ Please provide text or reply to a message/file❌", 90 | parse_mode=ParseMode.HTML 91 | ) 92 | await delete_messages(message.chat.id, [processing_msg.message_id]) 93 | LOGGER.warning(f"No text provided for /{command} in chat {message.chat.id}") 94 | if file_path: 95 | clean_download(file_path) 96 | return 97 | result = func(text) 98 | user_full_name = message.from_user.first_name + (" " + message.from_user.last_name if message.from_user.last_name else "") 99 | user_mention = f"{user_full_name}" 100 | LOGGER.info(f"Processed /{command} in chat {message.chat.id}") 101 | if len(result) > 4096: 102 | os.makedirs("./downloads", exist_ok=True) 103 | file_name = os.path.join("./downloads", f"{command}_result.txt") 104 | with open(file_name, "w", encoding="utf-8") as file: 105 | file.write(result) 106 | await bot.send_document( 107 | chat_id=message.chat.id, 108 | document=FSInputFile(path=file_name), 109 | caption=( 110 | f"✨ Here is your processed file! ✨\n\n" 111 | f"📂 Command Used: {command}\n" 112 | f"📝 Requested By: {user_mention}\n" 113 | f"📜 Processed Successfully! ✅" 114 | ), 115 | parse_mode=ParseMode.HTML 116 | ) 117 | else: 118 | await send_message( 119 | chat_id=message.chat.id, 120 | text=f"✅ {command} Result:\n{result}" if command != "wc" else result, 121 | parse_mode=ParseMode.HTML 122 | ) 123 | await delete_messages(message.chat.id, [processing_msg.message_id]) 124 | if file_path: 125 | clean_download(file_path) 126 | if file_name: 127 | clean_download(file_name) 128 | except (Exception, TelegramBadRequest) as e: 129 | await delete_messages(message.chat.id, [processing_msg.message_id]) 130 | await send_message( 131 | chat_id=message.chat.id, 132 | text="❌ Sorry Bro, Invalid Text Provided!", 133 | parse_mode=ParseMode.HTML 134 | ) 135 | LOGGER.error(f"Error processing /{command} in chat {message.chat.id}: {str(e)}") 136 | await Smart_Notify(bot, f"/{command}", e, message) 137 | if file_path: 138 | clean_download(file_path) 139 | if file_name and os.path.exists(file_name): 140 | clean_download(file_name) -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SmartUtilBot", 3 | "description": "A Smart Telegram Bot With Multi Functional Tools.", 4 | "repository": "https://github.com/TheSmartDevs/SmartUtilBot", 5 | "keywords": ["aiogram", "bot", "python", "telethon", "pyrogram", "tools"], 6 | "env": { 7 | "API_ID": { 8 | "description": "Get from my.telegram.org. Required for Pyro Bot Client.", 9 | "value": "Your_API_ID_Here", 10 | "required": true 11 | }, 12 | "API_HASH": { 13 | "description": "Get from my.telegram.org. Required for Pyro Bot Client.", 14 | "value": "Your_API_HASH_Here", 15 | "required": true 16 | }, 17 | "BOT_TOKEN": { 18 | "description": "Get from @BotFather. Required for Pyro Bot Client.", 19 | "value": "Your_BOT_TOKEN_Here", 20 | "required": true 21 | }, 22 | "SESSION_STRING": { 23 | "description": "Generate from @ItsSmartToolBot. Required for secure session.", 24 | "value": "Your_SESSION_STRING_Here", 25 | "required": true 26 | }, 27 | "DEVELOPER_USER_ID": { 28 | "description": "Telegram User ID of the bot developer. Get from @ItsSmartToolBot using /info.", 29 | "value": "Your_DEVELOPER_USER_ID_Here", 30 | "required": true 31 | }, 32 | "MONGO_URL": { 33 | "description": "MongoDB URL for bot users database and broadcast.", 34 | "value": "Your_MONGO_URL_Here", 35 | "required": true 36 | }, 37 | "DATABASE_URL": { 38 | "description": "Database URL for group settings database.", 39 | "value": "Your_DATABASE_URL_Here", 40 | "required": true 41 | }, 42 | "OPENAI_API_KEY": { 43 | "description": "OpenAI API Key from OpenAI API Developer Console. Required for AI features.", 44 | "value": "Your_OPENAI_API_KEY_Here", 45 | "required": false 46 | }, 47 | "REPLICATE_API_TOKEN": { 48 | "description": "Replicate.com API token for AI image and LLM features.", 49 | "value": "Your_REPLICATE_API_TOKEN_Here", 50 | "required": false 51 | }, 52 | "GOOGLE_API_KEY": { 53 | "description": "Google API Key for Google-based services.", 54 | "value": "Your_GOOGLE_API_KEY_Here", 55 | "required": false 56 | }, 57 | "TRANS_API_KEY": { 58 | "description": "Translation API Key for translation services.", 59 | "value": "Your_TRANS_API_KEY_Here", 60 | "required": false 61 | }, 62 | "OCR_API_KEY": { 63 | "description": "OCR API Key for optical character recognition services.", 64 | "value": "Your_OCR_API_KEY_Here", 65 | "required": false 66 | }, 67 | "MODEL_NAME": { 68 | "description": "Model name for Gemini API.", 69 | "value": "gemini-2.0-flash", 70 | "required": false 71 | }, 72 | "CC_SCRAPPER_LIMIT": { 73 | "description": "Limit for CC scrapper. Higher may risk account ban.", 74 | "value": "5000", 75 | "required": false 76 | }, 77 | "SUDO_CCSCR_LIMIT": { 78 | "description": "Sudo CC scrapper limit. Higher may risk account ban.", 79 | "value": "10000", 80 | "required": false 81 | }, 82 | "MULTI_CCSCR_LIMIT": { 83 | "description": "Multi CC scrapper limit.", 84 | "value": "2000", 85 | "required": false 86 | }, 87 | "MAIL_SCR_LIMIT": { 88 | "description": "Mail scrapper limit.", 89 | "value": "10000", 90 | "required": false 91 | }, 92 | "SUDO_MAILSCR_LIMIT": { 93 | "description": "Sudo mail scrapper limit.", 94 | "value": "15000", 95 | "required": false 96 | }, 97 | "CC_GEN_LIMIT": { 98 | "description": "Credit card generation limit.", 99 | "value": "2000", 100 | "required": false 101 | }, 102 | "MULTI_CCGEN_LIMIT": { 103 | "description": "Multi credit card generation limit.", 104 | "value": "5000", 105 | "required": false 106 | }, 107 | "TEXT_MODEL": { 108 | "description": "Text model for GROQ API.", 109 | "value": "deepseek-r1-distill-llama-70b", 110 | "required": false 111 | }, 112 | "GROQ_API_URL": { 113 | "description": "GROQ API URL.", 114 | "value": "https://api.groq.com/openai/v1/chat/completions", 115 | "required": false 116 | }, 117 | "GROQ_API_KEY": { 118 | "description": "GROQ API Key from GROQ API Console.", 119 | "value": "Your_GROK_API_KEY_Here", 120 | "required": false 121 | }, 122 | "A360APIBASEURL": { 123 | "description": "Base URL for A360 API.", 124 | "value": "https://a360api-c8fbf2fa3cda.herokuapp.com", 125 | "required": false 126 | }, 127 | "DOMAIN_API_KEY": { 128 | "description": "Domain API Key from WhoisXMLAPI website console.", 129 | "value": "Your_DOMAIN_API_KEY_Here", 130 | "required": false 131 | }, 132 | "DOMAIN_API_URL": { 133 | "description": "Domain API URL from WhoisXMLAPI.", 134 | "value": "https://www.whoisxmlapi.com/whoisserver/WhoisService", 135 | "required": false 136 | }, 137 | "UPDATE_CHANNEL_URL": { 138 | "description": "Bot updates channel URL.", 139 | "value": "t.me/TheSmartDev", 140 | "required": false 141 | }, 142 | "LOG_CHANNEL_ID": { 143 | "description": "Bot log channel ID.", 144 | "value": "-1002735511721", 145 | "required": false 146 | }, 147 | "COMMAND_PREFIX": { 148 | "description": "Command prefixes separated by |.", 149 | "value": "!|.|#|,|/", 150 | "required": false 151 | }, 152 | "DOMAIN_CHK_LIMIT": { 153 | "description": "Max number of domains to check with WhoisAPI.", 154 | "value": "20", 155 | "required": false 156 | }, 157 | "PROXY_CHECK_LIMIT": { 158 | "description": "Max number of proxies to check.", 159 | "value": "20", 160 | "required": false 161 | }, 162 | "IMGAI_SIZE_LIMIT": { 163 | "description": "Max file size for image AI tools (bytes).", 164 | "value": "5242880", 165 | "required": false 166 | }, 167 | "MAX_TXT_SIZE": { 168 | "description": "Max text file size (bytes).", 169 | "value": "15728640", 170 | "required": false 171 | }, 172 | "MAX_VIDEO_SIZE": { 173 | "description": "Max video file size (bytes).", 174 | "value": "2147483648", 175 | "required": false 176 | }, 177 | "YT_COOKIES_PATH": { 178 | "description": "Path to YouTube Netscape cookies file.", 179 | "value": "bot/SmartCookies/SmartUtilBot.txt", 180 | "required": false 181 | }, 182 | "VIDEO_RESOLUTION": { 183 | "description": "Video resolution for YouTube downloads (e.g., 1280x720).", 184 | "value": "1280x720", 185 | "required": false 186 | }, 187 | "IMAGE_UPLOAD_KEY": { 188 | "description": "API key for image upload services.", 189 | "value": "Your_IMAGE_UPLOAD_KEY_Here", 190 | "required": false 191 | }, 192 | "IPINFO_API_TOKEN": { 193 | "description": "API token for IPinfo services.", 194 | "value": "Your_IPINFO_API_TOKEN_Here", 195 | "required": false 196 | }, 197 | "WEB_SS_KEY": { 198 | "description": "API key for web screenshot services.", 199 | "value": "Your_WEB_SS_KEY_Here", 200 | "required": false 201 | } 202 | }, 203 | "buildpacks": [ 204 | { 205 | "url": "heroku/python" 206 | } 207 | ] 208 | } -------------------------------------------------------------------------------- /bot/modules/enh.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import aiohttp 5 | import random 6 | import os 7 | from io import BytesIO 8 | from PIL import Image 9 | from aiogram import Bot 10 | from aiogram.filters import Command 11 | from aiogram.types import Message, FSInputFile 12 | from aiogram.enums import ParseMode 13 | from bot import dp 14 | from bot.helpers.utils import new_task, clean_download 15 | from bot.helpers.botutils import send_message, delete_messages 16 | from bot.helpers.commands import BotCommands 17 | from bot.helpers.logger import LOGGER 18 | from bot.helpers.notify import Smart_Notify 19 | from bot.helpers.defend import SmartDefender 20 | import asyncio 21 | import threading 22 | 23 | user_daily_limits = {} 24 | daily_limits_lock = threading.Lock() 25 | 26 | async def upscale(buffer: bytes, width: int, height: int) -> tuple: 27 | try: 28 | random_number = random.randint(1_000_000, 999_999_999_999) 29 | form_data = aiohttp.FormData() 30 | form_data.add_field("image_file", buffer, filename="image.jpg", content_type="image/jpeg") 31 | form_data.add_field("name", str(random_number)) 32 | form_data.add_field("desiredHeight", str(height * 4)) 33 | form_data.add_field("desiredWidth", str(width * 4)) 34 | form_data.add_field("outputFormat", "png") 35 | form_data.add_field("compressionLevel", "high") 36 | form_data.add_field("anime", "false") 37 | headers = { 38 | "Accept": "application/json, text/plain, */*", 39 | "Origin": "https://upscalepics.com", 40 | "Referer": "https://upscalepics.com/", 41 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" 42 | } 43 | async with aiohttp.ClientSession() as session: 44 | async with session.post("https://api.upscalepics.com/upscale-to-size", data=form_data, headers=headers) as response: 45 | if response.status == 200: 46 | json_response = await response.json() 47 | return json_response.get("bgRemoved", "").strip(), None 48 | else: 49 | return None, f"API request failed with status {response.status}" 50 | except Exception as e: 51 | return None, f"Upscale error: {str(e)}" 52 | 53 | @dp.message(Command(commands=["enh"], prefix=BotCommands)) 54 | @new_task 55 | @SmartDefender 56 | async def enh_handler(message: Message, bot: Bot): 57 | chat_id = message.chat.id 58 | user_id = message.from_user.id if message.from_user else None 59 | with daily_limits_lock: 60 | if user_id not in user_daily_limits: 61 | user_daily_limits[user_id] = 10 62 | if user_daily_limits[user_id] <= 0: 63 | await send_message( 64 | chat_id=chat_id, 65 | text="You have reached your daily limit of 10 enhancements.", 66 | parse_mode=ParseMode.HTML 67 | ) 68 | return 69 | replied = message.reply_to_message 70 | valid_photo = replied and replied.photo 71 | valid_doc = replied and replied.document and replied.document.mime_type and replied.document.mime_type.startswith("image/") 72 | if not (valid_photo or valid_doc): 73 | await send_message( 74 | chat_id=chat_id, 75 | text="Reply to a photo or image file to enhance face", 76 | parse_mode=ParseMode.HTML 77 | ) 78 | return 79 | temp_message = await send_message( 80 | chat_id=chat_id, 81 | text="Enhancing Your Face....", 82 | parse_mode=ParseMode.HTML 83 | ) 84 | temp_files = [] 85 | try: 86 | file_id = replied.photo[-1].file_id if valid_photo else replied.document.file_id 87 | file_info = await bot.get_file(file_id) 88 | file_path = f"temp_{random.randint(1_000_000, 999_999_999_999)}.jpg" 89 | await bot.download_file(file_info.file_path, file_path) 90 | if not os.path.exists(file_path): 91 | raise Exception("Failed to download image") 92 | temp_files.append(file_path) 93 | with open(file_path, 'rb') as f: 94 | image_buffer = f.read() 95 | with Image.open(BytesIO(image_buffer)) as img: 96 | width, height = img.size 97 | image_url, error = await upscale(image_buffer, width, height) 98 | clean_download(*temp_files) 99 | if image_url and image_url.startswith("http"): 100 | with daily_limits_lock: 101 | user_daily_limits[user_id] -= 1 102 | async with aiohttp.ClientSession() as session: 103 | async with session.get(image_url) as img_resp: 104 | if img_resp.status == 200: 105 | img_bytes = await img_resp.read() 106 | if not img_bytes: 107 | raise ValueError("Empty image data received from API") 108 | img_path = f"enhanced_{random.randint(1_000_000, 999_999_999_999)}.png" 109 | with open(img_path, 'wb') as f: 110 | f.write(img_bytes) 111 | temp_files.append(img_path) 112 | try: 113 | await delete_messages(chat_id, temp_message.message_id) 114 | except Exception as e: 115 | LOGGER.error(f"Failed to delete temp message in chat {chat_id}: {str(e)}") 116 | await bot.send_document( 117 | chat_id=chat_id, 118 | document=FSInputFile(img_path), 119 | caption=f"✅ Face enhanced!\n{user_daily_limits[user_id]} enhancements remaining today.", 120 | parse_mode=ParseMode.HTML 121 | ) 122 | clean_download(*temp_files) 123 | else: 124 | await temp_message.edit_text( 125 | text="Sorry Enhancer API Dead", 126 | parse_mode=ParseMode.HTML, 127 | disable_web_page_preview=True 128 | ) 129 | else: 130 | await temp_message.edit_text( 131 | text="Sorry Enhancer API Dead", 132 | parse_mode=ParseMode.HTML, 133 | disable_web_page_preview=True 134 | ) 135 | if error: 136 | LOGGER.error(f"Enhancer error: {error}") 137 | await Smart_Notify(bot, "/enh", error, message) 138 | except Exception as e: 139 | LOGGER.error(f"Enhancer error: {str(e)}") 140 | await Smart_Notify(bot, "/enh", e, message) 141 | try: 142 | await temp_message.edit_text( 143 | text="Sorry Enhancer API Dead", 144 | parse_mode=ParseMode.HTML, 145 | disable_web_page_preview=True 146 | ) 147 | except Exception as edit_e: 148 | LOGGER.error(f"Failed to edit temp message in chat {chat_id}: {str(edit_e)}") 149 | await send_message( 150 | chat_id=chat_id, 151 | text="Sorry Enhancer API Dead", 152 | parse_mode=ParseMode.HTML 153 | ) 154 | clean_download(*temp_files) -------------------------------------------------------------------------------- /bot/modules/rembg.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import os 5 | import aiohttp 6 | import aiofiles 7 | import asyncio 8 | from aiogram import Bot 9 | from aiogram.filters import Command 10 | from aiogram.types import Message, FSInputFile 11 | from aiogram.enums import ParseMode, ChatType 12 | from bot import dp, SmartAIO 13 | from bot.helpers.utils import new_task, clean_download 14 | from bot.helpers.botutils import send_message, delete_messages, get_args 15 | from bot.helpers.notify import Smart_Notify 16 | from bot.helpers.logger import LOGGER 17 | from bot.helpers.buttons import SmartButtons 18 | from bot.helpers.commands import BotCommands 19 | from bot.helpers.defend import SmartDefender 20 | 21 | logger = LOGGER 22 | API_KEY = "23nfCEipDijgVv6SH14oktJe" 23 | user_daily_limits = {} 24 | daily_limits_lock = asyncio.Lock() 25 | 26 | def generate_unique_filename(base_name: str) -> str: 27 | if os.path.exists(base_name): 28 | count = 1 29 | name, ext = os.path.splitext(base_name) 30 | while True: 31 | new_name = f"{name}_{count}{ext}" 32 | if not os.path.exists(new_name): 33 | return new_name 34 | count += 1 35 | return base_name 36 | 37 | async def remove_bg(buffer: bytes, user_id: int) -> tuple: 38 | headers = {"X-API-Key": API_KEY} 39 | try: 40 | async with aiohttp.ClientSession() as session: 41 | form_data = aiohttp.FormData() 42 | form_data.add_field("image_file", buffer, filename="image.png", content_type="image/png") 43 | async with session.post("https://api.remove.bg/v1.0/removebg", headers=headers, data=form_data) as resp: 44 | if "image" not in resp.headers.get("content-type", ""): 45 | return False, await resp.json() 46 | os.makedirs("./downloads", exist_ok=True) 47 | output_filename = f"./downloads/no_bg_{user_id}.png" 48 | output_filename = generate_unique_filename(output_filename) 49 | async with aiofiles.open(output_filename, "wb") as out_file: 50 | await out_file.write(await resp.read()) 51 | return True, output_filename 52 | except Exception as e: 53 | return False, {"title": "Unknown Error", "errors": [{"detail": str(e)}]} 54 | 55 | @dp.message(Command(commands=["rmbg"], prefix=BotCommands)) 56 | @new_task 57 | @SmartDefender 58 | async def rmbg_handler(message: Message, bot: Bot): 59 | if message.chat.type not in [ChatType.PRIVATE, ChatType.GROUP, ChatType.SUPERGROUP]: 60 | await send_message( 61 | chat_id=message.chat.id, 62 | text="❌ This command only works in private or group chats", 63 | parse_mode=ParseMode.HTML 64 | ) 65 | return 66 | 67 | user_id = message.from_user.id 68 | logger.info(f"Command received from user {user_id} in chat {message.chat.id}: {message.text}") 69 | 70 | async with daily_limits_lock: 71 | if user_id not in user_daily_limits: 72 | user_daily_limits[user_id] = 10 73 | if user_daily_limits[user_id] <= 0: 74 | await send_message( 75 | chat_id=message.chat.id, 76 | text="❌ You have reached your daily limit of 10 background removals.", 77 | parse_mode=ParseMode.HTML 78 | ) 79 | return 80 | 81 | reply = message.reply_to_message 82 | valid_photo = reply and reply.photo 83 | valid_doc = reply and reply.document and reply.document.mime_type and reply.document.mime_type.startswith("image/") 84 | 85 | if not (valid_photo or valid_doc): 86 | await send_message( 87 | chat_id=message.chat.id, 88 | text="❌ Reply to a photo or image file to remove background", 89 | parse_mode=ParseMode.HTML 90 | ) 91 | return 92 | 93 | if reply.document: 94 | mime_type = reply.document.mime_type 95 | file_name = reply.document.file_name 96 | if not (mime_type in ["image/jpeg", "image/png", "image/jpg"] or 97 | (file_name and file_name.lower().endswith((".jpg", ".jpeg", ".png")))): 98 | await send_message( 99 | chat_id=message.chat.id, 100 | text="❌ Invalid Image Provided", 101 | parse_mode=ParseMode.HTML 102 | ) 103 | return 104 | 105 | loading_message = await send_message( 106 | chat_id=message.chat.id, 107 | text="Removing background...", 108 | parse_mode=ParseMode.HTML 109 | ) 110 | 111 | output_filename = None 112 | try: 113 | file_id = reply.photo[-1].file_id if valid_photo else reply.document.file_id 114 | os.makedirs("./downloads", exist_ok=True) 115 | temp_file = f"./downloads/temp_{user_id}.jpg" 116 | 117 | await bot.download(file=file_id, destination=temp_file) 118 | 119 | async with aiofiles.open(temp_file, "rb") as f: 120 | buffer = await f.read() 121 | 122 | success, result = await remove_bg(buffer, user_id) 123 | 124 | if not success: 125 | await SmartAIO.edit_message_text( 126 | chat_id=message.chat.id, 127 | message_id=loading_message.message_id, 128 | text="❌ Sorry Bro Removal Failed", 129 | parse_mode=ParseMode.HTML 130 | ) 131 | await Smart_Notify(bot, "/rmbg", result, message) 132 | return 133 | 134 | output_filename = result 135 | 136 | async with daily_limits_lock: 137 | user_daily_limits[user_id] -= 1 138 | remaining = user_daily_limits[user_id] 139 | 140 | await bot.send_document( 141 | chat_id=message.chat.id, 142 | document=FSInputFile(output_filename), 143 | caption=f"✅ Background removed!\n{remaining} removals remaining today.", 144 | parse_mode=ParseMode.HTML 145 | ) 146 | 147 | try: 148 | await SmartAIO.delete_message( 149 | chat_id=message.chat.id, 150 | message_id=loading_message.message_id 151 | ) 152 | except Exception: 153 | pass 154 | 155 | except Exception as e: 156 | logger.error(f"rmbg error: {str(e)}") 157 | try: 158 | await SmartAIO.edit_message_text( 159 | chat_id=message.chat.id, 160 | message_id=loading_message.message_id, 161 | text="❌ Sorry Bro Removal Failed", 162 | parse_mode=ParseMode.HTML 163 | ) 164 | except Exception: 165 | await send_message( 166 | chat_id=message.chat.id, 167 | text="❌ Sorry Bro Removal Failed", 168 | parse_mode=ParseMode.HTML 169 | ) 170 | await Smart_Notify(bot, "/rmbg", e, message) 171 | finally: 172 | try: 173 | temp_file = f"./downloads/temp_{user_id}.jpg" 174 | if os.path.exists(temp_file): 175 | clean_download(temp_file) 176 | if output_filename and os.path.exists(output_filename): 177 | clean_download(output_filename) 178 | except Exception as cleanup_error: 179 | logger.warning(f"Cleanup error for user {user_id}: {cleanup_error}") -------------------------------------------------------------------------------- /bot/modules/vnote.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import os 5 | import time 6 | import asyncio 7 | import subprocess 8 | from concurrent.futures import ThreadPoolExecutor 9 | from aiogram import Bot 10 | from aiogram.filters import Command 11 | from aiogram.types import Message 12 | from aiogram.enums import ParseMode 13 | from aiogram.exceptions import TelegramBadRequest 14 | from pyrogram.errors import FileIdInvalid 15 | from bot import dp, SmartPyro 16 | from bot.helpers.utils import new_task, clean_download 17 | from bot.helpers.botutils import send_message, delete_messages 18 | from bot.helpers.commands import BotCommands 19 | from bot.helpers.logger import LOGGER 20 | from bot.helpers.notify import Smart_Notify 21 | from bot.helpers.defend import SmartDefender 22 | 23 | DOWNLOAD_DIRECTORY = "./downloads/" 24 | if not os.path.exists(DOWNLOAD_DIRECTORY): 25 | os.makedirs(DOWNLOAD_DIRECTORY) 26 | 27 | executor = ThreadPoolExecutor(max_workers=16) 28 | 29 | def run_ffmpeg(ffmpeg_cmd): 30 | subprocess.run(ffmpeg_cmd, check=True, capture_output=True) 31 | 32 | @dp.message(Command(commands=["vnote"], prefix=BotCommands)) 33 | @new_task 34 | @SmartDefender 35 | async def vnote_handler(message: Message, bot: Bot): 36 | LOGGER.info(f"Received /vnote command from user: {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 37 | 38 | # Initialize all variables before try block 39 | progress_message = None 40 | input_path = None 41 | output_path = None 42 | 43 | try: 44 | if not message.reply_to_message or not message.reply_to_message.video: 45 | progress_message = await send_message( 46 | chat_id=message.chat.id, 47 | text="❌ Reply To A Video With The Command", 48 | parse_mode=ParseMode.HTML, 49 | disable_web_page_preview=True 50 | ) 51 | LOGGER.warning("No valid video provided for /vnote command") 52 | return 53 | 54 | video = message.reply_to_message.video 55 | if video.duration and video.duration > 60: 56 | progress_message = await send_message( 57 | chat_id=message.chat.id, 58 | text="❌ Video Must Be 1 Minute Or Shorter", 59 | parse_mode=ParseMode.HTML, 60 | disable_web_page_preview=True 61 | ) 62 | LOGGER.warning(f"Video duration too long: {video.duration} seconds") 63 | return 64 | 65 | progress_message = await send_message( 66 | chat_id=message.chat.id, 67 | text="Converting To Video Note...✨", 68 | parse_mode=ParseMode.HTML, 69 | disable_web_page_preview=True 70 | ) 71 | 72 | user_id = message.from_user.id if message.from_user else 0 73 | input_path = os.path.join(DOWNLOAD_DIRECTORY, f"input_{user_id}_{int(time.time())}.mp4") 74 | output_path = os.path.join(DOWNLOAD_DIRECTORY, f"output_{user_id}_{int(time.time())}.mp4") 75 | 76 | video_file_id = video.file_id 77 | await SmartPyro.download_media( 78 | message=video_file_id, 79 | file_name=input_path 80 | ) 81 | LOGGER.info(f"Downloaded video file to {input_path}") 82 | 83 | ffmpeg_cmd = [ 84 | "ffmpeg", "-y", "-i", input_path, 85 | "-vf", "crop='min(iw,ih):min(iw,ih)',scale=640:640", 86 | "-c:v", "libx264", "-preset", "ultrafast", "-crf", "30", 87 | "-c:a", "aac", "-b:a", "96k", "-ar", "32000", 88 | "-t", "60", "-movflags", "+faststart", output_path 89 | ] 90 | 91 | await asyncio.get_event_loop().run_in_executor(executor, run_ffmpeg, ffmpeg_cmd) 92 | LOGGER.info(f"Converted video to video note at {output_path}") 93 | 94 | await SmartPyro.send_video_note( 95 | chat_id=message.chat.id, 96 | video_note=output_path, 97 | length=640, 98 | duration=min(video.duration or 60, 60) 99 | ) 100 | LOGGER.info("Video note uploaded successfully") 101 | 102 | await delete_messages(message.chat.id, progress_message.message_id) 103 | LOGGER.info(f"Successfully processed /vnote command for user {message.from_user.id} in chat {message.chat.id}") 104 | 105 | except FileIdInvalid as e: 106 | LOGGER.error(f"Invalid file ID for /vnote command in chat {message.chat.id}: {str(e)}") 107 | await Smart_Notify(bot, "vnote", "Invalid file_id", message) 108 | error_text = "❌ Invalid Video File" 109 | 110 | if progress_message: 111 | try: 112 | await progress_message.edit_text( 113 | text=error_text, 114 | parse_mode=ParseMode.HTML 115 | ) 116 | LOGGER.info(f"Edited progress message with file error in chat {message.chat.id}") 117 | except TelegramBadRequest as edit_e: 118 | LOGGER.error(f"Failed to edit progress message in chat {message.chat.id}: {str(edit_e)}") 119 | await Smart_Notify(bot, "vnote", edit_e, message) 120 | await send_message( 121 | chat_id=message.chat.id, 122 | text=error_text, 123 | parse_mode=ParseMode.HTML 124 | ) 125 | LOGGER.info(f"Sent file error message to chat {message.chat.id}") 126 | else: 127 | await send_message( 128 | chat_id=message.chat.id, 129 | text=error_text, 130 | parse_mode=ParseMode.HTML 131 | ) 132 | LOGGER.info(f"Sent file error message to chat {message.chat.id}") 133 | except Exception as e: 134 | LOGGER.error(f"Error processing /vnote command in chat {message.chat.id}: {str(e)}") 135 | await Smart_Notify(bot, "vnote", e, message) 136 | error_text = "❌ Sorry Bro Converter API Error" 137 | 138 | if progress_message: 139 | try: 140 | await progress_message.edit_text( 141 | text=error_text, 142 | parse_mode=ParseMode.HTML 143 | ) 144 | LOGGER.info(f"Edited progress message with error in chat {message.chat.id}") 145 | except TelegramBadRequest as edit_e: 146 | LOGGER.error(f"Failed to edit progress message in chat {message.chat.id}: {str(edit_e)}") 147 | await Smart_Notify(bot, "vnote", edit_e, message) 148 | await send_message( 149 | chat_id=message.chat.id, 150 | text=error_text, 151 | parse_mode=ParseMode.HTML 152 | ) 153 | LOGGER.info(f"Sent error message to chat {message.chat.id}") 154 | else: 155 | await send_message( 156 | chat_id=message.chat.id, 157 | text=error_text, 158 | parse_mode=ParseMode.HTML 159 | ) 160 | LOGGER.info(f"Sent error message to chat {message.chat.id}") 161 | finally: 162 | 163 | if input_path and os.path.exists(input_path): 164 | try: 165 | os.remove(input_path) 166 | except: 167 | pass 168 | if output_path and os.path.exists(output_path): 169 | try: 170 | os.remove(output_path) 171 | except: 172 | pass 173 | -------------------------------------------------------------------------------- /bot/modules/binmd.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import re 5 | import os 6 | from aiogram import Bot 7 | from aiogram.filters import Command 8 | from aiogram.types import Message, FSInputFile 9 | from aiogram.enums import ParseMode 10 | from aiogram.exceptions import TelegramBadRequest 11 | from bot import dp 12 | from bot.helpers.utils import new_task, clean_download 13 | from bot.helpers.botutils import send_message, delete_messages, get_args 14 | from bot.helpers.commands import BotCommands 15 | from bot.helpers.buttons import SmartButtons 16 | from bot.helpers.logger import LOGGER 17 | from bot.helpers.notify import Smart_Notify 18 | from bot.helpers.defend import SmartDefender 19 | from config import MAX_TXT_SIZE, UPDATE_CHANNEL_URL 20 | 21 | async def filter_bin(content, bin_number): 22 | filtered_lines = [line for line in content if line.startswith(bin_number)] 23 | return filtered_lines 24 | 25 | async def remove_bin(content, bin_number): 26 | filtered_lines = [line for line in content if not line.startswith(bin_number)] 27 | return filtered_lines 28 | 29 | async def process_file(file_path, bin_number, command): 30 | with open(file_path, 'r') as file: 31 | content = file.readlines() 32 | if command in ['/adbin', '.adbin']: 33 | return await filter_bin(content, bin_number) 34 | elif command in ['/rmbin', '.rmbin']: 35 | return await remove_bin(content, bin_number) 36 | 37 | @dp.message(Command(commands=["adbin", "rmbin"], prefix=BotCommands)) 38 | @new_task 39 | @SmartDefender 40 | async def handle_bin_commands(message: Message, bot: Bot): 41 | progress_message = None 42 | file_path = None 43 | file_name = None 44 | try: 45 | args = get_args(message) 46 | if len(args) != 1: 47 | progress_message = await send_message( 48 | chat_id=message.chat.id, 49 | text="⚠️ Please provide a valid BIN number❌", 50 | parse_mode=ParseMode.HTML 51 | ) 52 | return 53 | command = message.text.split()[0] 54 | bin_number = args[0] 55 | if not re.match(r'^\d{6}$', bin_number): 56 | progress_message = await send_message( 57 | chat_id=message.chat.id, 58 | text="⚠️ BIN number must be 6 digits❌", 59 | parse_mode=ParseMode.HTML 60 | ) 61 | return 62 | if not message.reply_to_message or not message.reply_to_message.document or not message.reply_to_message.document.file_name.endswith('.txt'): 63 | progress_message = await send_message( 64 | chat_id=message.chat.id, 65 | text="⚠️ Please provide a valid .txt file by replying to it.❌", 66 | parse_mode=ParseMode.HTML 67 | ) 68 | return 69 | file_size_mb = message.reply_to_message.document.file_size / (1024 * 1024) 70 | if file_size_mb > MAX_TXT_SIZE: 71 | progress_message = await send_message( 72 | chat_id=message.chat.id, 73 | text="⚠️ File size exceeds the 15MB limit❌", 74 | parse_mode=ParseMode.HTML 75 | ) 76 | return 77 | processing_text = "Adding Bins..." if command in ['/adbin', '.adbin'] else "Removing Bins..." 78 | progress_message = await send_message( 79 | chat_id=message.chat.id, 80 | text=processing_text, 81 | parse_mode=ParseMode.HTML 82 | ) 83 | file_id = message.reply_to_message.document.file_id 84 | file_info = await bot.get_file(file_id) 85 | file_path = f"downloads/{file_id}.txt" 86 | os.makedirs('downloads', exist_ok=True) 87 | await bot.download_file(file_info.file_path, file_path) 88 | processed_cards = await process_file(file_path, bin_number, command) 89 | if not processed_cards: 90 | await progress_message.edit_text( 91 | text=f"❌ No credit card details found with BIN {bin_number}.", 92 | parse_mode=ParseMode.HTML 93 | ) 94 | clean_download(file_path) 95 | return 96 | action = "Add" if command in ['/adbin', '.adbin'] else "Remove" 97 | actioner = "Adder" if command in ['/adbin', '.adbin'] else "Remover" 98 | file_label = "Added" if command in ['/adbin', '.adbin'] else "Removed" 99 | await delete_messages(message.chat.id, progress_message.message_id) 100 | if len(processed_cards) <= 10: 101 | formatted_cards = "\n".join(f"{line.strip()}" for line in processed_cards) 102 | response_message = ( 103 | f"Smart Bin {action} → Successful ✅\n" 104 | f"━━━━━━━━━━━━━━━━━\n" 105 | f"{formatted_cards}\n" 106 | f"━━━━━━━━━━━━━━━━━\n" 107 | f"Smart Bin {actioner} → Activated ✅" 108 | ) 109 | await send_message( 110 | chat_id=message.chat.id, 111 | text=response_message, 112 | parse_mode=ParseMode.HTML 113 | ) 114 | else: 115 | file_name = f"downloads/Bin_{file_label}_Txt.txt" 116 | with open(file_name, "w") as file: 117 | file.write("".join(processed_cards)) 118 | total_amount = len(processed_cards) 119 | total_size = f"{os.path.getsize(file_name) / 1024:.2f} KB" 120 | total_lines = len(processed_cards) 121 | caption = ( 122 | f"Smart Bin {action} → Successful ✅\n" 123 | f"━━━━━━━━━━━━━━━━━\n" 124 | f"⊗ Total Amount: {total_amount}\n" 125 | f"⊗ Total Size: {total_size}\n" 126 | f"⊗ Target Bin: {bin_number}\n" 127 | f"⊗ Total Lines: {total_lines}\n" 128 | f"━━━━━━━━━━━━━━━━━\n" 129 | f"Smart Bin {actioner} → Activated ✅" 130 | ) 131 | buttons = SmartButtons() 132 | buttons.button(text="Join For Updates", url=UPDATE_CHANNEL_URL) 133 | await bot.send_document( 134 | chat_id=message.chat.id, 135 | document=FSInputFile(path=file_name), 136 | caption=caption, 137 | parse_mode=ParseMode.HTML, 138 | reply_markup=buttons.build_menu(b_cols=1) 139 | ) 140 | os.remove(file_name) 141 | clean_download(file_path) 142 | except Exception as e: 143 | LOGGER.error(f"Error processing {command} command in chat {message.chat.id}: {str(e)}") 144 | await Smart_Notify(bot, command, e, message) 145 | if progress_message: 146 | try: 147 | await progress_message.edit_text( 148 | text="❌ Error processing file", 149 | parse_mode=ParseMode.HTML 150 | ) 151 | except TelegramBadRequest: 152 | await send_message( 153 | chat_id=message.chat.id, 154 | text="❌ Error processing file", 155 | parse_mode=ParseMode.HTML 156 | ) 157 | else: 158 | await send_message( 159 | chat_id=message.chat.id, 160 | text="❌ Error processing file", 161 | parse_mode=ParseMode.HTML 162 | ) 163 | if file_path: 164 | clean_download(file_path) 165 | if file_name and os.path.exists(file_name): 166 | clean_download(file_name) -------------------------------------------------------------------------------- /bot/modules/mbin.py: -------------------------------------------------------------------------------- 1 | from aiogram import Bot 2 | from aiogram.filters import Command 3 | from aiogram.types import Message 4 | from aiogram.enums import ParseMode 5 | from aiogram.exceptions import TelegramBadRequest 6 | from bot import dp 7 | from bot.helpers.utils import new_task, clean_download 8 | from bot.helpers.botutils import send_message, delete_messages, get_args 9 | from bot.helpers.commands import BotCommands 10 | from bot.helpers.logger import LOGGER 11 | from bot.helpers.notify import Smart_Notify 12 | from bot.helpers.defend import SmartDefender 13 | from bot.helpers.bindb import smartdb 14 | import pycountry 15 | import os 16 | import asyncio 17 | 18 | async def get_bin_info(bin: str, bot: Bot, message: Message): 19 | try: 20 | result = await smartdb.get_bin_info(bin) 21 | if result.get("status") == "SUCCESS" and result.get("data") and isinstance(result["data"], list) and len(result["data"]) > 0: 22 | return result 23 | else: 24 | LOGGER.error(f"SmartBinDB returned invalid response for BIN: {bin} - {result}") 25 | await Smart_Notify(bot, "mbin", f"SmartBinDB invalid response: {result}", message) 26 | return None 27 | except Exception as e: 28 | LOGGER.error(f"Error fetching BIN info from SmartBinDB: {bin} - {str(e)}") 29 | await Smart_Notify(bot, "mbin", e, message) 30 | return None 31 | 32 | def get_flag(country_code: str): 33 | try: 34 | if not country_code or len(country_code) < 2: 35 | return "Unknown", "" 36 | country_code = country_code.upper() 37 | if country_code in ['US1', 'US2']: 38 | country_code = 'US' 39 | country = pycountry.countries.get(alpha_2=country_code) 40 | if not country: 41 | return "Unknown", "" 42 | country_name = country.name 43 | flag_emoji = chr(0x1F1E6 + ord(country_code[0]) - ord('A')) + chr(0x1F1E6 + ord(country_code[1]) - ord('A')) 44 | return country_name, flag_emoji 45 | except: 46 | return "Unknown", "" 47 | 48 | @dp.message(Command(commands=["mbin"], prefix=BotCommands)) 49 | @new_task 50 | @SmartDefender 51 | async def bin_handler(message: Message, bot: Bot): 52 | LOGGER.info(f"Received /mbin command from user: {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 53 | progress_message = None 54 | try: 55 | bins = [] 56 | if message.reply_to_message and message.reply_to_message.document: 57 | file_path = f"bin_{message.chat.id}.txt" 58 | await bot.download(message.reply_to_message.document, destination=file_path) 59 | with open(file_path, 'r') as f: 60 | bins = [line.strip()[:6] for line in f.readlines() if line.strip() and len(line.strip()) >= 6 and line.strip()[:6].isdigit()] 61 | clean_download() 62 | LOGGER.info(f"BINs extracted from uploaded file by user: {message.from_user.id}") 63 | else: 64 | args = get_args(message) 65 | if not args: 66 | progress_message = await send_message( 67 | chat_id=message.chat.id, 68 | text="Provide a valid BIN (6 digits) or reply to a text file containing BINs ❌", 69 | parse_mode=ParseMode.HTML 70 | ) 71 | LOGGER.warning(f"No BIN provided by user: {message.from_user.id}") 72 | return 73 | bins = [arg[:6] for arg in args if len(arg) >= 6 and arg[:6].isdigit()] 74 | 75 | if not bins: 76 | progress_message = await send_message( 77 | chat_id=message.chat.id, 78 | text="Provide valid BINs (6 digits) ❌", 79 | parse_mode=ParseMode.HTML 80 | ) 81 | LOGGER.warning(f"No valid BINs provided by user: {message.from_user.id}") 82 | return 83 | 84 | if len(bins) > 20: 85 | progress_message = await send_message( 86 | chat_id=message.chat.id, 87 | text="You can check up to 20 BINs at a time ❌", 88 | parse_mode=ParseMode.HTML 89 | ) 90 | LOGGER.warning(f"User {message.from_user.id} tried to fetch more than 20 BINs") 91 | return 92 | 93 | invalid_bins = [bin for bin in bins if len(bin) != 6 or not bin.isdigit()] 94 | if invalid_bins: 95 | progress_message = await send_message( 96 | chat_id=message.chat.id, 97 | text=f"Invalid BINs provided ❌ {' '.join(invalid_bins)}", 98 | parse_mode=ParseMode.HTML 99 | ) 100 | LOGGER.warning(f"Invalid BIN formats from user: {message.from_user.id} - {invalid_bins}") 101 | return 102 | 103 | progress_message = await send_message( 104 | chat_id=message.chat.id, 105 | text="Fetching BINs Info...✨", 106 | parse_mode=ParseMode.HTML 107 | ) 108 | 109 | async def fetch_bin_info(bin): 110 | bin_info = await get_bin_info(bin, bot, message) 111 | if bin_info: 112 | bank = bin_info["data"][0].get("issuer", "Unknown") 113 | card_type = bin_info["data"][0].get("type", "Unknown") 114 | card_scheme = bin_info["data"][0].get("brand", "Unknown") 115 | bank_text = bank.upper() if bank else "Unknown" 116 | country_code = bin_info["data"][0].get("country_code", "Unknown") 117 | country_name, flag_emoji = get_flag(country_code) 118 | return ( 119 | f"• BIN: {bin}\n" 120 | f"• INFO: {card_scheme.upper()} - {card_type.upper()}\n" 121 | f"• BANK: {bank_text}\n" 122 | f"• COUNTRY: {country_name.upper()} {flag_emoji}\n\n" 123 | ) 124 | else: 125 | return f"• BIN: {bin}\n• INFO: Not Found\n\n" 126 | 127 | tasks = [fetch_bin_info(bin) for bin in bins] 128 | results = await asyncio.gather(*tasks) 129 | response_text = ( 130 | f"🔍 BIN Details From Smart Database 📋\n" 131 | f"━━━━━━━━━━━━━━━━━━\n" 132 | f"{' '.join(results)}" 133 | f"━━━━━━━━━━━━━━━━━━\n" 134 | f"🔍 Smart Bin Checker → Activated ✅" 135 | ) 136 | 137 | await progress_message.edit_text( 138 | text=response_text, 139 | parse_mode=ParseMode.HTML 140 | ) 141 | LOGGER.info(f"Successfully sent BIN details for {len(bins)} BINs to chat {message.chat.id}") 142 | 143 | except Exception as e: 144 | LOGGER.error(f"Error processing /mbin command in chat {message.chat.id}: {str(e)}") 145 | await Smart_Notify(bot, "mbin", e, message) 146 | if progress_message: 147 | try: 148 | await progress_message.edit_text( 149 | text="❌ Sorry Bro BIN API Error", 150 | parse_mode=ParseMode.HTML 151 | ) 152 | LOGGER.info(f"Edited progress message with BIN error in chat {message.chat.id}") 153 | except TelegramBadRequest as edit_e: 154 | LOGGER.error(f"Failed to edit progress message in chat {message.chat.id}: {str(edit_e)}") 155 | await Smart_Notify(bot, "mbin", edit_e, message) 156 | await send_message( 157 | chat_id=message.chat.id, 158 | text="❌ Sorry Bro BIN API Error", 159 | parse_mode=ParseMode.HTML 160 | ) 161 | LOGGER.info(f"Sent BIN error message to chat {message.chat.id}") 162 | else: 163 | await send_message( 164 | chat_id=message.chat.id, 165 | text="❌ Sorry Bro BIN API Error", 166 | parse_mode=ParseMode.HTML 167 | ) 168 | LOGGER.info(f"Sent BIN error message to chat {message.chat.id}") 169 | finally: 170 | clean_download() -------------------------------------------------------------------------------- /bot/modules/pron.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import os 5 | import aiohttp 6 | from aiogram import Bot 7 | from aiogram.filters import Command 8 | from aiogram.types import Message, FSInputFile 9 | from aiogram.enums import ParseMode 10 | from aiogram.exceptions import TelegramBadRequest 11 | from bot import dp 12 | from bot.helpers.utils import new_task, clean_download 13 | from bot.helpers.botutils import send_message, delete_messages, get_args 14 | from bot.helpers.commands import BotCommands 15 | from bot.helpers.logger import LOGGER 16 | from bot.helpers.notify import Smart_Notify 17 | from bot.helpers.defend import SmartDefender 18 | from config import A360APIBASEURL 19 | 20 | DOWNLOAD_DIRECTORY = "./downloads/" 21 | if not os.path.exists(DOWNLOAD_DIRECTORY): 22 | os.makedirs(DOWNLOAD_DIRECTORY) 23 | 24 | async def fetch_pronunciation_info(word): 25 | url = f"{A360APIBASEURL}/eng/prn?word={word}" 26 | try: 27 | async with aiohttp.ClientSession() as session: 28 | async with session.get(url) as response: 29 | response.raise_for_status() 30 | result = await response.json() 31 | pronunciation_info = result['response'] 32 | LOGGER.info(f"Successfully fetched pronunciation info for '{word}'") 33 | return { 34 | "word": pronunciation_info['Word'], 35 | "breakdown": pronunciation_info['- Breakdown'], 36 | "pronunciation": pronunciation_info['- Pronunciation'], 37 | "stems": pronunciation_info['Word Stems'].split(", "), 38 | "definition": pronunciation_info['Definition'], 39 | "audio_link": pronunciation_info['Audio'] 40 | } 41 | except (aiohttp.ClientError, ValueError, KeyError) as e: 42 | LOGGER.error(f"Pronunciation API error for word '{word}': {e}") 43 | return None 44 | 45 | @dp.message(Command(commands=["prn"], prefix=BotCommands)) 46 | @new_task 47 | @SmartDefender 48 | async def prn_handler(message: Message, bot: Bot): 49 | LOGGER.info(f"Received /prn command from user: {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 50 | checking_message = None 51 | try: 52 | if message.reply_to_message and message.reply_to_message.text: 53 | word = message.reply_to_message.text.strip() 54 | if len(word.split()) != 1: 55 | checking_message = await send_message( 56 | chat_id=message.chat.id, 57 | text="❌ Reply To A Message With A Single Word", 58 | parse_mode=ParseMode.HTML, 59 | disable_web_page_preview=True 60 | ) 61 | LOGGER.warning(f"Invalid reply format: {word}") 62 | return 63 | else: 64 | command_parts = get_args(message) 65 | if not command_parts or len(command_parts) != 1: 66 | checking_message = await send_message( 67 | chat_id=message.chat.id, 68 | text="❌ Provide A Single Word To Check Pronunciation", 69 | parse_mode=ParseMode.HTML, 70 | disable_web_page_preview=True 71 | ) 72 | LOGGER.warning(f"Invalid command format: {message.text}") 73 | return 74 | word = command_parts[0].strip() 75 | checking_message = await send_message( 76 | chat_id=message.chat.id, 77 | text="Checking Pronunciation...✨", 78 | parse_mode=ParseMode.HTML, 79 | disable_web_page_preview=True 80 | ) 81 | pronunciation_info = await fetch_pronunciation_info(word) 82 | if pronunciation_info is None: 83 | error_text = "❌ Sorry Bro Pronunciation API Dead" 84 | try: 85 | await checking_message.edit_text( 86 | text=error_text, 87 | parse_mode=ParseMode.HTML 88 | ) 89 | LOGGER.info(f"Edited checking message with error in chat {message.chat.id}") 90 | except TelegramBadRequest as edit_e: 91 | LOGGER.error(f"Failed to edit checking message in chat {message.chat.id}: {str(edit_e)}") 92 | await Smart_Notify(bot, "prn", edit_e, message) 93 | await send_message( 94 | chat_id=message.chat.id, 95 | text=error_text, 96 | parse_mode=ParseMode.HTML 97 | ) 98 | LOGGER.error(f"Pronunciation API returned no data for word '{word}'") 99 | await Smart_Notify(bot, "prn", Exception("Pronunciation API returned no data"), message) 100 | return 101 | audio_filename = None 102 | if pronunciation_info['audio_link']: 103 | audio_filename = os.path.join(DOWNLOAD_DIRECTORY, f"prn_{message.chat.id}_{word}.mp3") 104 | try: 105 | async with aiohttp.ClientSession() as session: 106 | async with session.get(pronunciation_info['audio_link']) as response: 107 | response.raise_for_status() 108 | with open(audio_filename, 'wb') as f: 109 | f.write(await response.read()) 110 | LOGGER.info(f"Downloaded audio for word '{word}' to {audio_filename}") 111 | except aiohttp.ClientError as e: 112 | LOGGER.error(f"Failed to download audio for word '{word}': {e}") 113 | await Smart_Notify(bot, "prn audio", e, message) 114 | audio_filename = None 115 | caption = ( 116 | f"Word: {pronunciation_info['word']}\n" 117 | f"- Breakdown: {pronunciation_info['breakdown']}\n" 118 | f"- Pronunciation: {pronunciation_info['pronunciation']}\n\n" 119 | f"Word Stems:\n{', '.join(pronunciation_info['stems'])}\n\n" 120 | f"Definition:\n{pronunciation_info['definition']}" 121 | ) 122 | if audio_filename: 123 | await bot.send_audio( 124 | chat_id=message.chat.id, 125 | audio=FSInputFile(audio_filename), 126 | caption=caption, 127 | parse_mode=ParseMode.HTML 128 | ) 129 | LOGGER.info(f"Sent audio pronunciation for '{word}'") 130 | else: 131 | await send_message( 132 | chat_id=message.chat.id, 133 | text=caption, 134 | parse_mode=ParseMode.HTML 135 | ) 136 | LOGGER.info(f"Sent text pronunciation for '{word}'") 137 | await delete_messages(message.chat.id, checking_message.message_id) 138 | except Exception as e: 139 | LOGGER.error(f"Error processing /prn command for word '{word}': {str(e)}") 140 | await Smart_Notify(bot, "prn", e, message) 141 | error_text = "❌ Sorry Bro Pronunciation API Dead" 142 | if checking_message: 143 | try: 144 | await checking_message.edit_text( 145 | text=error_text, 146 | parse_mode=ParseMode.HTML 147 | ) 148 | LOGGER.info(f"Edited checking message with error in chat {message.chat.id}") 149 | except TelegramBadRequest as edit_e: 150 | LOGGER.error(f"Failed to edit checking message in chat {message.chat.id}: {str(edit_e)}") 151 | await Smart_Notify(bot, "prn", edit_e, message) 152 | await send_message( 153 | chat_id=message.chat.id, 154 | text=error_text, 155 | parse_mode=ParseMode.HTML 156 | ) 157 | else: 158 | await send_message( 159 | chat_id=message.chat.id, 160 | text=error_text, 161 | parse_mode=ParseMode.HTML 162 | ) 163 | LOGGER.info(f"Sent error message to chat {message.chat.id}") 164 | finally: 165 | if audio_filename and os.path.exists(audio_filename): 166 | clean_download(audio_filename) -------------------------------------------------------------------------------- /bot/modules/dep.py: -------------------------------------------------------------------------------- 1 | # Copyright @ISmartCoder 2 | # SmartUtilBot - Telegram Utility Bot for Smart Features Bot 3 | # Copyright (C) 2024-present Abir Arafat Chawdhury 4 | import aiohttp 5 | import asyncio 6 | import re 7 | from aiogram import Bot 8 | from aiogram.filters import Command 9 | from aiogram.types import Message 10 | from aiogram.enums import ParseMode 11 | from aiogram.exceptions import TelegramBadRequest 12 | from bot import dp 13 | from bot.helpers.botutils import send_message, delete_messages 14 | from bot.helpers.commands import BotCommands 15 | from bot.helpers.logger import LOGGER 16 | from bot.helpers.utils import new_task 17 | from bot.helpers.notify import Smart_Notify 18 | from bot.helpers.defend import SmartDefender 19 | from config import GROQ_API_KEY, GROQ_API_URL, TEXT_MODEL 20 | 21 | def escape_html(text): 22 | html_escape_table = { 23 | "&": "&", 24 | "<": "<", 25 | ">": ">", 26 | "`": "`", 27 | "\"": """, 28 | "'": "'" 29 | } 30 | return "".join(html_escape_table.get(c, c) for c in text) 31 | 32 | def format_code_response(text): 33 | text = re.sub(r']*>', '', text, flags=re.IGNORECASE) 34 | replacements = [ 35 | (r"^> (.*)", r"
\1
"), 36 | (r"```(?:\w*)\n([\s\S]*?)\n```", r"
\1
"), 37 | (r"`(.*?)`", r"\1"), 38 | (r"\*\*(.*?)\*\*", r"\1"), 39 | (r"\*(.*?)\*", r"\1"), 40 | (r"__(.*?)__", r"\1"), 41 | (r"_(.*?)_", r"\1"), 42 | (r"~~(.*?)~~", r"\1"), 43 | (r"\[(.*?)\]\((.*?)\)", r'\1') 44 | ] 45 | parts = [] 46 | last_pos = 0 47 | code_block_pattern = re.compile(r"```(?:\w*)\n([\s\S]*?)\n```", re.MULTILINE | re.DOTALL) 48 | for match in code_block_pattern.finditer(text): 49 | start, end = match.span() 50 | parts.append(escape_html(text[last_pos:start])) 51 | parts.append(f"
{escape_html(match.group(1))}
") 52 | last_pos = end 53 | parts.append(escape_html(text[last_pos:])) 54 | text = "".join(parts) 55 | for pattern, replacement in replacements[2:]: 56 | text = re.sub(pattern, replacement, text, flags=re.MULTILINE | re.DOTALL) 57 | text = re.sub(r']*>|]*>', '', text, flags=re.IGNORECASE) 58 | text = re.sub(r'<\?[\s\S]*?\?>', '', text) 59 | return text 60 | 61 | @dp.message(Command(commands=["dep"], prefix=BotCommands)) 62 | @new_task 63 | @SmartDefender 64 | async def dep_handler(message: Message, bot: Bot): 65 | LOGGER.info(f"Received command: '{message.text}' from user {message.from_user.id if message.from_user else 'Unknown'} in chat {message.chat.id}") 66 | progress_message = None 67 | try: 68 | progress_message = await send_message( 69 | chat_id=message.chat.id, 70 | text="DeepSeek AI Is Thinking Wait.. ✨", 71 | parse_mode=ParseMode.HTML 72 | ) 73 | user_text = None 74 | command_text = message.text.split(maxsplit=1) 75 | if message.reply_to_message and message.reply_to_message.text: 76 | user_text = message.reply_to_message.text 77 | elif len(command_text) > 1: 78 | user_text = command_text[1] 79 | if not user_text: 80 | await progress_message.edit_text( 81 | text="Please Provide A Prompt For DeepSeekAI ✨ Response", 82 | parse_mode=ParseMode.HTML 83 | ) 84 | LOGGER.info(f"Prompt missing for DeepSeekAI command in chat {message.chat.id}") 85 | return 86 | async with aiohttp.ClientSession() as session: 87 | async with session.post( 88 | GROQ_API_URL, 89 | headers={ 90 | "Authorization": f"Bearer {GROQ_API_KEY}", 91 | "Content-Type": "application/json", 92 | }, 93 | json={ 94 | "model": TEXT_MODEL, 95 | "messages": [ 96 | {"role": "system", "content": "Reply in the same language as the user's message But Always Try To Answer Shortly"}, 97 | {"role": "user", "content": user_text}, 98 | ], 99 | } 100 | ) as response: 101 | if response.status == 200: 102 | data = await response.json() 103 | bot_response = data.get("choices", [{}])[0].get("message", {}).get("content", "Sorry DeepSeek API Dead") 104 | bot_response = format_code_response(bot_response) 105 | else: 106 | error_response = await response.text() 107 | LOGGER.error(f"DeepSeekAI API request failed with status {response.status}: {error_response}") 108 | await Smart_Notify(bot, "dep", f"API request failed with status {response.status}: {error_response}", message) 109 | bot_response = "❌ Sorry Bro DeepSeekAI ✨ API Dead" 110 | if len(bot_response) > 4096: 111 | await delete_messages(message.chat.id, progress_message.message_id) 112 | parts = [] 113 | current_part = "" 114 | for line in bot_response.splitlines(True): 115 | if len(current_part) + len(line) <= 4096: 116 | current_part += line 117 | else: 118 | if current_part: 119 | parts.append(current_part) 120 | current_part = line 121 | if current_part: 122 | parts.append(current_part) 123 | for part in parts: 124 | try: 125 | await send_message( 126 | chat_id=message.chat.id, 127 | text=part, 128 | parse_mode=ParseMode.HTML 129 | ) 130 | await asyncio.sleep(0.5) 131 | except TelegramBadRequest as send_e: 132 | LOGGER.error(f"Failed to send message part to chat {message.chat.id}: {str(send_e)}") 133 | await Smart_Notify(bot, "dep", send_e, message) 134 | LOGGER.info(f"Successfully sent DeepSeekAI response (split) to chat {message.chat.id}") 135 | else: 136 | try: 137 | await progress_message.edit_text( 138 | text=bot_response, 139 | parse_mode=ParseMode.HTML 140 | ) 141 | LOGGER.info(f"Successfully sent DeepSeekAI response to chat {message.chat.id}") 142 | except TelegramBadRequest as edit_e: 143 | LOGGER.error(f"Failed to edit progress message in chat {message.chat.id}: {str(edit_e)}") 144 | await Smart_Notify(bot, "dep", edit_e, message) 145 | await delete_messages(message.chat.id, progress_message.message_id) 146 | await send_message( 147 | chat_id=message.chat.id, 148 | text=bot_response, 149 | parse_mode=ParseMode.HTML 150 | ) 151 | LOGGER.info(f"Successfully sent DeepSeekAI response to chat {message.chat.id}") 152 | except Exception as e: 153 | LOGGER.error(f"DeepSeekAI error in chat {message.chat.id}: {str(e)}") 154 | await Smart_Notify(bot, "dep", e, message) 155 | if progress_message: 156 | try: 157 | await progress_message.edit_text( 158 | text="❌ Sorry Bro DeepSeekAI ✨ API Dead", 159 | parse_mode=ParseMode.HTML 160 | ) 161 | LOGGER.info(f"Edited progress message with DeepSeekAI error in chat {message.chat.id}") 162 | except TelegramBadRequest as edit_e: 163 | LOGGER.error(f"Failed to edit progress message in chat {message.chat.id}: {str(edit_e)}") 164 | await Smart_Notify(bot, "dep", edit_e, message) 165 | await send_message( 166 | chat_id=message.chat.id, 167 | text="❌ Sorry Bro DeepSeekAI ✨ API Dead", 168 | parse_mode=ParseMode.HTML 169 | ) 170 | LOGGER.info(f"Sent DeepSeekAI error message to chat {message.chat.id}") 171 | else: 172 | await send_message( 173 | chat_id=message.chat.id, 174 | text="❌ Sorry Bro DeepSeekAI ✨ API Dead", 175 | parse_mode=ParseMode.HTML 176 | ) 177 | LOGGER.info(f"Sent DeepSeekAI error message to chat {message.chat.id}") --------------------------------------------------------------------------------