akn-dev / akn /clientmulti_bot.py
randydev's picture
fix revert back and update
21bc372
raw
history blame
20.1 kB
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