|
import asyncio |
|
from datetime import datetime as dt |
|
from pyrogram import Client |
|
from pyrogram.types import * |
|
from pyrogram.errors import * |
|
from pyrogram.raw.all import layer |
|
import pyromod |
|
from config import API_HASH, API_ID |
|
from akn import assistant |
|
from akn.utils.database import db |
|
from akn.utils.logger import LOGS |
|
from akn.utils.expired_bot import watch_do_time |
|
from akn import ids, gemini_bot_id |
|
from pyrogram import __version__ as pyrogram_version |
|
from box import Box |
|
|
|
async def start_user() -> None: |
|
sessions = await db.get_all_sessions() |
|
if not sessions: |
|
return |
|
active_clients = [] |
|
for i, session_data in enumerate(sessions, 1): |
|
api_id = session_data.get("api_id") |
|
api_hash = session_data.get("api_hash") |
|
session_str = session_data.get("session") |
|
user_id = session_data.get("user_id", 0) |
|
try: |
|
if not (api_id, api_hash, session_str, user_id): |
|
continue |
|
client = Client( |
|
name=f"UserBot_{i}_{user_id}", |
|
api_id=api_id, |
|
api_hash=api_hash, |
|
session_string=session_str, |
|
in_memory=False, |
|
plugins=dict(root="akn.Akeno"), |
|
workdir="/tmp/akn_sessions", |
|
app_version="UserBot/latest", |
|
device_model="Anonymous", |
|
system_version="Linux/Kernel-6.5", |
|
sleep_threshold=30 |
|
) |
|
await client.start() |
|
me = await client.get_me() |
|
if me.id != user_id: |
|
raise ValueError(f"Session user_id mismatch (expected {user_id}, got {me.id})") |
|
ids.append(user_id) |
|
LOGS.info(f"β
Started User #{i}: Name: {me.first_name}") |
|
active_clients.append(client) |
|
asyncio.create_task( |
|
_check_session_health(client, user_id), |
|
name=f"health_monitor_{user_id}" |
|
) |
|
except ( |
|
UserDeactivatedBan, |
|
AuthKeyDuplicated, |
|
UserDeactivated, |
|
AuthKeyUnregistered, |
|
SessionRevoked |
|
) as e: |
|
await _handle_dead_session(user_id, e) |
|
continue |
|
except Exception as e: |
|
LOGS.error(f"β οΈ User #{i} failed: {type(e).__name__}: {str(e)}") |
|
continue |
|
|
|
async def start_magic_bot() -> None: |
|
sessions = await db.get_all_magic_bot() |
|
if not sessions: |
|
LOGS.warning("No Magic bots found in database") |
|
return |
|
|
|
active_clients = [] |
|
active_bots = [] |
|
for i, data in enumerate(sessions): |
|
user_id = data.get("user_id") |
|
bot_token = data.get("bot_token") |
|
if not (bot_token, user_id): |
|
continue |
|
get_user_exp = await db.get_expired_date(user_id) |
|
to_obj = Box(get_user_exp or {}) |
|
if not to_obj: |
|
continue |
|
if not to_obj.get("user_client"): |
|
continue |
|
if to_obj.user_client.get("disconnected", False): |
|
continue |
|
try: |
|
client = Client( |
|
name=f"MagicBot_{i}", |
|
api_id=API_ID, |
|
api_hash=API_HASH, |
|
bot_token=bot_token, |
|
in_memory=True, |
|
plugins=dict(root="akn.MagicFonts"), |
|
workdir="/tmp/akn_magic", |
|
app_version="MagicBot/v1.1.0", |
|
device_model="SecureMagicBot", |
|
system_version="Linux/Kernel-6.5", |
|
sleep_threshold=30 |
|
) |
|
await client.start() |
|
me = await client.get_me() |
|
active_bots.append((client, user_id)) |
|
active_clients.append(client) |
|
LOGS.info(f"β
Started Magic bot {i}: {me.first_name} | {me.id}") |
|
asyncio.create_task( |
|
connection_watchdog(client), |
|
name=f"health_dog_{me.id}" |
|
) |
|
except (AuthKeyDuplicated, UserDeactivated, AccessTokenExpired) as e: |
|
LOGS.warning(f"π Bot Magic #{i} session dead: {type(e).__name__}") |
|
success = await db.remove_bot_token_magic(client.bot_token) |
|
if not success: |
|
LOGS.warning(f"β οΈ Failed to revoke token: {client.bot_token}") |
|
raise |
|
except Exception as e: |
|
LOGS.error(f"β οΈ Failed bot Magic #{i}: {type(e).__name__}: {str(e)}") |
|
await _cleanup_failed_client(client) |
|
raise |
|
|
|
tasks = [] |
|
for client, user_id in active_bots: |
|
tasks.append(watch_do_time(user_id, client, assistant)) |
|
if tasks: |
|
await asyncio.gather(*tasks) |
|
|
|
async def start_meta_bot() -> None: |
|
sessions = await db.get_all_meta_bot() |
|
if not sessions: |
|
LOGS.warning("No Meta bots found in database") |
|
return |
|
|
|
active_clients = [] |
|
active_bots_2 = [] |
|
for i, data in enumerate(sessions): |
|
user_id = data.get("user_id") |
|
bot_token = data.get("bot_token") |
|
if not (bot_token, user_id): |
|
continue |
|
get_user_exp = await db.get_expired_date(user_id) |
|
to_obj = Box(get_user_exp or {}) |
|
if not to_obj: |
|
continue |
|
if not to_obj.get("user_client"): |
|
continue |
|
if to_obj.user_client.get("disconnected", False): |
|
continue |
|
try: |
|
client = Client( |
|
name=f"MetaAI_{i}", |
|
api_id=API_ID, |
|
api_hash=API_HASH, |
|
bot_token=bot_token, |
|
in_memory=True, |
|
plugins=dict(root="akn.Meta"), |
|
workdir="/tmp/akn_meta", |
|
app_version="MetaBot/v1.1.0", |
|
device_model="SecureMetaBot", |
|
system_version="Linux/Kernel-6.5", |
|
sleep_threshold=30 |
|
) |
|
await client.start() |
|
me = await client.get_me() |
|
active_bots_2.append((client, user_id)) |
|
active_clients.append(client) |
|
LOGS.info(f"β
Started Meta AI bot {i}: {me.first_name} | {me.id}") |
|
asyncio.create_task( |
|
connection_watchdog(client), |
|
name=f"health_dog_{me.id}" |
|
) |
|
except (AuthKeyDuplicated, UserDeactivated, AccessTokenExpired) as e: |
|
LOGS.warning(f"π Bot Meta #{i} session dead: {type(e).__name__}") |
|
success = await db.remove_bot_token_meta(client.bot_token) |
|
if not success: |
|
LOGS.warning(f"Failed to revoke token: {client.bot_token}") |
|
raise |
|
except Exception as e: |
|
LOGS.error(f"β οΈ Failed bot Meta #{i}: {type(e).__name__}: {str(e)}") |
|
await _cleanup_failed_client(client) |
|
raise |
|
|
|
taskso = [] |
|
for client, user_id in active_bots_2: |
|
taskso.append(watch_do_time(user_id, client, assistant)) |
|
if taskso: |
|
await asyncio.gather(*taskso) |
|
|
|
async def start_gemini_bot() -> None: |
|
sessions = await db.get_all_gemini_bot() |
|
if not sessions: |
|
LOGS.warning("No Gemini bots found in database") |
|
return |
|
|
|
active_clients = [] |
|
|
|
for i, data in enumerate(sessions, 1): |
|
try: |
|
bot_token = data.get("bot_token") |
|
if not bot_token: |
|
continue |
|
client = Client( |
|
name=f"GeminiBot_{i}", |
|
api_id=API_ID, |
|
api_hash=API_HASH, |
|
bot_token=bot_token, |
|
in_memory=True, |
|
plugins=dict(root="akn.Gemini"), |
|
workdir="/tmp/akn_gemini", |
|
app_version="GeminiBot/v1.1.0", |
|
device_model="SecureGemini", |
|
system_version="Linux/Kernel-6.5", |
|
sleep_threshold=30 |
|
) |
|
await client.start() |
|
me = await client.get_me() |
|
gemini_bot_id.append(me.id) |
|
active_clients.append(client) |
|
LOGS.info(f"β
Started Gemini bot {i}: {me.first_name} | {me.id}") |
|
asyncio.create_task( |
|
connection_watchdog(client), |
|
name=f"health_dog_{me.id}" |
|
) |
|
except (AuthKeyDuplicated, UserDeactivated, AccessTokenExpired) as e: |
|
LOGS.warning(f"π Bot Gemini #{i} session dead: {type(e).__name__}") |
|
success = await db.remove_bot_token_gemini(client.bot_token) |
|
if not success: |
|
LOGS.warning(f"β οΈ Failed to revoke token: {client.bot_token}") |
|
raise |
|
except Exception as e: |
|
LOGS.error(f"β οΈ Failed bot Gemini #{i}: {type(e).__name__}: {str(e)}") |
|
await _cleanup_failed_client(client) |
|
raise |
|
|
|
async def start_youtube_bot() -> None: |
|
sessions = await db.get_all_youtube_bot() |
|
if not sessions: |
|
LOGS.warning("No YouTube bots found in database") |
|
return |
|
|
|
active_clients = [] |
|
for i, data in enumerate(sessions, 1): |
|
try: |
|
bot_token = data.get("bot_token") |
|
if not bot_token: |
|
continue |
|
client = Client( |
|
name=f"YoutubeBot_{i}", |
|
api_id=API_ID, |
|
api_hash=API_HASH, |
|
bot_token=bot_token, |
|
in_memory=True, |
|
plugins=dict(root="akn.Youtube"), |
|
workdir="/tmp/akn_youtubebot", |
|
app_version="YoutubeBot/v1.1.0", |
|
device_model="SecureYoutubeBot", |
|
system_version="Linux/Kernel-6.5", |
|
sleep_threshold=30 |
|
) |
|
await client.start() |
|
me = await client.get_me() |
|
LOGS.info(f"β
Started Youtube bot {i}: {me.first_name} | {me.id}") |
|
asyncio.create_task( |
|
connection_watchdog(client), |
|
name=f"health_dog_{me.id}" |
|
) |
|
except (AuthKeyDuplicated, UserDeactivated, AccessTokenExpired) as e: |
|
LOGS.warning(f"π Bot YouTube #{i} session dead: {type(e).__name__}") |
|
success = await db.remove_bot_token_youtube(client.bot_token) |
|
if not success: |
|
LOGS.warning(f"β οΈ Failed to revoke token: {client.bot_token}") |
|
raise |
|
except Exception as e: |
|
LOGS.error(f"β οΈ Failed bot Session #{i}: {type(e).__name__}: {str(e)}") |
|
await _cleanup_failed_client(client) |
|
raise |
|
|
|
async def start_session_bot() -> None: |
|
sessions = await db.get_all_session_bot() |
|
if not sessions: |
|
LOGS.warning("No Session bots found in database") |
|
return |
|
|
|
active_clients = [] |
|
for i, data in enumerate(sessions, 1): |
|
try: |
|
bot_token = data.get("bot_token") |
|
if not bot_token: |
|
continue |
|
client = Client( |
|
name=f"SessionBot_{i}", |
|
api_id=API_ID, |
|
api_hash=API_HASH, |
|
bot_token=bot_token, |
|
in_memory=True, |
|
plugins=dict(root="akn.SessionBot"), |
|
workdir="/tmp/akn_sessionbot", |
|
app_version="SessionBot/v1.1.0", |
|
device_model="SecureSessionBot", |
|
system_version="Linux/Kernel-6.5", |
|
sleep_threshold=30 |
|
) |
|
await client.start() |
|
me = await client.get_me() |
|
active_clients.append(client) |
|
LOGS.info(f"β
Started Session bot {i}: {me.first_name} | {me.id}") |
|
asyncio.create_task( |
|
connection_watchdog(client), |
|
name=f"health_dog_{me.id}" |
|
) |
|
except (AuthKeyDuplicated, UserDeactivated, AccessTokenExpired) as e: |
|
LOGS.warning(f"π Bot Session #{i} session dead: {type(e).__name__}") |
|
success = await db.remove_bot_token_sessionbot(client.bot_token) |
|
if not success: |
|
LOGS.warning(f"β οΈ Failed to revoke token: {client.bot_token}") |
|
raise |
|
except Exception as e: |
|
LOGS.error(f"β οΈ Failed bot Session #{i}: {type(e).__name__}: {str(e)}") |
|
await _cleanup_failed_client(client) |
|
raise |
|
|
|
async def start_captcha_bot() -> None: |
|
sessions = await db.get_all_captcha_bot() |
|
for i, data in enumerate(sessions): |
|
try: |
|
bot_token = data.get("bot_token") |
|
client = Client( |
|
name=f"CaptchaBot#{i + 1}", |
|
api_id=API_ID, |
|
api_hash=API_HASH, |
|
bot_token=bot_token, |
|
app_version="latest", |
|
device_model="Captcha Bot", |
|
system_version="Linux", |
|
plugins=dict(root="akn.ApproveBot"), |
|
) |
|
await client.start() |
|
me = await client.get_me() |
|
LOGS.info(f"β
Started Captcha bot {i + 1}: {me.first_name} | {me.id}") |
|
except AuthKeyDuplicated: |
|
continue |
|
except UserDeactivated: |
|
continue |
|
except Exception as e: |
|
continue |
|
|
|
async def start_all_downloader_bot() -> None: |
|
try: |
|
bot_sessions = await db.alldl_bot.find({ |
|
"bots": { |
|
"$elemMatch": { |
|
"status": "approved", |
|
"is_active": True |
|
} |
|
} |
|
}).to_list(length=None) |
|
if not bot_sessions: |
|
LOGS.warning("No active downloader bots found in database") |
|
return |
|
LOGS.info(f"β
Starting {len(bot_sessions)} downloader bots...") |
|
active_clients = [] |
|
success_count = 0 |
|
|
|
for i, session_data in enumerate(bot_sessions, 1): |
|
user_id = session_data.get("user_id") |
|
bots = session_data.get("bots", []) |
|
|
|
for bot_data in bots: |
|
if not (bot_data.get("status") == "approved" and bot_data.get("is_active")): |
|
continue |
|
|
|
bot_token = bot_data.get("bot_token") |
|
if not bot_token: |
|
LOGS.warning(f"Skipping bot #{i} - No token found for user {user_id}") |
|
continue |
|
|
|
try: |
|
client = Client( |
|
name=f"AllDLBot_{user_id}_{i}", |
|
api_id=API_ID, |
|
api_hash=API_HASH, |
|
bot_token=bot_token, |
|
in_memory=True, |
|
plugins=dict(root="akn.AllDownloaderBot"), |
|
workdir="/tmp", |
|
app_version="DLBot/v2.0.0", |
|
device_model="SecureDownloaderPro", |
|
system_version="Linux/Kernel-6.6", |
|
sleep_threshold=30 |
|
) |
|
|
|
start_success = await _startv_client_downloader_safely(client, i, user_id) |
|
if start_success: |
|
active_clients.append({ |
|
"client": client, |
|
"user_id": user_id, |
|
"bot_data": bot_data |
|
}) |
|
success_count += 1 |
|
|
|
await db.alldl_bot.update_one( |
|
{"user_id": user_id, "bots.bot_token": bot_token}, |
|
{"$set": {"bots.$.last_active": dt.now().isoformat()}} |
|
) |
|
|
|
except Exception as e: |
|
error_type = type(e).__name__ |
|
LOGS.error(f"β οΈ Failed to start bot #{i} for user {user_id}: {error_type}: {str(e)}") |
|
await db.alldl_bot.update_one( |
|
{"user_id": user_id, "bots.bot_token": bot_token}, |
|
{"$set": {"bots.$.is_active": False, "bots.$.error": str(e)}} |
|
) |
|
|
|
await _cleanupv_failed_client(client) |
|
continue |
|
|
|
LOGS.info(f"β
Successfully started {success_count}/{len(bot_sessions)} bots") |
|
|
|
global storage_running |
|
storage_running = active_clients |
|
|
|
except Exception as e: |
|
LOGS.critical(f"β οΈ Fatal error in bot startup: {type(e).__name__}: {str(e)}") |
|
raise |
|
|
|
async def _startv_client_downloader_safely(client: Client, index: int, user_id: int) -> bool: |
|
try: |
|
await asyncio.wait_for(client.start(), timeout=30) |
|
|
|
me = await client.get_me() |
|
if not me: |
|
raise ConnectionError("Failed to get bot identity") |
|
|
|
LOGS.info(f"β
Bot #{index} started for user {user_id} - @{me.username}") |
|
return True |
|
|
|
except asyncio.TimeoutError: |
|
LOGS.warning(f"β Timeout starting bot #{index} for user {user_id}") |
|
except Exception as e: |
|
LOGS.error(f"β οΈ Error starting bot #{index} for user {user_id}: {str(e)}") |
|
return False |
|
|
|
async def _cleanupv_failed_client(client: Client) -> None: |
|
try: |
|
if client.is_connected: |
|
await client.stop() |
|
except Exception as e: |
|
LOGS.warning(f"Error during client cleanup: {str(e)}") |
|
finally: |
|
await client.disconnect() |
|
|
|
async def _start_client_downloder_safely(client: Client, bot_num: int) -> None: |
|
try: |
|
await client.start() |
|
me = await client.get_me() |
|
LOGS.info( |
|
f"β
Started Downloader Bot #{bot_num}: " |
|
f"{me.first_name} (ID: {me.id})" |
|
) |
|
asyncio.create_task( |
|
connection_watchdog(client), |
|
name=f"health_dog_{me.id}" |
|
) |
|
except (AuthKeyDuplicated, UserDeactivated, AccessTokenExpired) as e: |
|
LOGS.warning(f"π Bot Downloader #{bot_num} session dead: {type(e).__name__}") |
|
success = await db.remove_bot_token_alldlbot(client.bot_token) |
|
if not success: |
|
LOGS.warning(f"β οΈ Failed to revoke token: {client.bot_token}") |
|
raise |
|
except Exception as e: |
|
LOGS.error(f"β οΈ Bot Downloader #{bot_num} critical failure: {str(e)}") |
|
raise |
|
|
|
async def _check_session_health(client: Client, user_id: int, interval: int = 300) -> None: |
|
while True: |
|
try: |
|
await asyncio.wait_for(client.get_me(), timeout=10) |
|
|
|
if not client.is_connected: |
|
raise ConnectionError("Client disconnected") |
|
|
|
LOGS.debug(f"Session health OK: User {user_id}") |
|
await asyncio.sleep(interval) |
|
|
|
except (UserDeactivated, AuthKeyInvalid) as e: |
|
LOGS.warning(f"π Session dead for {user_id}: {type(e).__name__}") |
|
await _handle_dead_session(user_id, e) |
|
break |
|
except Exception as e: |
|
LOGS.error(f"Health check failed for {user_id}: {type(e).__name__}: {str(e)}") |
|
await asyncio.sleep(60) |
|
|
|
async def _handle_dead_session(user_id: int, error: Exception) -> None: |
|
LOGS.warning(f"Cleaning up dead session: {user_id}") |
|
await _send_message_warning( |
|
user_id, |
|
f"π¨ Session terminated\n" |
|
f"User: {user_id}\n" |
|
f"Reason: Error: {type(error).__name__}" |
|
) |
|
await db.remove_strings_userv(user_id) |
|
LOGS.warning( |
|
f"π¨ Session terminated\n" |
|
f"User: {user_id}\n" |
|
f"Reason: {type(error).__name__}" |
|
) |
|
|
|
async def check_connection(client: Client) -> bool: |
|
try: |
|
return await client.get_me() is not None |
|
except: |
|
return False |
|
|
|
async def connection_watchdog(client: Client): |
|
while True: |
|
if not await check_connection(client): |
|
LOGS.warning("Reconnecting...") |
|
await client.disconnect() |
|
await client.connect() |
|
await asyncio.sleep(300) |
|
|
|
async def _send_message_warning(user_id, text): |
|
try: |
|
await assistant.send_message(user_id, text) |
|
except: |
|
pass |
|
|
|
async def _cleanup_failed_client(client: Client | None) -> None: |
|
if client: |
|
try: |
|
await client.stop() |
|
except: |
|
pass |
|
finally: |
|
del client |