diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..85ed2cab07f9eae8d3f6e4ccca227fe676e9984c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,37 @@ +*.7z filter=lfs diff=lfs merge=lfs -text +*.arrow filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.ckpt filter=lfs diff=lfs merge=lfs -text +*.ftz filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.h5 filter=lfs diff=lfs merge=lfs -text +*.joblib filter=lfs diff=lfs merge=lfs -text +*.lfs.* filter=lfs diff=lfs merge=lfs -text +*.mlmodel filter=lfs diff=lfs merge=lfs -text +*.model filter=lfs diff=lfs merge=lfs -text +*.msgpack filter=lfs diff=lfs merge=lfs -text +*.npy filter=lfs diff=lfs merge=lfs -text +*.npz filter=lfs diff=lfs merge=lfs -text +*.onnx filter=lfs diff=lfs merge=lfs -text +*.ot filter=lfs diff=lfs merge=lfs -text +*.parquet filter=lfs diff=lfs merge=lfs -text +*.pb filter=lfs diff=lfs merge=lfs -text +*.pickle filter=lfs diff=lfs merge=lfs -text +*.pkl filter=lfs diff=lfs merge=lfs -text +*.pt filter=lfs diff=lfs merge=lfs -text +*.pth filter=lfs diff=lfs merge=lfs -text +*.rar filter=lfs diff=lfs merge=lfs -text +*.safetensors filter=lfs diff=lfs merge=lfs -text +saved_model/**/* filter=lfs diff=lfs merge=lfs -text +*.tar.* filter=lfs diff=lfs merge=lfs -text +*.tar filter=lfs diff=lfs merge=lfs -text +*.tflite filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.wasm filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text +*tfevents* filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text diff --git a/Data.py b/Data.py new file mode 100755 index 0000000000000000000000000000000000000000..aeaf4397bbfe4abe566c2b7623b88294790acad6 --- /dev/null +++ b/Data.py @@ -0,0 +1,56 @@ +from pyrogram.types import InlineKeyboardButton + +class Data: + START = """ +👋 **Hello {}!** + +**Welcome {}!** + +We’re glad to have you here. This bot is designed to help you generate a **String Session** easily and securely. + +🚨 **Important Notes**: +If you don’t trust this bot: +1. **Don’t read this message**. +2. **Block the bot** or **delete the chat**. + +🤖 **How This Bot Works**: +- This bot helps you generate a **String Session** for your Telegram account. +- **Recommendation**: Use a secondary account to generate the String Session. This avoids delays and keeps your main account secure. +""" + + home_buttons = [ + [InlineKeyboardButton("🔥 sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ sᴇssɪᴏɴ 🔥", callback_data="generate")], + [InlineKeyboardButton(text="ᴋᴇᴍʙᴀʟɪ", callback_data="home")], + ] + + generate_button = [ + [InlineKeyboardButton("🔥 sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ sᴇssɪᴏɴ 🔥", callback_data="generate")] + ] + + buttons = [ + [InlineKeyboardButton("🔥 sᴛᴀʀᴛ ɢᴇɴᴇʀᴀᴛɪɴɢ sᴇssɪᴏɴ 🔥", callback_data="generate")], + [ + InlineKeyboardButton("ᴀʙᴏᴜᴛ", callback_data="about") + ] + ] + + HELP = """ +**Available Commands** + +/about - About this Bot +/help - This Message +/start - Start bot +/generate - Start Generating Session +""" + + ABOUT = """ +**About This Bot** + +A telegram bot to retrieve pyrograms and telethon string session by @VegetaSessionBot + +Framework : [Pyrogram](docs.pyrogram.org) + +Language : [Python](www.python.org) + +Developer : @xpushz +""" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100755 index 0000000000000000000000000000000000000000..6f39c2ef7a1e4a22eeff303eb6bede27155eee2b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,60 @@ +FROM python:3.11.11 + +RUN apt -qq update && \ + apt -qq install -y --no-install-recommends \ + ffmpeg \ + curl \ + git \ + gnupg2 \ + unzip \ + wget \ + xvfb \ + libxi6 \ + libgconf-2-4 \ + libappindicator3-1 \ + libxrender1 \ + libxtst6 \ + libnss3 \ + libatk1.0-0 \ + libxss1 \ + fonts-liberation \ + libasound2 \ + libgbm-dev \ + libu2f-udev \ + libvulkan1 \ + libgl1-mesa-dri \ + xdg-utils \ + python3-dev \ + python3-pip \ + libavformat-dev \ + libavcodec-dev \ + libavdevice-dev \ + libavfilter-dev \ + libavutil-dev \ + libswscale-dev \ + libswresample-dev \ + neofetch && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/ + +WORKDIR /app + +COPY requirements.txt . +COPY . . + +RUN mkdir -p /app/.cache/akn && \ + chmod -R 777 /app/.cache + +RUN chown -R 1000:0 . +RUN pip3 install --upgrade pip setuptools +RUN pip3 install -r requirements.txt + +RUN wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz && \ + wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz.md5 && \ + md5sum -c ffmpeg-git-amd64-static.tar.xz.md5 && \ + tar xvf ffmpeg-git-amd64-static.tar.xz && \ + mv ffmpeg-git*/ffmpeg ffmpeg-git*/ffprobe /usr/local/bin/ + +EXPOSE 7860 + +CMD ["bash", "-c", "python3 server.py & python3 -m akn"] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cc62adeaa5943ec387301a7f68689510898cf8da --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +--- +title: Akn +emoji: 🏆 +colorFrom: pink +colorTo: purple +sdk: docker +pinned: false +license: mit +--- + +Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference diff --git a/akn/Akeno/__init__.py b/akn/Akeno/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..3cdf7c701ed675425cf643c8d915823c6a489e53 --- /dev/null +++ b/akn/Akeno/__init__.py @@ -0,0 +1,11 @@ +from pyrogram.types import Message + +api_key_openai = "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" + +def ReplyCheck(message: Message): + reply_id = None + if message.reply_to_message: + reply_id = message.reply_to_message.id + elif not message.from_user.is_self: + reply_id = message.id + return reply_id \ No newline at end of file diff --git a/akn/Akeno/admin.py b/akn/Akeno/admin.py new file mode 100755 index 0000000000000000000000000000000000000000..8ef33c18f31147ea33e9bd47fa8d7991b6c7f4e7 --- /dev/null +++ b/akn/Akeno/admin.py @@ -0,0 +1,392 @@ +# Copyright (C) 2020-2023 TeamKillerX +# +# This file is part of TeamKillerX project, +# and licensed under GNU Affero General Public License v3. +# See the GNU Affero General Public License for more details. +# +# All rights reserved. See COPYING, AUTHORS. +# + +import asyncio +import time +from time import time as waktu + +from pyrogram import Client +from pyrogram import Client as ren +from pyrogram import * +from pyrogram import filters +from pyrogram.errors import * +from pyrogram.types import * + +from akn.utils.handler import * +from akn.Akeno.help import add_command_help +from akn.utils.logger import LOGS +from akn.utils.prefixprem import command +from config import * + +admins_in_chat = {} + +unmute_permissions = ChatPermissions( + can_send_messages=True, + can_send_media_messages=True, + can_send_polls=True, + can_change_info=False, + can_invite_users=True, + can_pin_messages=False, +) + + +async def extract_userid(message, text: str): + def is_int(text: str): + try: + int(text) + except ValueError: + return False + return True + + text = text.strip() + + if is_int(text): + return int(text) + + entities = message.entities + app = message._client + if len(entities) < 2: + return (await app.get_users(text)).id + entity = entities[1] + if entity.type == "mention": + return (await app.get_users(text)).id + if entity.type == "text_mention": + return entity.user.id + return None + + +async def extract_user_and_reason(message, sender_chat=False): + args = message.text.strip().split() + text = message.text + user = None + reason = None + if message.reply_to_message: + reply = message.reply_to_message + if not reply.from_user: + if ( + reply.sender_chat + and reply.sender_chat != message.chat.id + and sender_chat + ): + id_ = reply.sender_chat.id + else: + return None, None + else: + id_ = reply.from_user.id + + if len(args) < 2: + reason = None + else: + reason = text.split(None, 1)[1] + return id_, reason + + if len(args) == 2: + user = text.split(None, 1)[1] + return await extract_userid(message, user), None + + if len(args) > 2: + user, reason = text.split(None, 2)[1:] + return await extract_userid(message, user), reason + + return user, reason + + +async def extract_user(message): + return (await extract_user_and_reason(message))[0] + + +async def list_admins(client: Client, chat_id: int): + global admins_in_chat + if chat_id in admins_in_chat: + interval = time() - admins_in_chat[chat_id]["last_updated_at"] + if interval < 3600: + return admins_in_chat[chat_id]["data"] + + admins_in_chat[chat_id] = { + "last_updated_at": waktu(), + "data": [ + member.user.id + async for member in client.get_chat_members( + chat_id, filter=enums.ChatMembersFilter.ADMINISTRATORS + ) + ], + } + return admins_in_chat[chat_id]["data"] + + +@Akeno( + ~filters.scheduled & command(["ban", "dban", "hban"]) & filters.me & ~filters.forwarded +) +async def member_ban_user(client: Client, message: Message): + user_id, reason = await extract_user_and_reason(message, sender_chat=True) + rd = await message.edit_text("`Processing...`") + bot = (await client.get_chat_member(message.chat.id, client.me.id)).privileges + if not bot.can_restrict_members: + return await rd.edit_text("I don't have enough permissions") + if not user_id: + return await rd.edit_text("I can't find that user.") + if user_id == client.me.id: + return await rd.edit_text("I can't ban myself.") + if user_id == 1191668125: + return await rd.edit_text("I can't ban my developer!") + if user_id in (await list_admins(client, message.chat.id)): + return await rd.edit_text("I can't ban an admin, You know the rules, so do i.") + try: + mention = (await client.get_users(user_id)).mention + except IndexError: + mention = ( + message.reply_to_message.sender_chat.title + if message.reply_to_message + else "Anon" + ) + msg = ( + f"**Banned User:** {mention}\n" + f"**Banned By:** {message.from_user.mention if message.from_user else 'Anon'}\n" + ) + if message.command[0][0] == "d": + await message.reply_to_message.delete() + elif message.command[0][0] == "h": + await client.delete_user_history(message.chat.id, user_id) + if reason: + msg += f"**Reason:** {reason}" + await message.chat.ban_member(user_id) + await rd.edit_text(msg) + + +@Akeno( + ~filters.scheduled & command(["unban"]) & filters.me & ~filters.forwarded +) +async def member_unban_user(client: Client, message: Message): + reply = message.reply_to_message + rd = await message.edit_text("`Processing...`") + bot = (await client.get_chat_member(message.chat.id, client.me.id)).privileges + if not bot.can_restrict_members: + return await rd.edit_text("I don't have enough permissions") + if reply and reply.sender_chat and reply.sender_chat != message.chat.id: + return await rd.edit_text("You cannot unban a channel") + + if len(message.command) == 2: + user = message.text.split(None, 1)[1] + elif len(message.command) == 1 and reply: + user = message.reply_to_message.from_user.id + else: + return await rd.edit_text( + "Provide a username or reply to a user's message to unban." + ) + await message.chat.unban_member(user) + umention = (await client.get_users(user)).mention + await rd.edit_text(f"Unbanned! {umention}") + + +@Akeno( + ~filters.scheduled & command(["pin", "unpin"]) & filters.me & ~filters.forwarded +) +async def pin_message(client: Client, message: Message): + if not message.reply_to_message: + return await message.edit_text("Reply to a message to pin/unpin it.") + rd = await message.edit_text("`Processing...`") + bot = (await client.get_chat_member(message.chat.id, client.me.id)).privileges + if not bot.can_pin_messages: + return await rd.edit_text("I don't have enough permissions") + r = message.reply_to_message + if message.command[0][0] == "u": + await r.unpin() + return await rd.edit_text( + f"**Unpinned [this]({r.link}) message.**", + disable_web_page_preview=True, + ) + await r.pin(disable_notification=True) + await rd.edit_text( + f"**Pinned [this]({r.link}) message.**", + disable_web_page_preview=True, + ) + +@Akeno( + ~filters.scheduled & command(["mute", "dmute", "hmute"]) & filters.me & ~filters.forwarded +) +async def mute_user(client: Client, message: Message): + user_id, reason = await extract_user_and_reason(message) + rd = await message.edit_text("`Processing...`") + bot = (await client.get_chat_member(message.chat.id, client.me.id)).privileges + if not bot.can_restrict_members: + return await rd.edit_text("I don't have enough permissions") + if not user_id: + return await rd.edit_text("I can't find that user.") + if user_id == client.me.id: + return await rd.edit_text("I can't mute myself.") + if user_id == 1191668125: + return await rd.edit("I can't mute my developer!") + if user_id in (await list_admins(client, message.chat.id)): + return await rd.edit_text("I can't mute an admin, You know the rules, so do i.") + mention = (await client.get_users(user_id)).mention + msg = ( + f"**Muted User:** {mention}\n" + f"**Muted By:** {message.from_user.mention if message.from_user else 'Anon'}\n" + ) + if message.command[0][0] == "d": + await message.reply_to_message.delete() + elif message.command[0][0] == "h": + await client.delete_user_history(message.chat.id, user_id) + if reason: + msg += f"**Reason:** {reason}" + await message.chat.restrict_member(user_id, permissions=ChatPermissions()) + await rd.edit_text(msg) + +@Akeno( + ~filters.scheduled & command(["unmute"]) & filters.me & ~filters.forwarded +) +async def unmute_user(client: Client, message: Message): + user_id = await extract_user(message) + rd = await message.edit_text("`Processing...`") + bot = (await client.get_chat_member(message.chat.id, client.me.id)).privileges + if not bot.can_restrict_members: + return await rd.edit_text("I don't have enough permissions") + if not user_id: + return await rd.edit_text("I can't find that user.") + await message.chat.restrict_member(user_id, permissions=unmute_permissions) + umention = (await client.get_users(user_id)).mention + await rd.edit_text(f"Unmuted! {umention}") + +@Akeno( + ~filters.scheduled & command(["kick", "dkick", "hkick"]) & filters.me & ~filters.forwarded +) +async def kick_user(client: Client, message: Message): + user_id, reason = await extract_user_and_reason(message) + rd = await message.edit_text("`Processing...`") + bot = (await client.get_chat_member(message.chat.id, client.me.id)).privileges + if not bot.can_restrict_members: + return await rd.edit_text("I don't have enough permissions") + if not user_id: + return await rd.edit_text("I can't find that user.") + if user_id == client.me.id: + return await rd.edit_text("I can't kick myself.") + if user_id == 1191668125: + return await rd.edit_text("I can't kick my developer.") + if user_id in (await list_admins(client, message.chat.id)): + return await rd.edit_text("I can't kick an admin, You know the rules, so do i.") + mention = (await client.get_users(user_id)).mention + msg = f""" +**Kicked User:** {mention} +**Kicked By:** {message.from_user.mention if message.from_user else 'Anon'}""" + if message.command[0][0] == "d": + await message.reply_to_message.delete() + elif message.command[0][0] == "h": + await client.delete_user_history(message.chat.id, user_id) + if reason: + msg += f"\n**Reason:** `{reason}`" + try: + await message.chat.ban_member(user_id) + await rd.edit_text(msg) + await asyncio.sleep(1) + await message.chat.unban_member(user_id) + except ChatAdminRequired: + return await rd.edit_text("**Maaf Anda Bukan admin**") + +@Akeno( + ~filters.scheduled & command(["promote", "fullpromote"]) & filters.me & ~filters.forwarded +) +async def promotte_user(client: Client, message: Message): + user_id = await extract_user(message) + umention = (await client.get_users(user_id)).mention + rd = await message.edit_text("`Processing...`") + if not user_id: + return await rd.edit_text("I can't find that user.") + bot = (await client.get_chat_member(message.chat.id, client.me.id)).privileges + if not bot.can_promote_members: + return await rd.edit_text("I don't have enough permissions") + if message.command[0][0] == "f": + await message.chat.promote_member( + user_id, + privileges=ChatPrivileges( + can_manage_chat=True, + can_delete_messages=True, + can_manage_video_chats=True, + can_restrict_members=True, + can_change_info=True, + can_invite_users=True, + can_pin_messages=True, + can_promote_members=True, + ), + ) + return await rd.edit_text(f"Fully Promoted! {umention}") + + await message.chat.promote_member( + user_id, + privileges=ChatPrivileges( + can_manage_chat=True, + can_delete_messages=True, + can_manage_video_chats=True, + can_restrict_members=True, + can_change_info=True, + can_invite_users=True, + can_pin_messages=True, + can_promote_members=False, + ), + ) + await rd.edit_text(f"Promoted! {umention}") + +@Akeno( + ~filters.scheduled & command(["demote"]) & filters.me & ~filters.forwarded +) +async def demote_user(client: Client, message: Message): + user_id = await extract_user(message) + rd = await message.edit_text("`Processing...`") + if not user_id: + return await rd.edit_text("I can't find that user.") + if user_id == client.me.id: + return await rd.edit_text("I can't demote myself.") + await message.chat.promote_member( + user_id, + privileges=ChatPrivileges( + can_manage_chat=False, + can_delete_messages=False, + can_manage_video_chats=False, + can_restrict_members=False, + can_change_info=False, + can_invite_users=False, + can_pin_messages=False, + can_promote_members=False, + ), + ) + umention = (await client.get_users(user_id)).mention + await rd.edit_text(f"Demoted! {umention}") + +add_command_help( + "admin", + [ + ["ban [reply/username/userid]", "Ban someone."], + ["dban [reply]", "dban a user deleting the replied to message."], + ["unban [reply/username/userid]", "Unban someone."], + ["kick [reply/username/userid]", "kick out someone from your group."], + ["dkick [reply]", "dkick a user deleting the replied to message."], + ["promote `or` .fullpromote", "Promote someonen."], + ["demote", "Demote someone."], + ["mute [reply/username/userid]", "Mute someone."], + ["dmute [reply]", "dmute a user deleting the replied to message."], + ["unmute [reply/username/userid]", "Unmute someone."], + ["pin [reply]", "to pin any message."], + ["unpin [reply]", "To unpin any message."], + ["setgpic [reply ke image]", "To set an group profile pic."], + ], +) +module = modules_help.add_module("admin", __file__) +module.add_command("ban", "Ban someone.") +module.add_command("dban", "dban a user deleting the replied to message") +module.add_command("hban", "hban a user deleting all the replied to message") +module.add_command("kick", "kick out someone from your group") +module.add_command("dkick", "dkick a user deleting the replied to message") +module.add_command("hkick", "hkick a user deleting all the replied to message") +module.add_command("promote", "Promote someonen") +module.add_command("demote", "Demote someone") +module.add_command("mute", "Mute someone") +module.add_command("dmute", "dmute a user deleting the replied to message") +module.add_command("hmute", "dmute a user deleting all the replied to message") +module.add_command("pin", "to pin any message.") +module.add_command("unpin", "To unpin any message") +module.add_command("setgpic", "To set an group profile pic.") diff --git a/akn/Akeno/alive.py b/akn/Akeno/alive.py new file mode 100755 index 0000000000000000000000000000000000000000..88af8a2167a24e6c5e56d99a3ecb2fecc3b83f94 --- /dev/null +++ b/akn/Akeno/alive.py @@ -0,0 +1,128 @@ +import os +import random +import re +import asyncio +from random import choice +from pyrogram import Client, filters +from pyrogram.types import * +from akn.utils.handler import * +from akn import app +from akn.utils.prefixprem import command +from config import * +from RyuzakiLib import __version__ as ryu_version +from platform import python_version +from pyrogram.raw import functions + + +akeno_premium_text = """ +**Status Ubot** + **User Free**: [Ultra Premium] + {custom_emoji}**dc_id:** `{dc_id}` + {custom_emoji}**python_version:** `{python}` + {custom_emoji}**ryuzakilib_version:** `{ryu}` + {custom_emoji}**app_name:** `{app_name}` + {custom_emoji}**app_version:** `{app_version}` + {custom_emoji}**system_version:** `{system_version}` + {custom_emoji}**is_premium:** `{is_premium}` + {custom_emoji}**unlimited_by:** [aknuserbot]({aknuserbot}) +""" + +ryuzaki_text = """ +**Status Ubot** + **User Free**: [PRO] + **dc_id:** `{dc_id}` + **python_version:** `{python}` + **ryuzakilib_version:** `{ryu}` + **app_name:** `{app_name}` + **app_version:** `{app_version}` + **system_version:** `{system_version}` + **is_premium:** null + **unlimited_by:** [aknuserbot]({aknuserbot}) +""" + +CUSTOM_EMOJI_ALL = [ + 5469770984670108755, + 5301067044400146520, + 5300950543412241242, + 5300928913956938544, + 5301155675345265040, + 5300957668762987048, + 5366318141771096216, + 6039606071314615141, + 5971808079811972376, + 5764623873974734153, + 6048474766463996499, + 5974226571601382719, + 6041914500272098262, + 5974083454701145202, + 5328317370647715629 +] + +async def authorization(client: Client): + model = await client.invoke( + functions.account.GetAuthorizations() + ) + app_name = model.authorizations[0].app_name + app_version = model.authorizations[0].app_version + system_version = model.authorizations[0].system_version + return app_name, app_version, system_version + +@Akeno( + ~filters.scheduled + & command(["alivepro"]) + & filters.me + & ~filters.forwarded +) +async def akenopro(client: Client, message: Message): + bot_username = app.me.username + try: + oh = await client.get_inline_bot_results(bot=bot_username, query="test") + await asyncio.gather( + client.send_inline_bot_result( + message.chat.id, + oh.query_id, + oh.results[0].id, + reply_to_message_id=message.id + ) + ) + except Exception as e: + await message.reply_text(f"Error : {e}") + +@Akeno( + ~filters.scheduled + & command(["alive"]) + & filters.me + & ~filters.forwarded +) +async def akenocmd(client: Client, message: Message): + app_name, app_version, system_version = await authorization(client) + custom_emoji_random = choice(CUSTOM_EMOJI_ALL) + custom_emoji = f"" + if client.me.is_premium: + await message.reply_text( + akeno_premium_text.format( + dc_id=client.me.dc_id if client.me else 0, + custom_emoji=custom_emoji, + python=python_version(), + ryu=ryu_version, + app_name=app_name, + app_version=app_version, + system_version=system_version, + is_premium=client.me.is_premium, + aknuserbot="https://t.me/aknuserbot" + ), + disable_web_page_preview=True + ) + else: + await message.reply_text( + ryuzaki_text.format( + dc_id=client.me.dc_id if client.me else 0, + python=python_version(), + ryu=ryu_version, + app_name=app_name, + app_version=app_version, + system_version=system_version, + aknuserbot="https://t.me/aknuserbot" + ), + disable_web_page_preview=True + ) diff --git a/akn/Akeno/bot/Nothing b/akn/Akeno/bot/Nothing new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/akn/Akeno/bot/__init__.py b/akn/Akeno/bot/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/akn/Akeno/bot/bot.py b/akn/Akeno/bot/bot.py new file mode 100755 index 0000000000000000000000000000000000000000..1757b59f83fcd37028436094fadd746a8261e9bf --- /dev/null +++ b/akn/Akeno/bot/bot.py @@ -0,0 +1,203 @@ +import traceback +import time +import aiohttp +import platform +import asyncio +import os + +from pyrogram import filters +from pyrogram.errors import MessageDeleteForbidden +from pyrogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup +from pyrogram.types import * +from pyrogram import Client + +from pyrogram import * +from akn import CMD_HELP, app +from akn.Akeno.helper.data import Data +from akn.Akeno.helper.inline import paginate_help, cb_wrapper +from akn import ids as users +from config import * +import requests +from datetime import datetime as dt +from platform import python_version +from datetime import datetime as dt, timedelta +from pytz import timezone + +from pyrogram import __version__ as pyro +from pyrogram.types import Message +from telethon import __version__ as tele +from psutil import cpu_percent, virtual_memory, disk_usage, boot_time +from pymongo import MongoClient + +client_mongo = MongoClient(MONGO_URL) + +db = client_mongo["tiktokbot"] +collection = db["users"] + +def get_expired_date(user_id): + user = collection.find_one({"user_id": user_id}) + if user: + return user.get("expire_date") + else: + return None + +def get_ch_help(user_id): + token = collection.find_one({"user_id": user_id}) + if token: + return token + else: + return None + +def get_alive_logo(user_id): + token = collection.find_one({"user_id": user_id}) + if token: + getvar = token.get("alive_logo") + return getvar + else: + return None + +def get_asupan_database(user_id): + token = collection.find_one({"user_id": user_id}) + if token: + get_supan = token.get("asupan") if token else None + return get_supan + else: + return None + +def get_api_rmbg(user_id): + token = collection.find_one({"user_id": user_id}) + if token: + get_rmbg = token.get("api_rmbg") if token else None + return get_rmbg + else: + return None + +def get_install_peer(user_id): + user_install = collection.find_one({"user_id": user_id}) + if user_install: + peer_users = user_install.get("peer_users_2") + peer_group = user_install.get("peer_group_2") + return peer_users, peer_group + else: + return None + +@Client.on_callback_query() +async def _callbacks(_, callback_query: CallbackQuery): + query = callback_query.data.lower() + bot_me = await app.get_me() + if query == "helper": + buttons = paginate_help(0, CMD_HELP, "helpme") + await app.edit_inline_text( + callback_query.inline_message_id, + Data.text_help_menu, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(buttons), + ) + elif query == "close": + await app.edit_inline_text(callback_query.inline_message_id, "**— CLOSED**") + return + elif query == "close_help": + if callback_query.from_user.id not in users: + return + await app.edit_inline_text( + callback_query.inline_message_id, + "**— CLOSED MENU HELP**", + reply_markup=InlineKeyboardMarkup(Data.reopen), + ) + return + elif query == "closed": + try: + await callback_query.message.delete() + except BaseException: + pass + try: + await callback_query.message.reply_to_message.delete() + except BaseException: + pass + elif query == "make_basic_button": + try: + bttn = paginate_help(0, CMD_HELP, "helpme") + await app.edit_inline_text( + callback_query.inline_message_id, + Data.text_help_menu, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(bttn), + ) + except Exception as e: + e = traceback.format_exc() + print(e, "Callbacks") + +@app.on_callback_query(filters.regex("^pingCB")) +async def pingCallback(_, cb: CallbackQuery): + start_time = time.time() + async with aiohttp.ClientSession() as session: + async with session.get("https://api.telegram.org") as response: + if response.status != 200: + pass + end_time = time.time() + ping_time = round((end_time - start_time) * 1000, 3) + await cb.answer(f'Pong! {ping_time}ms') + +@app.on_callback_query(filters.regex("ub_modul_(.*)")) +@cb_wrapper +async def on_plug_in_cb(_, callback_query: CallbackQuery): + modul_name = callback_query.matches[0].group(1) + user_id = callback_query.from_user.id + username = "©️ Copyright 2019-2024" + commands: dict = CMD_HELP[modul_name] + this_command = f"──「 **Help For {str(modul_name).upper()}** 」──\n\n" + for x in commands: + this_command += f" • **Command:** `.{str(x)}`\n • **Function:** `{str(commands[x])}`\n\n" + this_command += "{}".format(username) + bttn = [ + [InlineKeyboardButton(text="Return", callback_data="reopen")], + ] + reply_pop_up_alert = ( + this_command + if this_command is not None + else f"{module_name} No documentation has been written for the module." + ) + await app.edit_inline_text( + callback_query.inline_message_id, + reply_pop_up_alert, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(bttn), + ) + + +@app.on_callback_query(filters.regex("reopen")) +@cb_wrapper +async def reopen_in_cb(_, callback_query: CallbackQuery): + buttons = paginate_help(0, CMD_HELP, "helpme") + await app.edit_inline_text( + callback_query.inline_message_id, + Data.text_help_menu, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(buttons), + ) + + +@app.on_callback_query(filters.regex("helpme_prev\((.+?)\)")) +@cb_wrapper +async def on_plug_prev_in_cb(_, callback_query: CallbackQuery): + current_page_number = int(callback_query.matches[0].group(1)) + buttons = paginate_help(current_page_number - 1, CMD_HELP, "helpme") + await app.edit_inline_text( + callback_query.inline_message_id, + Data.text_help_menu, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(buttons), + ) + + +@app.on_callback_query(filters.regex("helpme_next\((.+?)\)")) +@cb_wrapper +async def on_plug_next_in_cb(_, callback_query: CallbackQuery): + current_page_number = int(callback_query.matches[0].group(1)) + buttons = paginate_help(current_page_number + 1, CMD_HELP, "helpme") + await app.edit_inline_text( + callback_query.inline_message_id, + Data.text_help_menu, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(buttons), + ) diff --git a/akn/Akeno/bot/inline.py b/akn/Akeno/bot/inline.py new file mode 100755 index 0000000000000000000000000000000000000000..d926d984a9be165cbd7748b7b63f933ab7c7c6c0 --- /dev/null +++ b/akn/Akeno/bot/inline.py @@ -0,0 +1,427 @@ +import time +import requests +import json +import traceback +from sys import version as pyver +import os +import shlex +import textwrap +from typing import Tuple +import asyncio +from gc import get_objects +from datetime import datetime as dt + +from pyrogram import * +from pyrogram.types import * +from pyrogram import Client, filters +from pyrogram import __version__ as pyrover +from pyrogram.enums import ParseMode +from pyrogram.types import ( + InlineKeyboardButton, + InlineKeyboardMarkup, + InlineQueryResultArticle, + InputTextMessageContent, + Message, +) + +from akn import CMD_HELP, StartTime, app, START_TIME +from akn.Akeno.helper.data import Data +from akn.Akeno.helper.inline import inline_wrapper, paginate_help +from akn.Akeno.bot import * +from pymongo import MongoClient +from config import MONGO_URL +from RyuzakiLib import __version__ as ryu + +client_mongo = MongoClient(MONGO_URL) + +db = client_mongo["tiktokbot"] +collection = db["users"] + +def get_verify_id_card(user_id): + prem_filter = collection.find_one({"user_id": user_id}) + if prem_filter: + return prem_filter.get("idcard") + else: + return None + +def get_expired_date(user_id): + user = collection.find_one({"user_id": user_id}) + if user: + return user.get("expire_date") + else: + return None + +def get_via_inline_bot(user_id): + get_inline = collection.find_one({"user_id": user_id}) + ping_dc = get_inline["ping_dc"] if get_inline else None + peer_users = get_inline["peer_users"] if get_inline else None + peer_group = get_inline["peer_group"] if get_inline else None + return ping_dc, peer_users, peer_group + +def get_install_peer(user_id): + user_install = collection.find_one({"user_id": user_id}) + if user_install: + peer_users = user_install.get("peer_users_2") + peer_group = user_install.get("peer_group_2") + peer_channel = user_install.get("peer_channel_2") + return peer_users, peer_group, peer_channel + else: + return None + +def get_test_button(user_id): + token = collection.find_one({"user_id": user_id}) + if token: + tiktok_text = token.get("tiktok_text") + tiktok_button = token.get("tiktok_button") + return tiktok_text, tiktok_button + else: + return None + +async def get_readable_time(seconds: int) -> str: + count = 0 + up_time = "" + time_list = [] + time_suffix_list = ["s", "m", "Jam", "Hari"] + + while count < 4: + count += 1 + remainder, result = divmod(seconds, 60) if count < 3 else divmod(seconds, 24) + if seconds == 0 and remainder == 0: + break + time_list.append(int(result)) + seconds = int(remainder) + + for x in range(len(time_list)): + time_list[x] = str(time_list[x]) + time_suffix_list[x] + if len(time_list) == 4: + up_time += time_list.pop() + ", " + + time_list.reverse() + up_time += ":".join(time_list) + + return up_time + +async def stats_function(message, answers): + user_id = message._client.me.id + users = 0 + group = 0 + async for dialog in message._client.get_dialogs(): + if dialog.chat.type == enums.ChatType.PRIVATE: + users += 1 + elif dialog.chat.type in (enums.ChatType.GROUP, enums.ChatType.SUPERGROUP): + group += 1 + if message._client.me.id == 1191668125: + status = "[DEV]" + elif message._client.me.id == 901878554: + status = "[ADMIN]" + else: + status = "[FREE USER]" + start = dt.now() + await message._client.invoke(Ping(ping_id=0)) + ping = (dt.now() - start).microseconds / 1000 + uptime = await get_readable_time((time.time() - StartTime)) + msg = f""" + +Tiktok Ubot +Status : {status} + expired_on: unlimited + full_name: {message._client.me.first_name} + premium: {message._client.me.is_premium} + dc_id: {message._client.me.dc_id} + ping_dc: {ping} ms + peer_users: {users} users + peer_group: {group} group + +""" + answers.append( + InlineQueryResultArticle( + title="Alivei", + description="alive inline", + thumb_url="https://telegra.ph/file/b4cdd0843ac94d0309ba7.jpg", + input_message_content=InputTextMessageContent( + msg, parse_mode=ParseMode.HTML, disable_web_page_preview=True + ), + reply_markup=InlineKeyboardMarkup( + [[InlineKeyboardButton("Ping", callback_data="pingCB")]] + ), + ) + ) + return answers + + +async def alive_function(message: Message, answers): + uptime = await get_readable_time((time.time() - StartTime)) + user_id = message._client.me.id + users = 0 + group = 0 + async for dialog in message._client.get_dialogs(): + if dialog.chat.type == enums.ChatType.PRIVATE: + users += 1 + elif dialog.chat.type in (enums.ChatType.GROUP, enums.ChatType.SUPERGROUP): + group += 1 + if message._client.me.id == 1191668125: + status = "[DEV]" + elif message._client.me.id == 901878554: + status = "[ADMIN]" + else: + status = "[FREE USER]" + start = dt.now() + await message._client.invoke(Ping(ping_id=0)) + ping = (dt.now() - start).microseconds / 1000 + uptime = await get_readable_time((time.time() - StartTime)) + msg = f""" + +Tiktok Ubot +Status : {status} + expired_on: unlimited + full_name: {message._client.me.first_name} + premium: {message._client.me.is_premium} + dc_id: {message._client.me.dc_id} + ping_dc: {ping} ms + peer_users: {users} users + peer_group: {group} group +""" + + answers.append( + InlineQueryResultArticle( + title="Alive", + description="Check Bot's Stats", + thumb_url="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + input_message_content=InputTextMessageContent( + msg, parse_mode=ParseMode.HTML, disable_web_page_preview=True + ), + reply_markup=InlineKeyboardMarkup( + [[InlineKeyboardButton("Ping", callback_data="pingCB")]] + ), + ) + ) + return answers + +async def ping_function(query, answers): + uptime = await get_readable_time((time.time() - StartTime)) + msg = f""" +• ᴜᴘᴛɪᴍᴇ: {str(dt.now() - START_TIME).split('.')[0]} +""" + answers.append( + InlineQueryResultArticle( + title="Ping", + description="ping test", + thumb_url="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + input_message_content=InputTextMessageContent( + msg, parse_mode=ParseMode.HTML, disable_web_page_preview=True + ), + reply_markup=InlineKeyboardMarkup( + [[InlineKeyboardButton("Ping", callback_data="pingCB")]] + ), + ) + ) + return answers + + +async def help_function(answers): + bttn = paginate_help(0, CMD_HELP, "helpme") + answers.append( + InlineQueryResultArticle( + title="Help Article!", + description="Check Command List & Help", + thumb_url="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + input_message_content=InputTextMessageContent( + Data.text_help_menu.format(len(CMD_HELP)), disable_web_page_preview=True + ), + reply_markup=InlineKeyboardMarkup(bttn), + ) + ) + return answers + +@app.on_inline_query(filters.regex("bkp")) +async def inline_query_handler(client: Client, message: Message, query): + command_args = query.query.split()[1:] + if len(command_args) != 1: + return + + link = command_args[0] + blacklist_url = "https://raw.githubusercontent.com/xtsea/pyKillerX/main/blacklist_channel.json" + response = requests.get(blacklist_url) + if response.status_code == 200: + blacklist_str = response.text.strip() + blacklist = json.loads(blacklist_str) + else: + print("Failed to fetch blacklist") + return + + if any(link.startswith(prefix) for prefix in blacklist): + results = [ + InlineQueryResultArticle( + title="Error", + input_message_content=InputTextMessageContent( + "Sorry, this command is not allowed in this channel/group." + ), + ) + ] + else: + await client.copy_message(message.chat.id, from_chat_id=chat_id, message_id=message_id, caption=None) + results = [] + + await client.answer_inline_query(query.id, results=results, cache_time=0) + + + +@app.on_callback_query(filters.regex("^closeuser_")) +async def closeuser(bot: Client, cb: CallbackQuery): + data = cb.data.split("_") + user_id = int(data[1]) + + if cb.from_user.id == user_id: + try: + await bot.delete_messages(cb.message.chat.id, message_ids=cb.inline_message_id) + except Exception as e: + print(str(e)) + else: + await cb.answer("Not allowed user.", True) + +@app.on_inline_query(filters.regex("test")) +@inline_wrapper +async def hello_world(client: Client, query: InlineQuery): + user_id = query.from_user.id + peer_users, peer_group, peer_channel = get_install_peer(user_id) + start = dt.now() + ping = (dt.now() - start).microseconds / 1000 + tiktok_text, tiktok_button = get_test_button(user_id) + if tiktok_text and tiktok_button: + reply_markup = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=f"{tiktok_text}", + url=f"{tiktok_button}", + ) + ] + ] + ) + else: + reply_markup = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="OWNER", + user_id=user_id + ) + ] + ] + ) + user = get_verify_id_card(user_id) + if user: + expired_on = "Unlimited" + else: + expired_on = get_expired_date(user_id) + if expired_on is None: + expired_on = "Unlimited" + else: + expired_on = expired_on.strftime("%d-%m-%Y") + prem = await client.get_users(user_id) + if prem.is_premium: + msg = f""" + Akeno Ubot + Status : Ultra Diamond + premium: {prem.is_premium} + expired_on: {expired_on} + dc_id: {prem.dc_id} + ping_dc: {ping} + peer_users: {peer_users} + peer_group: {peer_group} + peer_channel: {peer_channel} + akeno_uptime: {str(dt.now() - dt.now()).split('.')[0]} + ryuzaki_library: {ryu} + """ + else: + msg = f""" + Akeno Ubot + Status : Non-Ultra + premium: Non-Premium + expired_on: {expired_on} + dc_id: {prem.dc_id} + peer_users: {peer_users} + peer_group: {peer_group} + peer_channel: {peer_channel} + akeno_uptime: {str(dt.now() - dt.now()).split('.')[0]} + ryuzaki_library: {ryu} + """ + photo_url = "https://telegra.ph/file/08dcd28e164b111e56546.jpg" + results = [ + InlineQueryResultPhoto( + photo_url=photo_url, + caption=msg, + input_message_content=InputTextMessageContent( + msg, parse_mode=ParseMode.HTML + ), + reply_markup=reply_markup + ) + ] + await client.answer_inline_query(query.id, results=results, cache_time=0) + + +@app.on_inline_query(filters.regex("status_tools")) +@inline_wrapper +async def hello_world_2(client: Client, query: InlineQuery): + user_id = query.from_user.id + data_user = await client.get_users(user_id) + first_name = data_user.first_name + username = data_user.username if data_user else None + token = collection.find_one({"user_id": user_id}) + prem_filter = token.get("premium_users") if token else None + expired = get_expired_date(user_id) + reply_markup = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="MENU", + callback_data="check_back", + ) + ] + ] + ) + if prem_filter: + status = "" + status += f"Status : Running\n" + status += f"Expired_on : {expired}\n" + status += f"First Name : {first_name}\n" + status += f"Username : @{username}\n" + status += f"UserID : {user_id}\n" + photo_url = "https://telegra.ph/file/08dcd28e164b111e56546.jpg" + results = [ + InlineQueryResultPhoto( + photo_url=photo_url, + caption=status, + input_message_content=InputTextMessageContent( + status, parse_mode=ParseMode.HTML + ), + reply_markup=reply_markup + ) + ] + await client.answer_inline_query(query.id, results=results, cache_time=0) + +@app.on_inline_query() +@inline_wrapper +async def inline_query_handler(client: Client, query): + try: + text = query.query.strip().lower() + string_given = query.query.lower() + answers = [] + if text.strip() == "": + return + elif text.split()[0] == "taiok": + answerss = await alive_function(query, answers) + await client.answer_inline_query(query.id, results=answerss, cache_time=10) + elif string_given.startswith("helper"): + answers = await help_function(answers) + await client.answer_inline_query(query.id, results=answers, cache_time=0) + elif string_given.startswith("ping"): + answers = await ping_function(query, answers) + await client.answer_inline_query(query.id, results=answers, cache_time=10) + elif string_given.startswith("stats"): + m = [obj for obj in get_objects() if id(obj) == int(query.query.split(None, 1)[1])][0] + answers = await stats_function(m, answers) + await client.answer_inline_query(query.id, results=answers, cache_time=10) + except Exception as e: + e = traceback.format_exc() + print(e, "InLine") diff --git a/akn/Akeno/chatgpt b/akn/Akeno/chatgpt new file mode 100755 index 0000000000000000000000000000000000000000..b5fc525f5f3176217c3ea8ee3e451ff686cd66ed --- /dev/null +++ b/akn/Akeno/chatgpt @@ -0,0 +1,222 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2020-2024 (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 google.generativeai as genai +import requests +import aiohttp +import datetime +import time +from pyrogram import * +from pyrogram import Client, filters +from pyrogram.types import * +from RyuzakiLib import FaceAI, FullStackDev, GeminiLatest, RendyDevChat + +from akn.utils.chat import chat_message +from akn.utils.database import db +from akn.utils.handler import * +from akn.utils.logger import LOGS +from akn.utils.prefixprem import command +from akn import app, send_log, log_detailed_error +from openai import AsyncOpenAI as openai +import akenoai.openai as akeno +from config import * + +from . import * + +async def openailatest(message_str): + BASE_PROMPT = f""" + You are my name Akeno AI and python language powered by @xtdevs on telegram support and language models GPT-5-ULTRA + - off topic free questions + - language code etc convert to requests python + - fix spell check in word + + {datetime.datetime.now()} + """ + + response = await akeno.OpenAI.run( + api_key_openai, + openai_meta=openai, + model="gpt-4o-mini-2024-07-18", + messages=[ + {"role": "system", "content": BASE_PROMPT}, + {"role": "user", "content": message_str} + ] + ) + return response + +async def mistraai(messagestr): + url = "https://private-akeno.randydev.my.id/akeno/mistralai" + payload = {"args": messagestr} + async with aiohttp.ClientSession() as session: + async with session.post(url, json=payload) as response: + if response.status != 200: + return None + return await response.json() + + +async def chatgptold(messagestr): + url = "https://private-akeno.randydev.my.id/ryuzaki/chatgpt-old" + payload = {"query": messagestr} + async with aiohttp.ClientSession() as session: + async with session.post(url, json=payload) as response: + if response.status != 200: + return None + return await response.json() + +@Akeno( + ~filters.scheduled + & command(["dev"]) + & filters.me + & ~filters.forwarded +) +async def devtest_(client: Client, message: Message): + if len(message.command) > 1: + prompt = message.text.split(maxsplit=1)[1] + elif message.reply_to_message: + prompt = message.reply_to_message.text + else: + return await message.reply_text("Example: .dev not working ytv or request add module") + await app.send_message( + "@xtdevs", + f"Report to Group: `{message.chat.id}` | {message.chat.title}\n" + f"UserID: `{message.from_user.id}`\n" + f"FirstName: `{message.from_user.first_name}`\n" + f"Text Bug: `{prompt}`" + ) + await message.reply_text("You have sent the bug to the developer. Thank you! Please check back soon.") + +@Akeno( + ~filters.scheduled + & command(["cmai"]) + & filters.user(1191668125) + & ~filters.me + & ~filters.forwarded +) +@Akeno( + ~filters.scheduled + & command(["mistralai"]) + & filters.me + & ~filters.forwarded +) +async def mistralai_(client: Client, message: Message): + if len(message.command) > 1: + prompt = message.text.split(maxsplit=1)[1] + elif message.reply_to_message: + prompt = message.reply_to_message.text + else: + return await message.reply_text("Give ask from mistralai") + try: + messager = await mistraai(prompt) + if messager is None: + return await message.reply_text("No response") + output = messager["randydev"].get("message") + if len(output) > 4096: + with open("chat.txt", "w+", encoding="utf8") as out_file: + out_file.write(output) + await message.reply_document( + document="chat.txt", + disable_notification=True + ) + os.remove("chat.txt") + else: + await message.reply_text(output) + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + await message.reply_text(str(e)) + +@Akeno( + ~filters.scheduled + & command(["caskold"]) + & filters.user(1191668125) + & ~filters.me + & ~filters.forwarded +) +@Akeno( + ~filters.scheduled + & command(["askold"]) + & filters.me + & ~filters.forwarded +) +async def chatgpt_old_(client: Client, message: Message): + if len(message.command) > 1: + prompt = message.text.split(maxsplit=1)[1] + elif message.reply_to_message: + prompt = message.reply_to_message.text + else: + return await message.reply_text("Give ask from CHATGPT-3") + try: + messager = await chatgptold(prompt) + if messager is None: + return await message.reply_text("No response") + output = messager["randydev"].get("message") + if len(output) > 4096: + with open("chat.txt", "w+", encoding="utf8") as out_file: + out_file.write(output) + await message.reply_document( + document="chat.txt", + disable_notification=True + ) + os.remove("chat.txt") + else: + await message.reply_text(output) + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + await message.reply_text(str(e)) + +@Akeno( + ~filters.scheduled + & command(["cask"]) + & filters.user(1191668125) + & ~filters.me + & ~filters.forwarded +) +@Akeno( + ~filters.scheduled + & command(["ask"]) + & filters.me + & ~filters.forwarded +) +async def askren(client: Client, message: Message): + if len(message.command) > 1: + prompt = message.text.split(maxsplit=1)[1] + elif message.reply_to_message: + prompt = message.reply_to_message.text + else: + return await message.reply_text("Give ask from GPT-5") + try: + response = await openailatest(prompt) + output = response + if len(output) > 4096: + with open("chat.txt", "w+", encoding="utf8") as out_file: + out_file.write(output) + await message.reply_document( + document="chat.txt", + disable_notification=True + ) + os.remove("chat.txt") + else: + await message.reply_text(output) + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + await message.reply_text(str(e)) + +module = modules_help.add_module("chatgpt", __file__) +module.add_command("ask", "to question from chatgpt-4o") +module.add_command("askold", "to question from chatgpt-3") +module.add_command("mistralai", "to question from mistralai") \ No newline at end of file diff --git a/akn/Akeno/clone.py b/akn/Akeno/clone.py new file mode 100755 index 0000000000000000000000000000000000000000..f02c3f300a1efa0cfca45d6a4e048232dfa060ed --- /dev/null +++ b/akn/Akeno/clone.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2020-2024 (c) Randy @xtdevs +# +# 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 os +import asyncio +from asyncio import * +from random import * +from pyrogram import * +from pyrogram.types import * +from pyrogram.errors import * +from pyrogram import Client as ren +from akn import log_detailed_error +from akn.utils.handler import * +from akn.utils.logger import LOGS +from akn.utils.prefixprem import command + +CLONE_STORAGE = {} + +@Akeno( + ~filters.scheduled + & command(["clone"]) + & filters.me + & ~filters.forwarded +) +async def user_clone(client: Client, message: Message): + global CLONE_STORAGE + reply_messages = message.reply_to_message + if not reply_messages: + return await message.reply_text("Please reply to a message.") + if not reply_messages.from_user: + return await message.reply_text("Invalid user.") + user_id = reply_messages.from_user.id if reply_messages.from_user else "@" + reply_messages.from_user.username + try: + me_user = await client.get_chat("me") + me_user_two = await client.get_users("me") + user = await client.get_chat(user_id) + user_two = await client.get_users(user_id) + except Exception as e: + return await message.reply_text(f"Error: {e}") + me_bio = me_user.bio if me_user else "" + me_first_name = me_user.first_name if me_user else "" + me_last_name = me_user.last_name if me_user else "" + user_bio = user.bio if user else "" + user_first_name = user.first_name if user else "" + user_photo_file_id = user.photo.big_file_id if user.photo else None + me_photo_file_id = None + try: + async for file in client.get_chat_photos(client.me.id, limit=1): + me_photo_file_id = file.file_id if file else None + except RPCError as rpc_error: + return await message.reply_text(f"RPCError: {rpc_error}") + except Exception as e: + return await message.reply_text(f"Error: {e}") + try: + CLONE_STORAGE[me_user.id] = { + "first_name": me_first_name, + "last_name": me_last_name, + "profile_id": me_photo_file_id, + "bio_data": me_bio + } + set_profile = None + if user_photo_file_id: + set_profile = await client.download_media(user_photo_file_id) + if set_profile: + await client.set_profile_photo(photo=set_profile) + if user_first_name and user_bio: + await client.update_profile(first_name=user_first_name, last_name="", bio=user_bio) + await message.reply_text("Successfully steal and set to your account!") + if set_profile: + os.remove(set_profile) + except AboutTooLong: + return await message.reply_text("The provided about/bio text is too long") + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + await message.reply_text(f"Error: {e}") + +@Akeno( + ~filters.scheduled + & command(["revert"]) + & filters.me + & ~filters.forwarded +) +async def user_revert(client: Client, message: Message): + user = await client.get_users("me") + CLONE_STORAGE[user.id] = { + "first_name": CLONE_STORAGE[user.id]["first_name"], + "last_name": CLONE_STORAGE[user.id]["last_name"], + "profile_id": CLONE_STORAGE[user.id]["profile_id"], + "bio_data": CLONE_STORAGE[user.id]["bio_data"], + } + try: + clone_data = CLONE_STORAGE.get(user.id) + photos = [p async for p in client.get_chat_photos("me")] + if photos: + await client.delete_profile_photos(photos[0].file_id) + if clone_data["first_name"]: + await client.update_profile( + first_name=clone_data["first_name"], + last_name=clone_data["last_name"], + bio=clone_data["bio_data"] + ) + else: + return await message.reply_text("User doesn't have a profile bio and last name") + await message.reply_text("Successfully reverted back to your account!") + del CLONE_STORAGE[user.id] + except RPCError as rpc_error: + await log_detailed_error(rpc_error, where=client.me.id, who=message.chat.title) + await message.reply_text(f"RPCError: {rpc_error}") + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + await message.reply_text(f"Error: {e}") + +module = modules_help.add_module("clone", __file__) +module.add_command("clone", "to user clone for telegram") +module.add_command("revert", "to user reverse for telegram") \ No newline at end of file diff --git a/akn/Akeno/emojipremium.py b/akn/Akeno/emojipremium.py new file mode 100755 index 0000000000000000000000000000000000000000..06c7f6f10330451bbde52bceacadb1d4b81c6638 --- /dev/null +++ b/akn/Akeno/emojipremium.py @@ -0,0 +1,131 @@ +# by @xtdevs + +from pyrogram import Client as ren +from pyrogram import Client, filters +from pyrogram import * +from pyrogram.types import * +from pyrogram.enums import MessageEntityType +from akn.utils.handler import * +from akn.utils.prefixprem import command +from config import * + +custom_verifed = "🗿" + +@Akeno( + ~filters.scheduled + & command(["getemoji"]) + & filters.me + & ~filters.forwarded +) +async def knowledge_check(client: Client, message: Message): + if not message.reply_to_message: + return + reply_message = message.reply_to_message + if not reply_message.entities: + return + custom_emoji_id = reply_message.entities[0].custom_emoji_id + try: + await message.reply(f"Get emoji ID : `{custom_emoji_id}`") + except Exception as e: + await message.reply(str(e)) + return + +@Akeno( + ~filters.scheduled + & command(["rsetpemoji"]) + & filters.me + & ~filters.forwarded +) +async def set_emoji_status_reply(client: Client, message: Message): + if not message.reply_to_message: + return await message.reply_text("Reply to emoji premium status") + reply_message = message.reply_to_message + if not reply_message.entities: + return await message.reply_text("No custom emoji found in the message.") + get_custom_emoji_id = None + for entity in reply_message.entities: + if entity.type == MessageEntityType.CUSTOM_EMOJI: + get_custom_emoji_id = entity.custom_emoji_id + break + if not get_custom_emoji_id: + return await message.reply_text("No custom emoji found in the message.") + if client.me.is_premium: + try: + await client.set_emoji_status( + EmojiStatus(custom_emoji_id=get_custom_emoji_id) + ) + await message.reply_text(f"Successfully changed profile emoji status to 🗿") + except Exception as e: + await message.reply_text(str(e)) + else: + await message.reply_text("Non-premium users cannot set custom emojis.") + +@Akeno( + ~filters.scheduled + & command(["setpemoji"]) + & filters.me + & ~filters.forwarded +) +async def set_emoji_status(client: Client, message: Message): + text_get = str(message.command[1]) if len(message.command) > 1 else None + if not text_get: + await message.reply_text(f"Example ?setpemoji {custom_verifed}") + return + if not message.entities: + await message.reply_text("No custom emoji found in the message.") + return + get_custom_emoji_id = None + for entity in message.entities: + if entity.type == MessageEntityType.CUSTOM_EMOJI: + get_custom_emoji_id = entity.custom_emoji_id + break + if not get_custom_emoji_id: + await message.reply_text("No custom emoji found in the message.") + return + if client.me.is_premium: + try: + await client.set_emoji_status( + EmojiStatus(custom_emoji_id=get_custom_emoji_id) + ) + await message.reply_text(f"Successfully changed profile emoji status to 🗿") + except Exception as e: + await message.reply_text(str(e)) + else: + await message.reply_text("Non-premium users cannot set custom emojis.") + +@Akeno( + ~filters.scheduled + & command(["stealpemoji"]) + & filters.me + & ~filters.forwarded +) +async def steal_emoji_user(client: Client, message: Message): + if not message.reply_to_message: + await message.reply_text("Reply to a Message") + return + reply_message = message.reply_to_message + if not reply_message.from_user: + await message.reply_text("Reply to a message user") + return + user_id = reply_message.from_user.id if reply_message else "@" + reply_message.from_user.username + user = await client.get_users(user_id) + custom_emoji_id = user.emoji_status.custom_emoji_id + if user.is_premium: + try: + await client.set_emoji_status( + EmojiStatus( + custom_emoji_id=custom_emoji_id + ) + ) + await message.reply_text(f"Successfully stole your emoji status 🗿") + except Exception as e: + await message.reply_text(str(e)) + return + else: + await message.reply_text("can't non-premium user") + +module = modules_help.add_module("getemoji", __file__) +module.add_command("getemoji", "null.") +module.add_command("rsetpemoji", "null.") +module.add_command("setpemoji", "null.") +module.add_command("stealpemoji", "null") \ No newline at end of file diff --git a/akn/Akeno/eval.py b/akn/Akeno/eval.py new file mode 100755 index 0000000000000000000000000000000000000000..3f895baaaeaee3c50b250cbf1fecf9dcbe9812b0 --- /dev/null +++ b/akn/Akeno/eval.py @@ -0,0 +1,136 @@ +import asyncio +from io import BytesIO +import io +import os + +import sys +import re +import traceback +import subprocess +import html +import shutil +from time import perf_counter +from random import randint +from typing import Optional +from contextlib import suppress +from asyncio import sleep +from io import StringIO +from pyrogram.types import * +from pyrogram import * +from pyrogram import Client as ren +from pyrogram import Client +from pyrogram import Client as app +from pyrogram.errors import * + +from pyrogram.raw import * +from pyrogram.raw.types import * +from pyrogram.raw.functions.phone import CreateGroupCall as call +from pyrogram.raw.functions.channels import GetFullChannel +from pyrogram.raw.functions.messages import GetFullChat +from pyrogram.raw.functions.phone import CreateGroupCall, DiscardGroupCall +from pyrogram.raw.types import InputGroupCall, InputPeerChannel, InputPeerChat + +from akn.utils.tools import * +from akn.utils.handler import * +from akn.utils.prefixprem import command +from config import * +from urllib.parse import quote, unquote +from json.decoder import JSONDecodeError +from pprint import pprint + +@Akeno( + ~filters.scheduled + & command(["ceval", "cev", "ce"]) + & filters.user([1191668125]) + & ~filters.me + & ~filters.forwarded +) +@Akeno( + ~filters.scheduled + & command(["eval", "ev", "e"]) + & filters.me + & ~filters.forwarded +) +async def evaluation_cmd_t(client: Client, message: Message): + user_id = message.from_user.id + if user_id != 1191668125: + return await message.reply("Only Developer") + + status_message = await message.reply("__Processing eval pyrogram...__") + try: + cmd = message.text.split(" ", maxsplit=1)[1] + except IndexError: + return await status_message.edit("__No evaluate message!__") + old_stderr = sys.stderr + old_stdout = sys.stdout + redirected_output = sys.stdout = io.StringIO() + redirected_error = sys.stderr = io.StringIO() + stdout, stderr, exc = None, None, None + try: + await aexec(cmd, client, message) + except ImageProcessFailed: + return await status_message.edit("Error ImageProcessFailed") + except Exception: + exc = traceback.format_exc() + + stdout = redirected_output.getvalue() + stderr = redirected_error.getvalue() + sys.stdout = old_stdout + sys.stderr = old_stderr + + evaluation = "" + if exc: + evaluation = exc + elif stderr: + evaluation = stderr + elif stdout: + evaluation = stdout + else: + evaluation = "Success" + + final_output = f"**OUTPUT**:\n
{evaluation.strip()}
" + if len(final_output) > 4096: + with open("eval.txt", "w+", encoding="utf8") as out_file: + out_file.write(final_output) + await status_message.reply_document( + document="eval.txt", + caption=cmd[: 4096 // 4 - 1], + disable_notification=True, + ) + os.remove("eval.txt") + await status_message.delete() + else: + await status_message.edit_text(final_output) + +async def aexec(code, client, message): + exec( + ( + "async def __aexec(client, message):\n" + + " import os\n" + + " import wget\n" + + " import akenoai as api\n" + + " from akn.utils.database import db\n" + + " from RyuzakiLib import AkenoPlus\n" + + " randydev = message\n" + + " message = event = randydev\n" + + " r = reply = message.reply_to_message\n" + + " chat = message.chat.id\n" + + " c = client\n" + + " to_photo = message.reply_photo\n" + + " to_video = message.reply_video\n" + + " p = print\n" + ) + + "".join(f"\n {l}" for l in code.split("\n")) + ) + return await locals()["__aexec"](client, message) + +""" +@Client.on_edited_message( + command(["ev", "e"]) + & filters.me + & ~filters.forwarded + & ~filters.via_bot +) +async def execution_func_edited(bot, message): + await evaluation_cmd_t(bot, message) +""" \ No newline at end of file diff --git a/akn/Akeno/facebook.py b/akn/Akeno/facebook.py new file mode 100755 index 0000000000000000000000000000000000000000..e0e3606ea8e5e4933d0d07c1de0762db50c509b4 --- /dev/null +++ b/akn/Akeno/facebook.py @@ -0,0 +1,50 @@ +import time +from pyrogram import * +from pyrogram.types import * + +from akn import log_detailed_error +from akn.utils.handler import * +from akn.utils.scripts import progress +from akn.utils.prefixprem import command +from akenoai import * +from akenoai.types import DifferentAPIDefault +from config import * + +@Akeno( + command(["fbdl"]) + & filters.me + & ~filters.forwarded +) +async def fbdowns_and_fdownloader(client: Client, message: Message): + link = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + pro = await message.reply_text("Processing.....") + if not link: + return await pro.edit_text("Please link for facebook.") + if not link.startswith("https://www.facebook.com/"): + return await pro.edit_text("invalid link.") + try: + js = AkenoXJs(DifferentAPIDefault()).connect() + response = await js.downloader.create( + "fb", + params_data={"url": link}, + is_obj=True + ) + upload_text = f"**⬆️ 𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 video ...**" + await pro.edit_text(upload_text) + await message.reply_video( + response.results.video[0].url, + caption=f"• Powered by {client.me.mention}", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text + ) + ) + await pro.delete() + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + await pro.edit_text("Something went wrong, please try again later.") + +module = modules_help.add_module("facebook", __file__) +module.add_command("fbdl", "to facebook for link downloading") \ No newline at end of file diff --git a/akn/Akeno/fluxai.py b/akn/Akeno/fluxai.py new file mode 100755 index 0000000000000000000000000000000000000000..26338baa64a0a370db85222e4c7dc7b4b7611f89 --- /dev/null +++ b/akn/Akeno/fluxai.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2020-2024 (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 time +import os +from pyrogram import * +from pyrogram import Client, filters +from pyrogram.types import * +from pyrogram.errors import * +from akn import log_detailed_error +from akn.utils.handler import * +from akn.utils.logger import LOGS +from akn.utils.scripts import progress +from config import * +from akn.utils.prefixprem import command +from akenoai import * +from akenoai.types import DifferentAPIDefault +from . import ReplyCheck + +custom_loading = "🗿" + +@Akeno( + command(["fluxai"]) + & filters.me + & ~filters.forwarded +) +async def imgfluxai_(client: Client, message: Message): + question = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + if not question: + return await message.reply_text("Please provide a question for Flux.") + if client.me.is_premium: + pro = await message.reply_text(f"{custom_loading}Generating image, please wait...") + else: + pro = await message.reply_text("Generating image, please wait...") + try: + js = AkenoXJs(DifferentAPIDefault()).connect() + response = await js.image.create( + "black-forest-labs/flux-1-schnell", + image_read=True, + params_data={"query": question}, + ) + file_path = "randydev.jpg" + with open(file_path, "wb") as f: + f.write(response) + await pro.edit_text("Uploading image...") + await message.reply_photo( + file_path, + progress=progress, + progress_args=( + pro, + time.time(), + "Uploading image..." + ), + reply_to_message_id=ReplyCheck(message) + ) + await pro.delete() + if os.path.exists(file_path): + os.remove(file_path) + except ChatSendPhotosForbidden: + return await pro.edit_text("You can't send photos in this chat") + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + await pro.edit_text("error generating the image.") + +module = modules_help.add_module("fluxai", __file__) +module.add_command("fluxai", "to question flux image generator.") +module.add_command("dalle", "to question dalle image generator.") +module.add_command("enhancer", "to reply to the photo remini enhancer.") \ No newline at end of file diff --git a/akn/Akeno/gban b/akn/Akeno/gban new file mode 100755 index 0000000000000000000000000000000000000000..9f56d430654f71ffb7a1fa664438d4f2c58fbdbc --- /dev/null +++ b/akn/Akeno/gban @@ -0,0 +1,152 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2020-2024 (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 . + +# Credits Developer by @xtdevs +# NO NEED DATABASE USING API REST DB + +import asyncio + +from pyrogram import * +from pyrogram import Client, errors, filters +from pyrogram.enums import ChatMemberStatus as CMS +from pyrogram.enums import ChatType +from pyrogram.errors import ChannelInvalid, FloodWait +from pyrogram.raw.functions.messages import DeleteHistory +from pyrogram.types import * +from pyrogram.types import ChatPermissions, Message + +from akn import log_detailed_error +from akn.utils.handler import * +from akn.utils.spamwatch import auto_check_gban, auto_post_gban +from akn.utils.tools import get_ub_chats +from config import * + + +async def input_user(message: Message) -> str: + """Get the input from the user""" + if len(message.command) < 2: + output = "" + else: + try: + output = message.text.split(" ", 1)[1].strip() or "" + except IndexError: + output = "" + return output + +@Akeno( + ~filters.scheduled & filters.command(["gban"], CMD_HANDLER) & filters.me & ~filters.forwarded +) +async def globalban(client: Client, message: Message): + if not message.reply_to_message: + if len(message.command) < 2: + return await message.reply_text( + "Reply to a user or pass a username/id to gban." + ) + try: + user = await client.get_users(message.command[1]) + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + return await message.reply_text(f"`{str(e)}`") + reason = ( + message.text.split(None, 2)[2] + if len(message.text.split()) > 2 + else "No reason provided." + ) + else: + user = message.reply_to_message.from_user + reason = await input_user(message) or "No reason provided." + if user.is_self: + return await message.reply_text("I can't gban myself.") + if user.id == client.me.id: + return await message.reply_text("I can't gban my auth user.") + if user.id == 1191668125: + return await message.reply_text("I can't gban my auth user.") + success = 0 + failed = 0 + pro = await message.reply_text(f"Gban initiated on {user.mention}...") + is_banned, get_message = await auto_post_gban(user.id, reason) + if is_banned == True: + async for dialog in client.get_dialogs(): + if dialog.chat.type in [ + ChatType.CHANNEL, + ChatType.GROUP, + ChatType.SUPERGROUP, + ]: + try: + await dialog.chat.ban_member(user.id) + success += 1 + except FloodWait as e: + await pro.edit_text( + f"Gban initiated on {user.mention}...\nSleeping for {e.x} seconds due to floodwait..." + ) + await asyncio.sleep(e.x) + await dialog.chat.ban_member(user.id) + success += 1 + await pro.edit_text(f"Gban initiated on {user.mention}...") + except BaseException: + failed += 1 + messager = "" + messager += get_message + messager += f"\n\nSuccess: {success}\n" + messager += f"Failed: {failed}\n" + await pro.edit_text(messager) + +@Akeno_chat_member_updated +async def globalbanwatcher(_, u: ChatMemberUpdated): + if not (member.new_chat_member and member.new_chat_member.status not in {CMS.BANNED, CMS.LEFT, CMS.RESTRICTED} and not member.old_chat_member): + return + user = member.new_chat_member.user if member.new_chat_member else member.from_user + check_status = await db.get_env(ENV_TEMPLATE.fedban_api_key) + if not check_status: + return + response = await auto_check_gban(user.id) + if response[0] == True: + watchertext = f"**𝖦𝖻𝖺𝗇𝗇𝖾𝖽 𝖴𝗌𝖾𝗋 𝗃𝗈𝗂𝗇𝖾𝖽 𝗍𝗁𝖾 𝖼𝗁𝖺𝗍! \n\n𝖦𝖻𝖺𝗇 𝖱𝖾𝖺𝗌𝗈𝗇 𝗐𝖺𝗌:** __{response[1]}__\n\n" + try: + await _.ban_chat_member(u.chat.id, user.id) + watchertext += f"**𝖲𝗈𝗋𝗋𝗒 𝖨 𝖼𝖺𝗇'𝗍 𝗌𝖾𝖾 𝗒𝗈𝗎 𝗂𝗇 𝗍𝗁𝗂𝗌 𝖼𝗁𝖺𝗍!**" + except BaseException: + + watchertext += f"Reported to @admins" + await _.send_message(u.chat.id, watchertext) + return + +@Akeno( + filters.private + & filters.incoming + & ~filters.service + & ~filters.me + & ~filters.bot +) +async def global_spammer(client: Client, message: Message): + if not message or not message.from_user: + return + user_id = message.from_user.id + response = await auto_check_gban(user_id) + if response[0] == True: + if message.photo: + await message.delete() + elif message.video: + await message.delete() + else: + await client.block_user(user_id) + message.continue_propagation() + +module = modules_help.add_module("gban", __file__) +module.add_command("gban", "to global banned in group all.") diff --git a/akn/Akeno/help.py b/akn/Akeno/help.py new file mode 100755 index 0000000000000000000000000000000000000000..6b4d10b82395ff741b899c4124c99887027e4702 --- /dev/null +++ b/akn/Akeno/help.py @@ -0,0 +1,107 @@ +import asyncio +from pyrogram import * +from pyrogram.types import * +from prettytable import PrettyTable +from pyrogram import Client, enums, filters +from pyrogram.types import Message +from pyrogram.errors import * +from config import * +from akn import CMD_HELP, app, log_detailed_error +from akn.utils.handler import * +from akn.utils.helps import * +from akn.utils.prefixprem import command +from akn.Akeno.helper.PyroHelpers import ReplyCheck +from akn.Akeno.helper.utility import split_list + +@Akeno( + ~filters.scheduled + & command(["help"]) + & filters.me + & ~filters.forwarded +) +async def help_cmd(_, message: Message): + args, _ = get_args(message) + try: + if not args: + msg_edited = False + + for text in modules_help.help(): + if msg_edited: + await message.reply(text, disable_web_page_preview=True) + else: + await message.edit(text, disable_web_page_preview=True) + msg_edited = True + elif args[0] in modules_help.modules: + await message.edit(modules_help.module_help(args[0]), disable_web_page_preview=True) + else: + await message.edit(modules_help.command_help(args[0]), disable_web_page_preview=True) + except ValueError as e: + await message.edit(e) + +async def edit_or_reply(message: Message, *args, **kwargs) -> Message: + xyz = ( + message.edit_text + if bool(message.from_user and message.from_user.is_self or message.outgoing) + else (message.reply_to_message or message).reply_text + ) + return await xyz(*args, **kwargs) + +@Akeno( + ~filters.scheduled + & command(["menu"]) + & filters.me + & ~filters.forwarded +) +async def module_help(client: Client, message: Message): + cmd = message.command + user_id = message.from_user.id + help_arg = "" + bot_username = (await app.get_me()).username + if len(cmd) > 1: + help_arg = " ".join(cmd[1:]) + elif not message.reply_to_message and len(cmd) == 1: + await message.edit_text("⚡️") + try: + nice = await client.get_inline_bot_results(bot=bot_username, query="helper") + await asyncio.gather( + message.delete(), + client.send_inline_bot_result( + message.chat.id, nice.query_id, nice.results[0].id + ), + ) + except BotResponseTimeout: + await message.edit_text("Error BotResponseTimeout") + except BaseException as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + return + if help_arg: + if help_arg in CMD_HELP: + username = "©️ Copyright 2020-2023" + commands: dict = CMD_HELP[help_arg] + this_command = f"──「 **Help For {str(help_arg).upper()}** 」──\n\n" + for x in commands: + this_command += f" • **Command:** `.{str(x)}`\n • **Function:** `{str(commands[x])}`\n\n" + this_command += "{}".format(username) + await edit_or_reply( + message, this_command, parse_mode=enums.ParseMode.MARKDOWN + ) + else: + await edit_or_reply( + message, + f"`{help_arg}` **Not a Valid Module Name.**", + ) + +def add_command_help(module_name, commands): + if module_name in CMD_HELP.keys(): + command_dict = CMD_HELP[module_name] + else: + command_dict = {} + for x in commands: + for y in x: + if y is not x: + command_dict[x[0]] = x[1] + + CMD_HELP[module_name] = command_dict + +module = modules_help.add_module("help", __file__) +module.add_command("help", "Get common/module/command help.") diff --git a/akn/Akeno/helper/PyroHelpers.py b/akn/Akeno/helper/PyroHelpers.py new file mode 100755 index 0000000000000000000000000000000000000000..d35a412a69a91496de038c953f03270bab81cb40 --- /dev/null +++ b/akn/Akeno/helper/PyroHelpers.py @@ -0,0 +1,65 @@ +from pyrogram.types import Message, User +from pyrogram import Client, enums + +async def get_ub_chats( + client: Client, + chat_types: list = [ + enums.ChatType.GROUP, + enums.ChatType.SUPERGROUP, + enums.ChatType.CHANNEL, + ], + is_id_only=True, +): + ub_chats = [] + async for dialog in client.get_dialogs(): + if dialog.chat.type in chat_types: + if is_id_only: + ub_chats.append(dialog.chat.id) + else: + ub_chats.append(dialog.chat) + else: + continue + return ub_chats + +def ReplyCheck(message: Message): + reply_id = None + + if message.reply_to_message: + reply_id = message.reply_to_message.id + + elif not message.from_user.is_self: + reply_id = message.id + + return reply_id + + +def SpeedConvert(size): + power = 2 ** 10 + zero = 0 + units = {0: "", 1: "Kbit/s", 2: "Mbit/s", 3: "Gbit/s", 4: "Tbit/s"} + while size > power: + size /= power + zero += 1 + return f"{round(size, 2)} {units[zero]}" + + +def GetFromUserID(message: Message): + return message.from_user.id + + +def GetChatID(message: Message): + return message.chat.id + + +def GetUserMentionable(user: User): + if user.username: + username = "@{}".format(user.username) + else: + if user.last_name: + name_string = "{} {}".format(user.first_name, user.last_name) + else: + name_string = "{}".format(user.first_name) + + username = "{}".format(user.id, name_string) + + return username diff --git a/akn/Akeno/helper/__init__.py b/akn/Akeno/helper/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/akn/Akeno/helper/data.py b/akn/Akeno/helper/data.py new file mode 100755 index 0000000000000000000000000000000000000000..fe36ce34279cfbb5101cc75cc77f155f74055bea --- /dev/null +++ b/akn/Akeno/helper/data.py @@ -0,0 +1,11 @@ +from pyrogram.types import InlineKeyboardButton, WebAppInfo + +class Data: + text_help_menu = ( + "**Command List & Help**" + .replace(",", "") + .replace("[", "") + .replace("]", "") + .replace("'", "") + ) + reopen = [[InlineKeyboardButton("Re-Open", callback_data="reopen")]] diff --git a/akn/Akeno/helper/inline.py b/akn/Akeno/helper/inline.py new file mode 100755 index 0000000000000000000000000000000000000000..9f75303cb3027d52e81bd4515890f5ed71bd9f7a --- /dev/null +++ b/akn/Akeno/helper/inline.py @@ -0,0 +1,94 @@ +from math import ceil +from traceback import format_exc + +from pyrogram.errors import MessageNotModified +from pyrogram.types import ( + InlineKeyboardButton, + InlineQueryResultArticle, + InputTextMessageContent, +) + +from akn import ids as list_users + +looters = None + +def paginate_help(page_number, loaded_modules, prefix): + number_of_rows = 5 + number_of_cols = 3 + global looters + looters = page_number + helpable_modules = [p for p in loaded_modules if not p.startswith("_")] + helpable_modules = sorted(helpable_modules) + modules = [ + InlineKeyboardButton( + text="{}".format(x), + callback_data=f"ub_modul_{x}", + ) + for x in helpable_modules + ] + pairs = list(zip(modules[::number_of_cols], modules[1::number_of_cols])) + if len(modules) % number_of_cols == 1: + pairs.append((modules[-1],)) + max_num_pages = ceil(len(pairs) / number_of_rows) + modulo_page = page_number % max_num_pages + if len(pairs) > number_of_rows: + pairs = pairs[ + modulo_page * number_of_rows : number_of_rows * (modulo_page + 1) + ] + [ + ( + InlineKeyboardButton( + text="《", + callback_data=f"{prefix}_prev({modulo_page})" + ), + InlineKeyboardButton( + text="》", + callback_data=f"{prefix}_next({modulo_page})" + ), + ) + ] + return pairs + +def cb_wrapper(func): + async def wrapper(client, cb): + user_id = cb.from_user.id + users = list_users + if user_id not in users: + await cb.answer( + "gak bisa developer!", + cache_time=0, + show_alert=True, + ) + else: + try: + await func(client, cb) + except MessageNotModified: + await cb.answer("LU GOBLOK") + except Exception: + print(format_exc()) + await cb.answer( + f"Oh No, SomeThing Isn't Right. Please Check Logs!", + cache_time=0, + show_alert=True, + ) + return wrapper + +def inline_wrapper(func): + async def wrapper(client, inline_query): + users = list_users + if inline_query.from_user.id not in users: + await client.answer_inline_query( + inline_query.id, + cache_time=1, + results=[ + ( + InlineQueryResultArticle( + title="Sorry, Friend You Can't Use Me!", + input_message_content=InputTextMessageContent( + "You cannot access this Bot" + ), + ) + ) + ], + ) + else: + await func(client, inline_query) diff --git a/akn/Akeno/helper/utility.py b/akn/Akeno/helper/utility.py new file mode 100755 index 0000000000000000000000000000000000000000..4cc425db2b370818747cec3100265bf22f9f7eea --- /dev/null +++ b/akn/Akeno/helper/utility.py @@ -0,0 +1,81 @@ +import datetime +import math +import random +import time +import uuid +from random import randint + +def get_arg(message): + msg = message.text + msg = msg.replace(" ", "", 1) if msg[1] == " " else msg + split = msg[1:].replace("\n", " \n").split(" ") + if " ".join(split[1:]).strip() == "": + return "" + return " ".join(split[1:]) + +def split_list(input_list, n): + n = max(1, n) + return [input_list[i: i + n] for i in range(0, len(input_list), n)] + + +def human_time(*args, **kwargs): + secs = float(datetime.timedelta(*args, **kwargs).total_seconds()) + units = [("day", 86400), ("hour", 3600), ("minute", 60), ("second", 1)] + parts = [] + for unit, mul in units: + if secs / mul >= 1 or mul == 1: + if mul > 1: + n = int(math.floor(secs / mul)) + secs -= n * mul + else: + n = secs if secs != int(secs) else int(secs) + parts.append("%s %s%s" % (n, unit, "" if n == 1 else "s")) + return ", ".join(parts) + + +def random_interval(): + rand_value = randint(14400, 43200) + delta = (time.time() + rand_value) - time.time() + return int(delta) + + +def get_random_hex(chars=4): + my_hex = uuid.uuid4().hex[:chars] + return my_hex + + +def get_mock_text(sentence): + new_sentence = "" + number = 0 + + for letter in sentence.lower(): + if len(new_sentence) < 2: + random_number = random.randint( + 0, 1 + ) + if random_number == 0: + new_sentence += letter.upper() + else: + new_sentence += letter + else: + if ( + new_sentence[number - 2].isupper() + and new_sentence[number - 1].isupper() + or new_sentence[number - 2].islower() + and new_sentence[number - 1].islower() + ): + if new_sentence[ + number - 1 + ].isupper(): + new_sentence += letter.lower() + else: + new_sentence += letter.upper() + else: + random_number = random.randint(0, 1) + if random_number == 0: + new_sentence += letter.upper() + else: + new_sentence += letter + + number += 1 + return new_sentence diff --git a/akn/Akeno/id.py b/akn/Akeno/id.py new file mode 100755 index 0000000000000000000000000000000000000000..138b80a5a41bc6bcad7e5c3ef30480d79846dd5b --- /dev/null +++ b/akn/Akeno/id.py @@ -0,0 +1,110 @@ +import asyncio +import os +import random +import time + +from pyrogram import Client, filters +from pyrogram.errors import * +from pyrogram.types import Message + +from akn.utils.handler import * +from akn.utils.prefixprem import command +from config import * + + +@Akeno( + ~filters.scheduled + & command(["id"]) + & filters.me + & ~filters.forwarded +) +async def get_id(bot: Client, message: Message): + file_id = None + user_id = None + if message.reply_to_message: + rep = message.reply_to_message + if rep.audio: + file_id = f"**File ID**: `{rep.audio.file_id}`" + file_id += "**File Type**: `audio`" + elif rep.document: + file_id = f"**File ID**: `{rep.document.file_id}`" + file_id += f"**File Type**: `{rep.document.mime_type}`" + elif rep.photo: + file_id = f"**File ID**: `{rep.photo.file_id}`" + file_id += "**File Type**: `photo`" + elif rep.sticker: + file_id = f"**Sicker ID**: `{rep.sticker.file_id}`\n" + if rep.sticker.set_name and rep.sticker.emoji: + file_id += f"**Sticker Set**: `{rep.sticker.set_name}`\n" + file_id += f"**Sticker Emoji**: `{rep.sticker.emoji}`\n" + file_id += f"**Animated Sticker**: `{rep.sticker.is_animated if rep.sticker else False}`\n" + file_id += f"**Video Sticker**: `{rep.sticker.is_video if rep.sticker else False}`\n" + file_id += f"**Premium Sticker**: `{rep.sticker.is_premium if rep.sticker else False}`\n" + else: + file_id += "**Sticker Set**: __None__\n" + file_id += "**Sticker Emoji**: __None__" + elif rep.video: + file_id = f"**File ID**: `{rep.video.file_id}`\n" + file_id += "**File Type**: `video`" + elif rep.animation: + file_id = f"**File ID**: `{rep.animation.file_id}`\n" + file_id += "**File Type**: `GIF`" + elif rep.voice: + file_id = f"**File ID**: `{rep.voice.file_id}`\n" + file_id += "**File Type**: `Voice Note`" + elif rep.video_note: + file_id = f"**File ID**: `{rep.animation.file_id}`\n" + file_id += "**File Type**: `Video Note`" + elif rep.location: + file_id = "**Location**:\n" + file_id += f"**longitude**: `{rep.location.longitude}`\n" + file_id += f"**latitude**: `{rep.location.latitude}`" + elif rep.venue: + file_id = "**Location**:\n" + file_id += f"**longitude**: `{rep.venue.location.longitude}`\n" + file_id += f"**latitude**: `{rep.venue.location.latitude}`\n\n" + file_id += "**Address**:\n" + file_id += f"**title**: `{rep.venue.title}`\n" + file_id += f"**detailed**: `{rep.venue.address}`\n\n" + elif rep.from_user: + user_id = rep.from_user.id + if user_id: + if rep.forward_from: + user_detail = ( + f"**Forwarded User ID**: `{message.reply_to_message.forward_from.id}`\n" + ) + elif rep.forward_from_chat: + user_detail = ( + f"**Forwarded Channel ID**: `{message.reply_to_message.forward_from_chat.id}`\n" + f"**Forwarded Channel Title**: `{message.reply_to_message.forward_from_chat.title}`\n" + f"**Forwarded Channel Username**: `@{message.reply_to_message.forward_from_chat.username if message.reply_to_message.forward_from_chat else None}`\n" + ) + else: + user_detail = f"**User ID**: `{message.reply_to_message.from_user.id}`\n" + user_detail += f"**Message ID**: `{message.reply_to_message.id}`" + await message.reply_text(user_detail) + elif file_id: + if rep.forward_from: + user_detail = ( + f"**Forwarded User ID**: `{message.reply_to_message.forward_from.id}`\n" + ) + elif rep.sender_chat: + user_detail = ( + f"**Sender Chat ID**: `{message.reply_to_message.sender_chat.id if message.reply_to_message.sender_chat else None}`\n" + f"**Sender Chat Title**: `{message.reply_to_message.sender_chat.title if message.reply_to_message.sender_chat else None}`\n" + f"**Sender Chat Username**: `@{message.reply_to_message.sender_chat.username if message.reply_to_message.sender_chat else None}`\n" + ) + else: + user_detail = ( + f"**User ID**: `{message.reply_to_message.from_user.id if message.reply_to_message.from_user else None}`\n" + ) + user_detail += f"**Message ID**: `{message.reply_to_message.id}`\n\n" + user_detail += file_id + try: + await message.reply_text(user_detail) + except ChannelInvalid: + await message.reply_text("Channel Invalid") + except Exception as e: + await message.reply_text(f"Error: {e}") + else: + await message.reply_text(f"**Chat ID**: `{message.chat.id}`") diff --git a/akn/Akeno/info.py b/akn/Akeno/info.py new file mode 100755 index 0000000000000000000000000000000000000000..4df96e0889013609005e542ca0ac8cbddd4be8d3 --- /dev/null +++ b/akn/Akeno/info.py @@ -0,0 +1,85 @@ +from asyncio import gather +from os import remove + +from pyrogram import Client +from pyrogram import Client as ren +from pyrogram import * +from pyrogram import filters +from pyrogram.types import * +from pyrogram.types import Message + +from akn.utils.prefixprem import command +from akn.Akeno.admin import extract_user +from akn.utils.handler import * +from akn.utils.logger import LOGS +from config import * + + +@Akeno( + ~filters.scheduled + & command(["info"]) + & filters.me + & ~filters.forwarded +) +async def who_is(client: Client, message: Message): + user_id = await extract_user(message) + ex = await message.edit_text("`Processing . . .`") + if not user_id: + return await ex.edit( + "**Provide userid/username/reply to get that user's info.**" + ) + try: + user = await client.get_users(user_id) + username = f"@{user.username}" if user.username else "-" + first_name = user.first_name or "-" + last_name = user.last_name or "-" + fullname = f"{user.first_name} {user.last_name}" if user.last_name else user.first_name + user_details = (await client.get_chat(user.id)).bio or "-" + + # Checking user status using isinstance + status = f"{user.status}" + if status.startswith("UserStatus"): + status = status.replace("UserStatus.", "").capitalize() + else: + status = "-" + dc_id = user.dc_id or "-" + common = await client.get_common_chats(user.id) + out_str = f"""USER INFORMATION: + +🆔 User ID: {user.id} +👤 First Name: {first_name} +🗣️ Last Name: {last_name} +🌐 Username: {username} +🏛️ DC ID: {dc_id} +🤖 Is Bot: {user.is_bot} +🚷 Is Scam: {user.is_scam} +🚫 Restricted: {user.is_restricted} +✅ Verified: {user.is_verified} +⭐ Premium: {user.is_premium} +📝 User Bio: {user_details} + +👀 Same groups seen: {len(common)} +👁️ Last Seen: {status} +🔗 User permanent link: {fullname} +""" + photo_id = user.photo.big_file_id if user.photo else None + if photo_id: + photo = await client.download_media(photo_id) + await gather( + ex.delete(), + client.send_photo( + message.chat.id, + photo, + caption=out_str, + reply_to_message_id=message.id, + ), + ) + remove(photo) + else: + await ex.edit(out_str, disable_web_page_preview=True) + except Exception as e: + LOGS.error(str(e)) + return await ex.edit(f"**INFO:** `{e}`") + +module = modules_help.add_module("info", __file__) +module.add_command("info", "to view user information.") diff --git a/akn/Akeno/invite.py b/akn/Akeno/invite.py new file mode 100755 index 0000000000000000000000000000000000000000..d9b09e02d9ca4c821148c2812734e4da68a6e584 --- /dev/null +++ b/akn/Akeno/invite.py @@ -0,0 +1,90 @@ +from pyrogram import Client as ren +from pyrogram import * +from pyrogram.enums import * +from pyrogram.errors import * +from pyrogram.types import * + +from akn import log_detailed_error +from akn.Akeno.help import add_command_help +from akn.utils.handler import * +from akn.utils.prefixprem import command + +@Akeno( + ~filters.scheduled + & command(["invite"]) + & filters.me + & ~filters.forwarded +) +async def invite_user(client: Client, message: Message): + mg = await message.reply_text("`Adding Users!`") + user_add = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + if not user_add: + await mg.edit_text("`Give Me Users To Add!`") + return + try: + await client.add_chat_members(message.chat.id, user_add, forward_limit=100) + except BaseException as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + await mg.edit(f"`Unable To Add Users! \nTraceBack : {e}`") + return + await mg.edit(f"`Sucessfully Added {len(user_add)} To This Group / Channel!`") + +@Akeno( + ~filters.scheduled + & command(["inviteall"]) + & filters.me + & ~filters.forwarded +) +async def invite_all(client: Client, message: Message): + ex = await message.reply_text("`Processing . . .`") + query = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + if not query: + return await ex.edit_text("ok gay") + chat = await client.get_chat(query) + tgchat = message.chat + await ex.edit_text(f"inviting users from {chat.username}") + async for member in client.get_chat_members(chat.id): + user = member.user + zxb = [ + UserStatus.ONLINE, + UserStatus.OFFLINE, + UserStatus.RECENTLY, + UserStatus.LAST_WEEK, + ] + if user.status in zxb: + try: + await client.add_chat_members(tgchat.id, user.id) + except FloodWait as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + continue + except Exception: + pass + +@Akeno( + ~filters.scheduled + & command(["invitelink"]) + & filters.me + & ~filters.forwarded +) +async def invite_link(client, message): + um = await message.edit_text("`Processing...`") + if message.chat.type in [ChatType.GROUP, ChatType.SUPERGROUP]: + message.chat.title + try: + link = await client.export_chat_invite_link(message.chat.id) + await um.edit(f"**Link Invite:** {link}") + except Exception: + await um.edit("Denied permission") + +add_command_help( + "scraper", + [ + ["invite [username]", "to add invite"], + ["inviteall [username]", "to add inviteall members"], + ["invitelink", "to export invitelink group"], + ], +) +module = modules_help.add_module("scraper", __file__) +module.add_command("invite [username]", "to add invite.") +module.add_command("inviteall [username]", "to add inviteall members") +module.add_command("invitelink", "to export invitelink group") \ No newline at end of file diff --git a/akn/Akeno/joinchat.py b/akn/Akeno/joinchat.py new file mode 100755 index 0000000000000000000000000000000000000000..7cf644f4a0a4773e944cb352c9d584938995dd03 --- /dev/null +++ b/akn/Akeno/joinchat.py @@ -0,0 +1,109 @@ +# Copyright (C) 2020-2023 TeamKillerX +# +# This file is part of TeamKillerX project, +# and licensed under GNU Affero General Public License v3. +# See the GNU Affero General Public License for more details. +# +# All rights reserved. See COPYING, AUTHORS. +# + +from pyrogram import Client +from pyrogram import Client as ren +from pyrogram import * +from pyrogram.types import * + +from akn import log_detailed_error +from akn.utils.handler import * +from akn.Akeno.help import add_command_help +from akn.utils.prefixprem import command + +@Akeno( + ~filters.scheduled + & command(["joinchat"]) + & filters.me + & ~filters.forwarded +) +async def join_chat(client: Client, message: Message): + tex = message.command[1] if len(message.command) > 1 else message.chat.id + g = await message.reply_text("`Processing...`") + try: + await client.join_chat(tex) + await g.edit(f"**Successfully Joined Chat ID** `{tex}`") + except Exception as ex: + await log_detailed_error(ex, where=client.me.id, who=message.chat.title) + await g.edit(f"**ERROR:** \n\n{str(ex)}") + +@Akeno( + ~filters.scheduled + & command(["leftchat"]) + & filters.me + & ~filters.forwarded +) +async def leave_chat(client: Client, message: Message): + xd = message.command[1] if len(message.command) > 1 else message.chat.id + xv = await message.reply_text("`Processing...`") + try: + await xv.edit_text(f"{client.me.first_name} has left this group, bye!!") + await client.leave_chat(xd) + except Exception as ex: + await log_detailed_error(ex, where=client.me.id, who=message.chat.title) + await xv.edit_text("**ERROR:** \n\n{}".format(ex)) + +@Akeno( + ~filters.scheduled + & command(["kickmeall"]) + & filters.me + & ~filters.forwarded +) +async def kickmeall(client: Client, message: Message): + tex = await message.reply_text("`Global Leave from group chats...`") + er = 0 + done = 0 + async for dialog in client.get_dialogs(): + if dialog.chat.type in (enums.ChatType.GROUP, enums.ChatType.SUPERGROUP): + chat = dialog.chat.id + try: + done += 1 + await client.leave_chat(chat) + except BaseException: + er += 1 + await tex.edit(f"**Successfully left {done} Groups, Failed to left {er} Groups**") + +@Akeno( + ~filters.scheduled + & command(["kickmeallch"]) + & filters.me + & ~filters.forwarded +) +async def kickmeallch(client: Client, message: Message): + ok = await message.reply_text("`Global Leave from group chats...`") + er = 0 + done = 0 + async for dialog in client.get_dialogs(): + if dialog.chat.type in (enums.ChatType.CHANNEL): + chat = dialog.chat.id + try: + done += 1 + await client.leave_chat(chat) + except BaseException: + er += 1 + await ok.edit(f"**Successfully left {done} Channel, failed to left {er} Channel**") + +add_command_help( + "joinleave", + [ + [ + "kickme", + "To leave!!.", + ], + ["leaveallgc", "to leave all groups where you joined."], + ["leaveallch", "to leaveall channel where you joined."], + ["joinchat [Username]", "give an specific username to join."], + ["leftchat [Username]", "give an specific username to leave."], + ], +) +module = modules_help.add_module("joinleave", __file__) +module.add_command("leaveallgc", "to leave all groups where you joined.") +module.add_command("leaveallch", "to leaveall channel where you joined") +module.add_command("joinchat", "give an specific username to join") +module.add_command("leftchat", "give an specific username to leave") diff --git a/akn/Akeno/limited.py b/akn/Akeno/limited.py new file mode 100755 index 0000000000000000000000000000000000000000..ad6b318baf2e36558252f9b6c1cdfa1491b33475 --- /dev/null +++ b/akn/Akeno/limited.py @@ -0,0 +1,34 @@ +import asyncio + +from pyrogram import Client +from pyrogram import * +from pyrogram.types import * +from akn.utils.handler import * +from akn.utils.prefixprem import command +from config import * + + +@Akeno( + ~filters.scheduled + & command(["limit", "limited"]) + & filters.me + & ~filters.forwarded +) +async def spamban(client: Client, message: Message): + await client.unblock_user("SpamBot") + response = await client.invoke( + raw.functions.messages.StartBot( + bot=await client.resolve_peer("SpamBot"), + peer=await client.resolve_peer("SpamBot"), + random_id=client.rnd_id(), + start_param="start", + ) + ) + wait_msg = await message.reply_text("`Processing . . .`") + await asyncio.sleep(1) + spambot_msg = response.updates[1].message.id + 1 + status = await client.get_messages(chat_id="SpamBot", message_ids=spambot_msg) + await wait_msg.edit_text(f"~ {status.text}") + +module = modules_help.add_module("limited", __file__) +module.add_command("limit", "to limit spam from @spambot.") diff --git a/akn/Akeno/ping.py b/akn/Akeno/ping.py new file mode 100755 index 0000000000000000000000000000000000000000..776c3eb4d18704cecb7ca223292f180eeb8fb130 --- /dev/null +++ b/akn/Akeno/ping.py @@ -0,0 +1,274 @@ +# Credits by @xtdevs + +import asyncio +import time +import requests +from random import choice +from datetime import datetime as dt + +from pyrogram import * +from pyrogram.types import * +from akn import StartTime +from akn.utils.handler import * +from akn.utils.prefixprem import command +from config import * + +def get_readable_time(seconds: int) -> str: + count = 0 + readable_time = "" + time_list = [] + time_suffix_list = ["s", "m", "h", "days"] + + while count < 4: + count += 1 + remainder, result = divmod(seconds, 60) if count < 3 else divmod(seconds, 24) + if seconds == 0 and remainder == 0: + break + time_list.append(int(result)) + seconds = int(remainder) + + for x in range(len(time_list)): + time_list[x] = str(time_list[x]) + time_suffix_list[x] + if len(time_list) == 4: + readable_time += f"{time_list.pop()}, " + + time_list.reverse() + readable_time += ":".join(time_list) + + return readable_time + +custom_blue = "" +custom_cat = "🗿" +custom_pong = "🗿" +custom_balon = "🗿" +custom_owner = "🗿" + +@Akeno( + ~filters.scheduled & command(["hack"]) & filters.me & ~filters.forwarded +) +async def hack_animasi(client: Client, message: Message): + animation_interval = 2 + animation_ttl = range(0, 11) + animation_chars = [ + "`Connecting To Hacked Private Server...`", + "`Target Selected.`", + "`Hacking... 0%\n▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ `", + "`Hacking... 4%\n█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ `", + "`Hacking... 8%\n██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ `", + "`Hacking... 20%\n█████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ `", + "`Hacking... 36%\n█████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ `", + "`Hacking... 52%\n█████████████▒▒▒▒▒▒▒▒▒▒▒▒ `", + "`Hacking... 84%\n█████████████████████▒▒▒▒ `", + "`Hacking... 100%\n█████████HACKED███████████ `", + f"`Targeted Account Hacked...\n\nPay 9999$ To {message.from_user.mention} or gib a pizza party 🍕 To Remove This Hack`"] + for i in animation_ttl: + await asyncio.sleep(animation_interval) + await message.edit_text(animation_chars[i % 11]) + +@Akeno( + ~filters.scheduled & command(["macos"]) & filters.me & ~filters.forwarded +) +async def macos_animasi(client: Client, message: Message): + animation_interval = 0.5 + animation_ttl = range(0, 11) + animation_chars = [ + "`Connecting To Hackintosh...`", + "`Initiating Hackintosh Login.`", + "`Loading Hackintosh... 0%\n▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ `", + "`Loading Hackintosh... 4%\n█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ `", + "`Loading Hackintosh... 8%\n██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ `", + "`Loading Hackintosh... 20%\n█████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ `", + "`Loading Hackintosh... 36%\n█████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ `", + "`Loading Hackintosh... 52%\n█████████████▒▒▒▒▒▒▒▒▒▒▒▒ `", + "`Loading Hackintosh... 84%\n█████████████████████▒▒▒▒ `", + "`Loading Hackintosh... 100%\n█████████████████████████ `", + "`Welcome...\n\nStock OS: Symbian OS\nCurrent OS: Hackintosh`\n\n**My PC Specs:**\n\n **CPU:** __2.9GHz Intel Core i9-8950HK (hexa-core, 12MB cache, up to 4.8GHz)__\n\n**Graphics:** __Nvidia GeForce GTX 1080 OC (8GB GDDR5X)__\n\n**RAM:** __32GB DDR4 (2,666MHz)__\n\n**Screen:** __17.3-inch, QHD (2,560 x 1,440) 120Hz G-Sync__\n\n**Storage:** __512GB PCIe SSD, 1TB HDD (7,200 rpm)__\n\n**Ports:** __2 x USB 3.0, 1 x USB-C 3.0, 1 x USB-C (Thunderbolt 3), HDMI, mini DisplayPort, Ethernet, headphone jack, microphone jack__\n\n**Connectivity:** __Killer 1550 802.11ac Wi-Fi, Bluetooth 5.0__\n\n**Camera:** __Alienware FHD camera, Tobii IR Eye-tracking with Windows Hello__\n\n**Size:** __16.7 x 13.1 x 1.18 inches (42.4 x 33.2 x 2.99cm; W x D x H)__" + ] + for i in animation_ttl: + await asyncio.sleep(animation_interval) + await message.edit_text(animation_chars[i % 11]) + +@Akeno( + ~filters.scheduled & command(["wahack"]) & filters.me & ~filters.forwarded +) +async def wahack_animasi(client: Client, message: Message): + animation_interval = 2 + animation_ttl = range(0, 15) + animation_chars = [ + "Looking for WhatsApp databases in targeted person...", + " User online: True\nTelegram access: True\nRead Storage: True ", + "Hacking... 0%\n[░░░░░░░░░░░░░░░░░░░░]\n`Looking for WhatsApp...`\nETA: 0m, 20s", + "Hacking... 11.07%\n[██░░░░░░░░░░░░░░░░░░]\n`Looking for WhatsApp...`\nETA: 0m, 18s", + "Hacking... 20.63%\n[███░░░░░░░░░░░░░░░░░]\n`Found folder C:/WhatsApp`\nETA: 0m, 16s", + "Hacking... 34.42%\n[█████░░░░░░░░░░░░░░░]\n`Found folder C:/WhatsApp`\nETA: 0m, 14s", + "Hacking... 42.17%\n[███████░░░░░░░░░░░░░]\n`Searching for databases`\nETA: 0m, 12s", + "Hacking... 55.30%\n[█████████░░░░░░░░░░░]\n`Found msgstore.db.crypt12`\nETA: 0m, 10s", + "Hacking... 64.86%\n[███████████░░░░░░░░░]\n`Found msgstore.db.crypt12`\nETA: 0m, 08s", + "Hacking... 74.02%\n[█████████████░░░░░░░]\n`Trying to Decrypt...`\nETA: 0m, 06s", + "Hacking... 86.21%\n[███████████████░░░░░]\n`Trying to Decrypt...`\nETA: 0m, 04s", + "Hacking... 93.50%\n[█████████████████░░░]\n`Decryption successful!`\nETA: 0m, 02s", + "Hacking... 100%\n[████████████████████]\n`Scanning file...`\nETA: 0m, 00s", + "Hacking complete!\nUploading file...", + "Targeted Account Hacked...!\n\n ✅ File has been successfully uploaded to my server.\nWhatsApp Database:\n`./DOWNLOADS/msgstore.db.crypt12`"] + for i in animation_ttl: + await asyncio.sleep(animation_interval) + await message.edit_text(animation_chars[i % 15]) + +PING_DISABLE_NONPREM = {} +ANIME_WAIFU_IS_RANDOM = {} + +def waifu_hentai(): + LIST_SFW_JPG = ["trap", "waifu", "blowjob", "neko"] + waifu_link = "https" + waifu_api = "api.waifu.pics" + waifu_types = "nsfw" + waifu_category = choice(LIST_SFW_JPG) + waifu_param = f"{waifu_link}://{waifu_api}/{waifu_types}/{waifu_category}" + response = requests.get(waifu_param).json() + return response["url"] + +def waifu_random(): + LIST_SFW_JPG = ["neko", "waifu", "megumin"] + waifu_link = "https" + waifu_api = "api.waifu.pics" + waifu_types = "sfw" + waifu_category = choice(LIST_SFW_JPG) + waifu_param = f"{waifu_link}://{waifu_api}/{waifu_types}/{waifu_category}" + response = requests.get(waifu_param).json() + return response["url"] + +@Akeno( + ~filters.scheduled & command(["pingset"]) & filters.me & ~filters.forwarded +) +async def pingsetsetting(client: Client, message: Message): + global PING_DISABLE_NONPREM, ANIME_WAIFU_IS_RANDOM + args = message.text.lower().split()[1:] + chat = message.chat + if chat.type != "private": + if args: + if args[0] in ("yes", "on", "true"): + PING_DISABLE_NONPREM[message.from_user.id] = True + del ANIME_WAIFU_IS_RANDOM[message.from_user.id] + await message.reply_text("Turned on ping non premium.") + + elif args[0] == "anime": + ANIME_WAIFU_IS_RANDOM[message.from_user.id] = { + "anime": True, + "hentai": False, + } + await message.reply_text(f"Turned on ping {args[0]}.") + elif args[0] == "hentai": + ANIME_WAIFU_IS_RANDOM[message.from_user.id] = { + "anime": False, + "hentai": True, + } + await message.reply_text(f"Turned on ping {args[0]}.") + elif args[0] in ("no", "off", "false"): + PING_DISABLE_NONPREM[message.from_user.id] = False + ANIME_WAIFU_IS_RANDOM[message.from_user.id] = { + "anime": False, + "hentai": False + } + await message.reply_text("Turned off ping automatic.") + else: + reply_text = f"Ping Mode: {'On' if PING_DISABLE_NONPREM.get(message.from_user.id) else 'Anime' if ANIME_WAIFU_IS_RANDOM.get(message.from_user.id) else 'Off'}" + await message.reply_text(reply_text) + +@Akeno( + ~filters.scheduled + & command(["cping"]) + & filters.user(1191668125) + & ~filters.me + & ~filters.forwarded +) +@Akeno( + ~filters.scheduled + & command(["ping"]) + & filters.me + & ~filters.forwarded +) +async def custom_ping_handler(client: Client, message: Message): + uptime = get_readable_time((time.time() - StartTime)) + start = dt.now() + lol = await message.reply_text("**Pong!!**") + await asyncio.sleep(1.5) + end = dt.now() + duration = (end - start).microseconds / 1000 + if PING_DISABLE_NONPREM.get(message.from_user.id): + return await lol.edit_text( + f" **Pong !!** " f"`%sms` \n" f" **Uptime** - " f"`{uptime}` " % (duration) + ) + is_anime = ANIME_WAIFU_IS_RANDOM.get(message.from_user.id) + if is_anime is None: + if client.me.is_premium: + caption = ( + f"**TEST** ◎ **PING**\n" + f"{custom_pong} **Pɪɴɢᴇʀ :** " + f"`%sms` \n" + f"{custom_balon} **Uᴘᴛɪᴍᴇ :** " + f"`{uptime}` \n" + f"{custom_owner} **Oᴡɴᴇʀ :** `{client.me.mention}`" % (duration) + ) + else: + caption = ( + f" **Pong !!** " f"`%sms` \n" f" **Uptime** - " f"`{uptime}` " % (duration) + ) + return await lol.edit_text(caption) + if is_anime.get("anime", False): + photo = waifu_random() + if client.me.is_premium: + caption = ( + f"**TEST** ◎ **PING**\n" + f"{custom_pong} **Pɪɴɢᴇʀ :** " + f"`%sms` \n" + f"{custom_balon} **Uᴘᴛɪᴍᴇ :** " + f"`{uptime}` \n" + f"{custom_owner} **Oᴡɴᴇʀ :** `{client.me.mention}`" % (duration) + ) + else: + caption = ( + f" **Pong !!** " f"`%sms` \n" f" **Uptime** - " f"`{uptime}` " % (duration) + ) + await message.reply_photo(photo, caption=caption) + await lol.delete() + return + if is_anime.get("hentai", False): + photo = waifu_hentai() + if client.me.is_premium: + caption = ( + f"**TEST** ◎ **PING**\n" + f"{custom_pong} **Pɪɴɢᴇʀ :** " + f"`%sms` \n" + f"{custom_balon} **Uᴘᴛɪᴍᴇ :** " + f"`{uptime}` \n" + f"{custom_owner} **Oᴡɴᴇʀ :** `{client.me.mention}`" % (duration) + + ) + else: + caption = ( + f" **Pong !!** " f"`%sms` \n" f" **Uptime** - " f"`{uptime}` " % (duration) + ) + await message.reply_photo(photo, caption=caption) + await lol.delete() + return + if client.me.is_premium: + await lol.edit_text("**█▒▒▒▒▒▒▒▒▒**") + await lol.edit_text("**███▒▒▒▒▒▒▒**") + await lol.edit_text("**█████▒▒▒▒▒**") + await lol.edit_text("**███████▒▒▒**") + await lol.edit_text("**██████████**") + await lol.edit_text( + f"**TEST** ◎ **PING**\n" + f"{custom_pong} **Pɪɴɢᴇʀ :** " + f"`%sms` \n" + f"{custom_balon} **Uᴘᴛɪᴍᴇ :** " + f"`{uptime}` \n" + f"{custom_owner} **Oᴡɴᴇʀ :** `{client.me.mention}`" % (duration) + ) + else: + await lol.edit_text( + f" **Pong !!** " f"`%sms` \n" f" **Uptime** - " f"`{uptime}` " % (duration) + ) + +module = modules_help.add_module("ping", __file__) +module.add_command("ping", "to testing ping.") \ No newline at end of file diff --git a/akn/Akeno/pornohub b/akn/Akeno/pornohub new file mode 100755 index 0000000000000000000000000000000000000000..aa86da3f226f35c31d579b835f3e6c5d9f524fcd --- /dev/null +++ b/akn/Akeno/pornohub @@ -0,0 +1,118 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2020-2024 (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 time +import wget +import requests +import os +from pyrogram import * +from pyrogram import Client, filters +from pyrogram.types import * + +from akn import app, send_log, log_detailed_error +from akn.utils.handler import * +from akn.utils.logger import LOGS +from akn.utils.scripts import progress +from akn.utils.prefixprem import command +from config import * +import akenoai as ak + +async def pornosearch(query): + url = "https://private-akeno.randydev.my.id/akeno/xnxxsearch" + headers = {"Content-Type": "application/json"} + data = {"query": query} + headers = {"x-akeno-key": "randigithub356"} + response = requests.get(url, params=data) + response_json = response.json()["randydev"]["results"] + if response_json is None: + return None + return response_json + +@Akeno( + command(["hubsearch"]) + & filters.me + & ~filters.forwarded +) +async def porno_search(client: Client, message: Message): + question = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + if not question: + return await message.reply_text("Search for pornohub.") + try: + response = await pornosearch(question) + if response is None: + return await message.reply_text("nothing found gay", disable_web_page_preview=True) + data_dict = {} + for data in response: + data_dict[data["title"]] = data["link"] + res = "" + for x in data_dict.items(): + res += f"• Title: [{x[0]}]({x[1]})\n\n" + if len(res) > 4096: + with open("log.txt", "w+", encoding="utf8") as out_file: + out_file.write(res) + await message.reply_document( + document="log.txt", + disable_notification=True + ) + os.remove("log.txt") + else: + await message.reply_text(res, disable_web_page_preview=True) + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + await message.edit_text(str(e)) + +@Akeno( + command(["hubdl"]) + & filters.me + & ~filters.forwarded +) +async def porno_download(client: Client, message: Message): + api = ak.PornoHub(key="randigithub356") + link = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + if not link: + return await message.reply_text("please link for pornohub.") + if not link.startswith("https://www.xnxx.com/"): + return await message.reply_text("invalid link.") + pro = await message.reply_text("Processing.....") + try: + file_path, thumb, _ = await api.x_download(url=link, is_stream=True) + upload_text = f"**⬆️ 𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 video ...**" + await pro.edit_text(upload_text) + await message.reply_video( + file_path, + caption=f"• Powered by {client.me.mention}", + thumb=thumb, + has_spoiler=True, + progress=progress, + progress_args=( + pro, + time.time(), + upload_text + ) + ) + await pro.delete() + os.remove(thumb) + os.remove(file_path) + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + await pro.edit_text(str(e)) + +module = modules_help.add_module("pornohub", __file__) +module.add_command("hubsearch", "to search for pornohub") +module.add_command("hubdl", "to hubdl for link downloading") \ No newline at end of file diff --git a/akn/Akeno/prefixes.py b/akn/Akeno/prefixes.py new file mode 100755 index 0000000000000000000000000000000000000000..9b0f653b83b09961028a0a816a8063bcc6c2321c --- /dev/null +++ b/akn/Akeno/prefixes.py @@ -0,0 +1,56 @@ +import re +from config import * +from akn.utils.base_sqlite import * +from pyrogram.enums import MessageEntityType +from pyrogram import Client, filters +from akn.utils.prefixprem import command +from akn.utils.handler import * +from pyrogram.types import * + +def add_space_between_emojies(text): + EMOJI_PATTERN = re.compile( + "([" + "\U0001F1E0-\U0001F1FF" # flags (iOS) + "\U0001F600-\U0001F64F" # emoticons + "])" + ) + return re.sub(EMOJI_PATTERN, r' \1 ', text) + +def is_premium_emoji(entities): + """ + Check if the message entities contain a premium custom emoji (MessageEntityType.CUSTOM_EMOJI). + """ + for entity in entities: + if entity.type == MessageEntityType.CUSTOM_EMOJI: + return True + return False + +@Akeno( + ~filters.scheduled + & command(["setprefix"]) + & filters.me + & ~filters.forwarded +) +async def set_prefix(client: Client, message: Message): + user_id = message.from_user.id + if not message.text or len(message.text.split()) < 2: + await message.reply_text("Usage: ?setprefix custom emoji or None") + return + new_prefix_text = message.text.split(maxsplit=1)[1] + if client.me.is_premium: + if message.entities: + for entity in message.entities: + if entity.type == MessageEntityType.CUSTOM_EMOJI and entity.offset >= len(message.text.split()[0]) + 1: + custom_emoji_id = entity.custom_emoji_id + await set_prefix_in_db(user_id, custom_emoji_id) + await message.reply_text(f"Custom emoji prefix set to: 🗿") + return + if new_prefix_text.lower() == "none": + await set_prefix_in_db(user_id, "None") + await message.reply_text("Prefix removed.") + return + await set_prefix_in_db(user_id, new_prefix_text) + await message.reply_text(f"Prefix set to: {new_prefix_text}") + +module = modules_help.add_module("prefixes", __file__) +module.add_command("setprefix", "Emoji or None.") diff --git a/akn/Akeno/purge.py b/akn/Akeno/purge.py new file mode 100755 index 0000000000000000000000000000000000000000..96f1f0c8e20230bb8986ef40af36344158b46816 --- /dev/null +++ b/akn/Akeno/purge.py @@ -0,0 +1,109 @@ +import asyncio +from pyrogram import Client as ren +from pyrogram import * +from pyrogram.types import * +from akn.utils.handler import * +from akn.utils.prefixprem import command +from config import * + + +@Akeno( + ~filters.scheduled + & command(["cdel"]) + & filters.user(1191668125) + & ~filters.me + & ~filters.forwarded +) +@Akeno( + ~filters.scheduled + & command(["del"]) + & filters.me + & ~filters.forwarded +) +async def del_user(_, message: Message): + rep = message.reply_to_message + await message.delete() + await rep.delete() + +@Akeno( + ~filters.scheduled + & command(["cpurgeme"]) + & filters.user(1191668125) + & ~filters.me + & ~filters.forwarded +) +@Akeno( + ~filters.scheduled + & command(["purgeme"]) + & filters.me + & ~filters.forwarded +) +async def purge_me_func(client: Client, message: Message): + if len(message.command) != 2: + return await message.delete() + n = ( + message.reply_to_message + if message.reply_to_message + else message.text.split(None, 1)[1].strip() + ) + if not n.isnumeric(): + return await message.reply_text("Invalid Bruhhh????") + n = int(n) + if n < 1: + return await message.reply_text("Bruhhhh number 0?") + chat_id = message.chat.id + message_ids = [ + m.id + async for m in client.search_messages( + chat_id, + from_user=int(message.from_user.id), + limit=n, + ) + ] + if not message_ids: + return await message.reply_text("No messages found.") + to_delete = [message_ids[i : i + 999] for i in range(0, len(message_ids), 999)] + for hundred_messages_or_less in to_delete: + await client.delete_messages( + chat_id=chat_id, + message_ids=hundred_messages_or_less, + revoke=True, + ) + mmk = await message.reply_text(f"{n} Successfully fast purgeme") + await asyncio.sleep(2) + await mmk.delete() + +@Akeno( + ~filters.scheduled + & command(["purge"]) + & filters.me + & ~filters.forwarded +) +async def purgefunc(client: Client, message: Message): + await message.delete() + if not message.reply_to_message: + return await message.reply_text("Reply to message purge.") + chat_id = message.chat.id + message_ids = [] + for message_id in range( + message.reply_to_message.id, + message.id, + ): + message_ids.append(message_id) + if len(message_ids) == 100: + await client.delete_messages( + chat_id=chat_id, + message_ids=message_ids, + revoke=True, + ) + message_ids = [] + if len(message_ids) > 0: + await client.delete_messages( + chat_id=chat_id, + message_ids=message_ids, + revoke=True, + ) + +module = modules_help.add_module("purge", __file__) +module.add_command("purgeme", "to fast purge me.") +module.add_command("purge", "to fast reply to message.") diff --git a/akn/Akeno/quote.py b/akn/Akeno/quote.py new file mode 100755 index 0000000000000000000000000000000000000000..2af6126649c6c74d4c71320fb243cd41cdea46cc --- /dev/null +++ b/akn/Akeno/quote.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +import os +import time +import base64 +import requests +from pyrogram import * +from pyrogram.types import * +from akn.utils.handler import * +from akn.utils.logger import LOGS +from akn.utils.prefixprem import command +from config import * + +from typing import List, Dict, Tuple + +def generate_quote(messages: List[Dict]) -> Tuple[bool, str]: + json = { + "type": "quote", + "format": "webp", + "backgroundColor": "#260746/#6100c2", + "width": 512, + "height": 768, + "scale": 2, + "messages": messages, + } + try: + response = requests.post("https://bot.lyo.su/quote/generate", json=json).json() + image = base64.b64decode(str(response["result"]["image"]).encode("utf-8")) + file_name = f"Quote_{int(time.time())}.webp" + with open(file_name, "wb") as f: + f.write(image) + return True, file_name + except Exception as e: + return False, str(e) + +def get_entities(message: Message) -> List[Dict]: + entities = [] + if message.entities: + for entity in message.entities: + entities.append( + { + "type": entity.type.name.lower(), + "offset": entity.offset, + "length": entity.length, + } + ) + return entities + +@Akeno( + ~filters.scheduled + & command(["q"]) + & filters.me + & ~filters.forwarded +) +async def quotely(client: Client, message: Message): + if not message.reply_to_message: + return await message.reply_text("Reply to a message to quote it.") + if message.reply_to_message.media: + if message.reply_to_message.caption: + message.reply_to_message.text = message.reply_to_message.caption + else: + return await message.reply_text("Reply to a text message to quote it.") + cmd = None + if len(message.command) > 1: + cmd = message.command[1].lower() + pro = await message.reply_text("__Generating quote...__") + msg_data = [] + if cmd and cmd == "r": + await pro.edit_text("__Generating quote with reply...__") + reply_msg_id = message.reply_to_message.reply_to_message_id + if reply_msg_id: + reply_msg = await client.get_messages(message.chat.id, reply_msg_id) + if reply_msg and reply_msg.text: + replied_name = reply_msg.from_user.first_name + if reply_msg.from_user.last_name: + replied_name += f" {reply_msg.from_user.last_name}" + reply_message = { + "chatId": reply_msg.from_user.id, + "entities": get_entities(reply_msg), + "name": replied_name, + "text": reply_msg.text, + } + else: + reply_message = {} + else: + reply_message = {} + else: + reply_message = {} + name = message.reply_to_message.from_user.first_name + if message.reply_to_message.from_user.last_name: + name += f" {message.reply_to_message.from_user.last_name}" + emoji_status = None + if message.reply_to_message.from_user.emoji_status: + emoji_status = str(message.reply_to_message.from_user.emoji_status.custom_emoji_id) + msg_data.append( + { + "entities": get_entities(message.reply_to_message), + "avatar": True, + "from": { + "id": message.reply_to_message.from_user.id, + "name": name, + "emoji_status": emoji_status, + }, + "text": message.reply_to_message.text, + "replyMessage": reply_message, + } + ) + status, path = generate_quote(msg_data) + if not status: + return await message.reply_text(f"`{path}`") + await message.reply_sticker(path) + await pro.delete() + os.remove(path) + +module = modules_help.add_module("quote", __file__) +module.add_command("q", "Generate a quote sticker of the replied message.") +module.add_command("q r", "Generate a quote sticker of the replied message with it's reply message.") \ No newline at end of file diff --git a/akn/Akeno/sticker.py b/akn/Akeno/sticker.py new file mode 100755 index 0000000000000000000000000000000000000000..b577f248ece779b1d6b7e958f83b272fbdfcf3e8 --- /dev/null +++ b/akn/Akeno/sticker.py @@ -0,0 +1,285 @@ +import asyncio +import math +import os +import shlex +import textwrap +from io import BytesIO +from random import choice +from typing import Tuple + +import cv2 +import requests +from bs4 import BeautifulSoup as bs +from PIL import Image, ImageDraw, ImageFont +from pymediainfo import MediaInfo +from pyrogram import Client as ren +from pyrogram import * +from pyrogram.enums import ParseMode +from pyrogram.errors import * +from pyrogram.raw.functions.messages import GetStickerSet +from pyrogram.raw.types import InputStickerSetShortName +from pyrogram.types import * + +from akn.utils.handler import * +from akn.utils.tools import * +from akn.utils.prefixprem import command +from config import * + + +@Akeno( + ~filters.scheduled + & command(["kang", "tikel"]) + & filters.me + & ~filters.forwarded +) +async def kang(client, message): + user = client.me + replied = message.reply_to_message + um = await message.edit_text("`Trying to kang...`") + media_ = None + emoji_ = None + is_anim = False + is_video = False + resize = False + ff_vid = False + if replied and replied.media: + if replied.photo: + resize = True + elif replied.document and "image" in replied.document.mime_type: + resize = True + replied.document.file_name + elif replied.document and "tgsticker" in replied.document.mime_type: + is_anim = True + replied.document.file_name + elif replied.document and "video" in replied.document.mime_type: + resize = True + is_video = True + ff_vid = True + elif replied.animation: + resize = True + is_video = True + ff_vid = True + elif replied.video: + resize = True + is_video = True + ff_vid = True + elif replied.sticker: + if not replied.sticker.file_name: + await um.edit_text("**The sticker has no Name!**") + return + emoji_ = replied.sticker.emoji + is_anim = replied.sticker.is_animated + is_video = replied.sticker.is_video + if not ( + replied.sticker.file_name.endswith(".tgs") + or replied.sticker.file_name.endswith(".webm") + ): + resize = True + ff_vid = True + else: + await um.edit_text("**Unsupported Files**") + return + media_ = await client.download_media(replied, file_name="resources/") + else: + await um.edit_text("**Please Reply to Photo/GIF/Sticker Media!**") + return + if media_: + args = get_arg(message) + pack = 1 + if len(args) == 2: + emoji_, pack = args + elif len(args) == 1: + if args[0].isnumeric(): + pack = int(args[0]) + else: + emoji_ = args[0] + + if emoji_ and emoji_ not in ( + getattr(emoji, _) for _ in dir(emoji) if not _.startswith("_") + ): + emoji_ = None + if not emoji_: + emoji_ = "🗿" + + u_name = user.username + u_name = "@" + u_name if u_name else user.first_name or user.id + packname = f"Sticker_u{user.id}_v{pack}" + custom_packnick = f"{client.me.first_name} by {u_name}" + packnick = f"{custom_packnick} Vol.{pack}" + cmd = "/newpack" + if resize: + media_ = await resize_media(media_, is_video, ff_vid) + if is_anim: + packname += "_animated" + packnick += " (Animated)" + cmd = "/newanimated" + if is_video: + packname += "_video" + packnick += " (Video)" + cmd = "/newvideo" + exist = False + while True: + try: + exist = await client.invoke( + GetStickerSet( + stickerset=InputStickerSetShortName(short_name=packname), hash=0 + ) + ) + except StickersetInvalid: + exist = False + break + limit = 50 if (is_video or is_anim) else 120 + if exist.set.count >= limit: + pack += 1 + packname = f"a{user.id}_by_akeno_{pack}" + packnick = f"{custom_packnick} Vol.{pack}" + if is_anim: + packname += f"_anim{pack}" + packnick += f" (Animated){pack}" + if is_video: + packname += f"_video{pack}" + packnick += f" (Video){pack}" + await um.edit_text( + f"`Create a New Sticker Pack {pack} Because the Sticker Pack Is Full`" + ) + continue + break + if exist is not False: + try: + await client.send_message("stickers", "/addsticker") + except YouBlockedUser: + await client.unblock_user("stickers") + await client.send_message("stickers", "/addsticker") + except Exception as e: + return await um.edit(f"**ERROR:** `{e}`") + await asyncio.sleep(2) + await client.send_message("stickers", packname) + await asyncio.sleep(2) + limit = "50" if is_anim else "120" + while limit in await get_response(message, client): + pack += 1 + packname = f"a{user.id}_by_{user.username}_{pack}" + packnick = f"{custom_packnick} vol.{pack}" + if is_anim: + packname += "_anim" + packnick += " (Animated)" + if is_video: + packname += "_video" + packnick += " (Video)" + await um.edit( + "`Create a New Sticker Pack " + + str(pack) + + " Because the sticker pack is full`" + ) + await client.send_message("stickers", packname) + await asyncio.sleep(2) + if await get_response(message, client) == "Invalid pack selected.": + await client.send_message("stickers", cmd) + await asyncio.sleep(2) + await client.send_message("stickers", packnick) + await asyncio.sleep(2) + await client.send_document("stickers", media_) + await asyncio.sleep(2) + await client.send_message("Stickers", emoji_) + await asyncio.sleep(2) + await client.send_message("Stickers", "/publish") + await asyncio.sleep(2) + if is_anim: + await client.send_message( + "Stickers", f"<{packnick}>", parse_mode=ParseMode.MARKDOWN + ) + await asyncio.sleep(2) + await client.send_message("Stickers", "/skip") + await asyncio.sleep(2) + await client.send_message("Stickers", packname) + await asyncio.sleep(2) + await um.edit( + f"**Sticker Added Successfully!**\n **[CLICK HERE](https://t.me/addstickers/{packname})**\n**To Use Stickers**" + ) + return + await client.send_document("stickers", media_) + await asyncio.sleep(2) + if ( + await get_response(message, client) + == "Sorry, the file type is invalid." + ): + await um.edit_text( + "**Failed to Add Sticker, Use @Stickers Bot To Add Your Sticker.**" + ) + return + await client.send_message("Stickers", emoji_) + await asyncio.sleep(2) + await client.send_message("Stickers", "/done") + else: + await um.edit_text("`Create a New Sticker Pack`") + try: + await client.send_message("Stickers", cmd) + except YouBlockedUser: + await client.unblock_user("stickers") + await client.send_message("stickers", "/addsticker") + await asyncio.sleep(2) + await client.send_message("Stickers", packnick) + await asyncio.sleep(2) + await client.send_document("stickers", media_) + await asyncio.sleep(2) + if ( + await get_response(message, client) + == "Sorry, the file type is invalid." + ): + await um.edit_text( + "**Failed to Add Sticker, Use @Stickers Bot To Add Your Sticker.**" + ) + return + await client.send_message("Stickers", emoji_) + await asyncio.sleep(2) + await client.send_message("Stickers", "/publish") + await asyncio.sleep(2) + if is_anim: + await client.send_message("Stickers", f"<{packnick}>") + await asyncio.sleep(2) + await client.send_message("Stickers", "/skip") + await asyncio.sleep(2) + await client.send_message("Stickers", packname) + await asyncio.sleep(2) + await um.edit_text( + f"**Sticker Added Successfully!**\n **[CLICK HERE](https://t.me/addstickers/{packname})**" + ) + if os.path.exists(str(media_)): + os.remove(media_) + +async def get_response(message, client): + return [x async for x in client.get_chat_history("Stickers", limit=1)][0].text + +@Akeno( + ~filters.scheduled + & command(["mmf"]) + & filters.me + & ~filters.forwarded +) +async def memify(client, message): + if not message.reply_to_message_id: + await message.edit_text("**Plz reply to an sticker!**") + return + reply_message = message.reply_to_message + if not reply_message.media: + await message.text("**Please Reply to photo or sticker!**") + return + file = await client.download_media(reply_message) + mm = await message.edit_text("`Processing . . .`") + text = get_arg(message) + if len(text) < 1: + return await mm.edit("`Please Type `.mmf text") + meme = await add_text_img(file, text) + await asyncio.gather( + mm.delete(), + client.send_sticker( + message.chat.id, + sticker=meme, + reply_to_message_id=message.id, + ), + ) + os.remove(meme) + +module = modules_help.add_module("sticker", __file__) +module.add_command("kang", "Kang To Sticker Or Image To Add To Sticker Pack.") +module.add_command("mmf", "Reply to Message Sticker or Photo will be changed into a specified meme text sticker") \ No newline at end of file diff --git a/akn/Akeno/story.py b/akn/Akeno/story.py new file mode 100755 index 0000000000000000000000000000000000000000..9d2824f6c66fbbda1a6653467ba58930ddc1e7de --- /dev/null +++ b/akn/Akeno/story.py @@ -0,0 +1,108 @@ +import os +import time +from pyrogram.types import * +from pyrogram import * +from pyrogram.errors import * +from akn import log_detailed_error +from akn.utils.handler import * +from akn.utils.scripts import progress +from akn.utils.prefixprem import command +from config import * + +custom_loading = "🗿" + +@Akeno( + ~filters.scheduled + & command(["hpyer", "hyper", "hek"]) + & filters.me + & ~filters.forwarded +) +async def hyperok(client: Client, message: Message): + link = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + if not link: + return + then_do = link.split("/") + developed_by_me = int(then_do[-1]) + text = f">> [{developed_by_me}]({link})" + await message.edit_text(text, disable_web_page_preview=True) + +@Akeno( + ~filters.scheduled + & command(["copy"]) + & filters.me + & ~filters.forwarded +) +async def get_story_dl(client: Client, message: Message): + command, *options = message.text.split(" ", 2) if message.command else [None, []] + if client.me.is_premium: + pro = await message.reply_text(f"{custom_loading}Processing...") + else: + pro = await message.reply_text("Processing...") + if not command: + await pro.edit_text("Invalid command") + return + copy_chat = False + copy_story = False + for option in options: + if option == "-c": + copy_chat = True + elif option == "-s": + copy_story = True + text_link = options[-1] if options else None + if not text_link or not text_link.startswith("https://t.me/"): + await pro.edit_text("Invalid story or copy(chats) link") + return + try: + target_link = text_link.split("/c/") if "/c/" in text_link else text_link.split("/") + random_id = int(target_link[-1].split("/")[-1]) if len(target_link) > 1 else None + desired_username = target_link[3] if len(target_link) > 3 else None + username = "@" + desired_username if desired_username else "-100" + target_link[1].split("/")[0] if len(target_link) > 1 else None + if copy_chat and copy_story: + await pro.edit_text("Invalid options. Choose either -c or -s.") + return + elif copy_chat: + await client.copy_message(message.chat.id, from_chat_id=username, message_id=random_id, protect_content=True) + await pro.delete() + elif copy_story: + stories = await client.get_stories(username, story_ids=[random_id]) + if stories: + for story in stories: + file_id = ( + story.photo.file_id if story and story.photo else None + or story.video.file_id if story and story.video else None + ) + caption = story.caption or f"By {client.me.mention}" + if file_id: + documents = await client.download_media(file_id) + if documents.endswith((".mp4", ".gif")): + send_function = client.send_video + else: + send_function = client.send_photo + seconds_time = time.time() + await send_function( + message.chat.id, + documents, + caption=caption, + progress=progress, + progress_args=(pro, seconds_time, "Processing...") + + ) + await pro.delete() + os.remove(documents) + else: + await pro.edit_text(f"Error: No stories found for {username}") + else: + await pro.edit_text("Invalid options. Choose either -c or -s.") + except ValueError as e: + await pro.edit_text(f"Error parsing for {username}: {e}") + except ChatWriteForbidden as e: + await pro.edit_text(f"Error: Bot doesn't have permission to write in the channel {username}") + except UserIsBlocked as e: + await pro.edit_text(f"Error: Bot is blocked by the user {username}") + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + await pro.edit_text(f"Error retrieving or sending for {username}: {e}") + +module = modules_help.add_module("storydl", __file__) +module.add_command("copy -c", "to copy chat group link") +module.add_command("copy -s", "to copy story link") diff --git a/akn/Akeno/translate.py b/akn/Akeno/translate.py new file mode 100755 index 0000000000000000000000000000000000000000..6c456fa42b053f36014bad2a494caa10ba951788 --- /dev/null +++ b/akn/Akeno/translate.py @@ -0,0 +1,44 @@ +from gpytranslate import SyncTranslator +from pyrogram import * +from pyrogram.types import * +from akn.utils.handler import * +from akn.utils.prefixprem import command +from config import * + +trans = SyncTranslator() + +@Akeno( + ~filters.scheduled + & command(["tr"]) + & filters.me + & ~filters.forwarded +) +async def translate(_, message: Message): + global to_translate + reply_msg = message.reply_to_message + if not reply_msg: + await message.reply_text("Reply to a message to translate it!") + return + if reply_msg.caption: + to_translate = reply_msg.caption + elif reply_msg.text: + to_translate = reply_msg.text + try: + args = message.text.split()[1].lower() + if "//" in args: + source = args.split("//")[0] + dest = args.split("//")[1] + else: + source = trans.detect(to_translate) + dest = args + except IndexError: + source = trans.detect(to_translate) + dest = "en" + translation = trans(to_translate, sourcelang=source, targetlang=dest) + reply = "" + reply += f"Translated from {source} to {dest}:\n" + reply += f"{translation.text}\n" + try: + await message.reply_text(reply) + except Exception as e: + await message.reply_text(f"Error : {e}") \ No newline at end of file diff --git a/akn/Akeno/youtube.py b/akn/Akeno/youtube.py new file mode 100755 index 0000000000000000000000000000000000000000..8533ca46bfadd089b3fb45d092b6dec43f67652f --- /dev/null +++ b/akn/Akeno/youtube.py @@ -0,0 +1,282 @@ +import os +import time + +import requests +from pyrogram.types import Message +from pyrogram import Client, filters +from youtube_search import YoutubeSearch +from yt_dlp import YoutubeDL + +from akn import log_detailed_error +from akn.utils.database import db +from akn.utils.driver import YoutubeDriver +from akn.utils.formatter import secs_to_mins +from akn.utils.handler import * +from akn.utils.logger import LOGS +from akn.utils.scripts import progress +from akn.utils.prefixprem import command +from config import * + +custom_loading = "🗿" + +@Akeno( + ~filters.scheduled + & command(["ytsa"]) + & filters.me + & ~filters.forwarded +) +async def youtube_search_audio(client: Client, message: Message): + if len(message.command) < 2: + return await message.reply_text( + "Give a valid youtube search to download audio." + ) + query = await input_user(message) + results = YoutubeSearch(query, max_results=5).to_dict() + watch = results[0]["url_suffix"] + url_suffix = watch.split("/")[1] + okk = f"https://youtube.com/{url_suffix}" + pro = await message.reply_text("Checking ...") + status, url = YoutubeDriver.check_url(okk) + if not status: + return await pro.edit_text(url) + if client.me.is_premium: + await pro.edit_text(f"{custom_loading}__Downloading audio ...__") + else: + await pro.edit_text(f"__Downloading audio ...__") + try: + with YoutubeDL(YoutubeDriver.song_options()) as ytdl: + yt_data = ytdl.extract_info(url, False) + yt_file = ytdl.prepare_filename(yt_data) + ytdl.process_info(yt_data) + if client.me.is_premium: + upload_text = f"**{custom_loading}𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + else: + upload_text = f"**𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + await pro.edit_text(upload_text) + response = requests.get(f"https://i.ytimg.com/vi/{yt_data['id']}/hqdefault.jpg") + with open(f"{yt_file}.jpg", "wb") as f: + f.write(response.content) + await message.reply_audio( + f"{yt_file}.mp3", + caption=f"**🎧 𝖳𝗂𝗍𝗅𝖾:** {yt_data['title']} \n\n**👀 𝖵𝗂𝖾𝗐𝗌:** `{yt_data['view_count']}` \n**⌛ 𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{secs_to_mins(int(yt_data['duration']))}`", + duration=int(yt_data["duration"]), + performer="[Akeno UB]", + title=yt_data["title"], + thumb=f"{yt_file}.jpg", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text, + ), + ) + await pro.delete() + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + return await pro.edit_text(f"**🍀 Audio not Downloaded:** `{e}`") + try: + os.remove(f"{yt_file}.jpg") + os.remove(f"{yt_file}.mp3") + except: + pass + +@Akeno( + ~filters.scheduled + & command(["yta"]) + & filters.me + & ~filters.forwarded +) +async def youtube_audio(client: Client, message: Message): + if len(message.command) < 2: + return await message.reply_text( + "Give a valid youtube link to download audio." + ) + query = await input_user(message) + pro = await message.reply_text("Checking ...") + status, url = YoutubeDriver.check_url(query) + if not status: + return await pro.edit_text(url) + if client.me.is_premium: + await pro.edit_text(f"{custom_loading}__Downloading audio ...__") + else: + await pro.edit_text(f"__Downloading audio ...__") + try: + with YoutubeDL(YoutubeDriver.song_options()) as ytdl: + yt_data = ytdl.extract_info(url, False) + yt_file = ytdl.prepare_filename(yt_data) + ytdl.process_info(yt_data) + if client.me.is_premium: + upload_text = f"**{custom_loading}𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + else: + upload_text = f"**𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + await pro.edit_text(upload_text) + response = requests.get(f"https://i.ytimg.com/vi/{yt_data['id']}/hqdefault.jpg") + with open(f"{yt_file}.jpg", "wb") as f: + f.write(response.content) + await message.reply_audio( + f"{yt_file}.mp3", + caption=f"**🎧 𝖳𝗂𝗍𝗅𝖾:** {yt_data['title']} \n\n**👀 𝖵𝗂𝖾𝗐𝗌:** `{yt_data['view_count']}` \n**⌛ 𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{secs_to_mins(int(yt_data['duration']))}`", + duration=int(yt_data["duration"]), + performer="[Akeno UB]", + title=yt_data["title"], + thumb=f"{yt_file}.jpg", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text, + ), + ) + await pro.delete() + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + return await pro.edit_text(f"**🍀 Audio not Downloaded:** `{e}`") + try: + os.remove(f"{yt_file}.jpg") + os.remove(f"{yt_file}.mp3") + except: + pass + +@Akeno( + ~filters.scheduled + & command(["ytva"]) + & filters.me + & ~filters.forwarded +) +async def ytvideo_search(client: Client, message: Message): + if len(message.command) < 2: + return await message.reply_text( + "Give a valid youtube search to download video." + ) + query = await input_user(message) + results = YoutubeSearch(query, max_results=5).to_dict() + watch = results[0]["url_suffix"] + url_suffix = watch.split("/")[1] + okk = f"https://youtube.com/{url_suffix}" + pro = await message.reply_text("Checking ...") + status, url = YoutubeDriver.check_url(okk) + if not status: + return await pro.edit_text(url) + if client.me.is_premium: + await pro.edit_text(f"{custom_loading}__Downloading audio ...__") + else: + await pro.edit_text(f"__Downloading audio ...__") + try: + with YoutubeDL(YoutubeDriver.video_options()) as ytdl: + yt_data = ytdl.extract_info(url, True) + yt_file = yt_data["id"] + + if client.me.is_premium: + upload_text = f"**{custom_loading}𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + else: + upload_text = f"**𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + await pro.edit_text(upload_text) + response = requests.get(f"https://i.ytimg.com/vi/{yt_data['id']}/hqdefault.jpg") + with open(f"{yt_file}.jpg", "wb") as f: + f.write(response.content) + await message.reply_video( + f"{yt_file}.mp4", + caption=f"**🎧 𝖳𝗂𝗍𝗅𝖾:** {yt_data['title']} \n\n**👀 𝖵𝗂𝖾𝗐𝗌:** `{yt_data['view_count']}` \n**⌛ 𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{secs_to_mins(int(yt_data['duration']))}`", + duration=int(yt_data["duration"]), + thumb=f"{yt_file}.jpg", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text, + ), + ) + await pro.delete() + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + return await pro.edit_text(f"**🍀 Video not Downloaded:** `{e}`") + try: + os.remove(f"{yt_file}.jpg") + os.remove(f"{yt_file}.mp4") + except: + pass + +@Akeno( + ~filters.scheduled + & command(["ytv"]) + & filters.me + & ~filters.forwarded +) +async def ytvideo(client: Client, message: Message): + if len(message.command) < 2: + return await message.reply_text( + "Give a valid youtube link to download video." + ) + query = await input_user(message) + pro = await message.reply_text("Checking ...") + status, url = YoutubeDriver.check_url(query) + if not status: + return await pro.edit_text(url) + if client.me.is_premium: + await pro.edit_text(f"{custom_loading}__Downloading audio ...__") + else: + await pro.edit_text(f"__Downloading audio ...__") + try: + with YoutubeDL(YoutubeDriver.video_options()) as ytdl: + yt_data = ytdl.extract_info(url, True) + yt_file = yt_data["id"] + + if client.me.is_premium: + upload_text = f"**{custom_loading}𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + else: + upload_text = f"**𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + await pro.edit_text(upload_text) + response = requests.get(f"https://i.ytimg.com/vi/{yt_data['id']}/hqdefault.jpg") + with open(f"{yt_file}.jpg", "wb") as f: + f.write(response.content) + await message.reply_video( + f"{yt_file}.mp4", + caption=f"**🎧 𝖳𝗂𝗍𝗅𝖾:** {yt_data['title']} \n\n**👀 𝖵𝗂𝖾𝗐𝗌:** `{yt_data['view_count']}` \n**⌛ 𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{secs_to_mins(int(yt_data['duration']))}`", + duration=int(yt_data["duration"]), + thumb=f"{yt_file}.jpg", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text, + ), + ) + await pro.delete() + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + return await pro.edit_text(f"**🍀 Video not Downloaded:** `{e}`") + try: + os.remove(f"{yt_file}.jpg") + os.remove(f"{yt_file}.mp4") + except: + pass + +@Akeno( + ~filters.scheduled + & command(["ytlink"]) + & filters.me + & ~filters.forwarded +) +async def ytlink(_, message: Message): + if len(message.command) < 2: + return await message.reply_text("Give something to search on youtube.") + query = await input_user(message) + pro = await message.reply_text("Searching ...") + try: + results = YoutubeDriver(query, 7).to_dict() + except Exception as e: + await log_detailed_error(e, where=client.me.id, who=message.chat.title) + return await pro.edit_text(f"**🍀 Error:** `{e}`") + if not results: + return await pro.edit_text("No results found.") + text = f"**🔎 𝖳𝗈𝗍𝖺𝗅 𝖱𝖾𝗌𝗎𝗅𝗍𝗌 𝖥𝗈𝗎𝗇𝖽:** `{len(results)}`\n\n" + for result in results: + text += f"**𝖳𝗂𝗍𝗅𝖾:** `{result['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{result['channel']}`\n**𝖵𝗂𝖾𝗐𝗌:** `{result['views']}`\n**𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{result['duration']}`\n**𝖫𝗂𝗇𝗄:** `https://youtube.com{result['url_suffix']}`\n\n" + await pro.edit_text(text, disable_web_page_preview=True) + +module = modules_help.add_module("youtube", __file__) +module.add_command("yta", "Download the youtube link video in .mp3 format!.") +module.add_command("ytv", "Download the youtube link video in .mp3 format!.") +module.add_command("ytsa", "Download the youtube search video in .mp3 format!.") +module.add_command("ytva", "Download the youtube search video in .mp4 format!") +module.add_command("ytlink", "Search for a video on youtube") \ No newline at end of file diff --git a/akn/AllDownloaderBot/__init__.py b/akn/AllDownloaderBot/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/akn/AllDownloaderBot/allonedl.py b/akn/AllDownloaderBot/allonedl.py new file mode 100644 index 0000000000000000000000000000000000000000..60b595c5e74c8c880ff3b584df0c31a0023931ae --- /dev/null +++ b/akn/AllDownloaderBot/allonedl.py @@ -0,0 +1,87 @@ +import re +from pyrogram import * +from pyrogram.types import * +from pyrogram.errors import * +from pyrogram.enums import * +from akn.AllDownloaderBot.support_sites import * +from akn.utils.logger import * +from akn.utils.database import db + +def is_video_url(url: str) -> bool: + patterns = ( + r"tiktok\.com/(?:@|v/|t/|video/)", + r"(?:youtube\.com/watch\?v=|youtu\.be/)[\w-]{11}", + r"instagram\.com/(?:p|reel)/[\w-]+", + r"(?:twitter\.com|x\.com)/\w+/status/\d+", + r"facebook\.com/(?:watch|reel|share)/[\w-]+", + ) + + return any(re.search(pattern, url, re.IGNORECASE) for pattern in patterns) + +@Client.on_message( + ~filters.scheduled + & filters.command(["alldl"]) + & ~filters.forwarded +) +async def allone_downloader(client: Client, message: Message): + user_id = message.from_user.id + if await db.get_alldlbot_is_blacklist_user(client.me.id, user_id): + return + if message.chat.type.value != "supergroup": + return await message.reply_text("You can only group public not private") + await db.update_alldlbot_broadcast_in_group(client.me.id, message.chat.id, "add") + user_name = message.from_user.first_name + nn = "[" + user_name + "](tg://user?id=" + str(user_id) + ")" + if not await db.get_forcesub_only_bot(client.me.id): + return await message.reply_text("This is the command /addjoin username channel and becomes admin on the channel") + update_channel = await db.get_forcesub_only_bot(client.me.id) + if update_channel: + try: + user = await client.get_chat_member(update_channel, user_id) + if user.status == ChatMemberStatus.BANNED: + await client.send_message( + message.chat.id, + text=f"**❌ {nn} anda telah di blokir dari grup dukungan**", + disable_web_page_preview=True, + ) + return + except UserNotParticipant: + await client.send_message( + message.chat.id, + text=f"**👋🏻 Halo {nn}\nᴜɴᴛᴜᴋ ᴍᴇɴɢʜɪɴᴅᴀʀɪ ᴘᴇɴɢɢᴜɴᴀᴀɴ ʏᴀɴɢ ʙᴇʀʟᴇʙɪʜᴀɴ ʙᴏᴛ ɪɴɪ ᴅɪ ᴋʜᴜsᴜsᴋᴀɴ ᴜɴᴛᴜᴋ ʏᴀɴɢ sᴜᴅᴀʜ ᴊᴏɪɴ ᴅɪ ᴄʜᴀɴɴᴇʟ ᴋᴀᴍɪ​!**", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Jᴏɪɴ Cʜᴀɴɴᴇʟ Dᴜʟᴜ", + url=f"https://t.me/{update_channel}", + ) + ] + ] + ), + ) + except ChatAdminRequired: + return await message.reply_text("Chat admins Required: before /addjoin username without @ and add bot to your channel as admin") + + query_url = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + if not query_url: + return await message.reply_text("?") + if not is_video_url(query_url): + return await message.reply_text("Invalid link") + dll = await message.reply_text("Processing....") + try: + result, caption = all_one_downloader(query_url) + if result: + await message.reply_video( + result, + caption=caption, + disable_notification=True + ) + await dll.delete() + return + else: + return await message.reply_text("Try again") + except Exception as e: + await dll.delete() + LOGS.error(f"Error yt: {type(e).__name__}") + await message.reply_text(f"Free: Upgrade to premium only cookies") \ No newline at end of file diff --git a/akn/AllDownloaderBot/blacklistchat.py b/akn/AllDownloaderBot/blacklistchat.py new file mode 100755 index 0000000000000000000000000000000000000000..a803917a834418fb20c958dfaed003a24801ce18 --- /dev/null +++ b/akn/AllDownloaderBot/blacklistchat.py @@ -0,0 +1,262 @@ +# credits original: yukki music +# kurigram versions: latest +# code by @xpushz + +from pyrogram import * +from pyrogram.types import * +from pyrogram.errors import * +from akn.utils.logger import LOGS +from akn.utils.database import db + +@Client.on_message(filters.new_chat_members, group=2) +async def welcomecheck(client, message: Message): + chat_id = message.chat.id + if await db.get_alldlbot_is_blacklist_chat(client.me.id, chat_id): + return await client.leave_chat(chat_id) + return await client.send_message( + chat_id, + f"Thank you for using my bot: {client.me.first_name}" + ) + +@Client.on_message( + ~filters.scheduled + & filters.command(["addblacklist"]) + & ~filters.forwarded +) +async def blacklist_user(c, m): + is_sudo = await db.get_alldlbot_sudouser(c.me.id, m.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(m.from_user.id) + if not protect_own and not is_sudo: + return await m.reply_text("You are not allowed here.") + + if m.chat.type.value != "supergroup": + return await m.reply_text("You can only group public not private") + await db.update_alldlbot_broadcast_in_group(c.me.id, m.chat.id, "add") + user_id = None + if not m.reply_to_message: + if len(m.command) < 2: + return await m.reply_text( + "Reply to a user or pass a user_id to blacklist" + ) + try: + getuser = m.command[1] + except Exception as e: + return await m.reply_text(f"`{str(e)}`") + else: + getuser = m.reply_to_message.from_user.id + try: + user_id = (await c.get_users(getuser)).id + await db.add_alldlbot_blacklist_user(c.me.id, user_id) + await m.reply_text(f"Successfully blacklist `{user_id}` from bots.") + except Exception as e: + await m.reply_text(f"Error: {e}") + +@Client.on_message( + ~filters.scheduled + & filters.command(["rmblacklist"]) + & ~filters.forwarded +) +async def unblacklist_user(c, m): + is_sudo = await db.get_alldlbot_sudouser(c.me.id, m.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(m.from_user.id) + if not protect_own and not is_sudo: + return await m.reply_text("You are not allowed here.") + + if m.chat.type.value != "supergroup": + return await m.reply_text("You can only group public not private") + await db.update_alldlbot_broadcast_in_group(c.me.id, m.chat.id, "add") + user_id = None + if not m.reply_to_message: + if len(m.command) < 2: + return await m.reply_text( + "Reply to a user or pass a user_id to unblacklist." + ) + try: + getuser = m.command[1] + except Exception as e: + return await m.reply_text(f"`{str(e)}`") + else: + getuser = m.reply_to_message.from_user.id + try: + user_id = (await c.get_users(getuser)).id + await db.add_alldlbot_unblacklist_user(c.me.id, user_id) + await m.reply_text(f"Successfully removed blacklist `{user_id}` from bots.") + except Exception as e: + await m.reply_text(f"Error: {e}") + +@Client.on_message( + ~filters.scheduled + & filters.command(["addsudo"]) + & ~filters.forwarded +) +async def add_sudo_func(client, message: Message): + if message.chat.type.value != "supergroup": + return await message.reply_text("This command can only be used in supergroups.") + is_sudo = await db.get_alldlbot_sudouser(client.me.id, message.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(message.from_user.id) + if not protect_own and not is_sudo: + return await message.reply_text("You are not allowed here.") + if len(message.command) != 2: + return await message.reply_text("**Usage:**\n/addsudo [USER_ID]") + user_id = int(message.text.strip().split()[1]) + if await db.get_alldlbot_sudouser(client.me.id, user_id): + return await message.reply_text("User is already sudo.") + if user_id == client.me.id: + return await message.reply_text("You can't add yourself as sudo.") + update_sudo = await db.update_alldlbot_sudouser(client.me.id, user_id, "add") + if update_sudo: + await message.reply_text("User has been successfully added to sudo list") + else: + await message.reply_text("Something wrong happened.") + +@Client.on_message( + ~filters.scheduled + & filters.command(["delsudo"]) + & ~filters.forwarded +) +async def delc_sudo_func(client, message: Message): + if message.chat.type.value != "supergroup": + return await message.reply_text("This command can only be used in supergroups.") + is_sudo = await db.get_alldlbot_sudouser(client.me.id, message.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(message.from_user.id) + if not protect_own and not is_sudo: + return await message.reply_text("You are not allowed here.") + if len(message.command) != 2: + return await message.reply_text("**Usage:**\n/delsudo [USER_ID]") + user_id = int(message.text.strip().split()[1]) + if not await db.get_alldlbot_sudouser(client.me.id, user_id): + return await message.reply_text("User is not sudo.") + if user_id == client.me.id: + return await message.reply_text("You can't remove yourself as sudo.") + update_sudo = await db.update_alldlbot_sudouser(client.me.id, user_id, "remove") + if update_sudo: + await message.reply_text("User has been successfully removed from sudo list") + else: + await message.reply_text("Something wrong happened.") + +@Client.on_message( + ~filters.scheduled + & filters.command(["blacklistchat"]) + & ~filters.forwarded +) +async def blacklist_chat_func(client, message: Message): + if message.chat.type.value != "supergroup": + return await message.reply_text("This command can only be used in supergroups.") + is_sudo = await db.get_alldlbot_sudouser(client.me.id, message.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(message.from_user.id) + if not protect_own and not is_sudo: + return await message.reply_text("You are not allowed here.") + if len(message.command) != 2: + return await message.reply_text("**Usage:**\n/blacklistchat [CHAT_ID]") + chat_id = int(message.text.strip().split()[1]) + if await db.get_alldlbot_is_blacklist_chat(client.me.id, chat_id): + return await message.reply_text("Chat is already blacklisted.") + blacklisted = await db.add_alldlbot_blacklist_chat(client.me.id, chat_id) + if blacklisted: + await message.reply_text("Chat has been successfully blacklisted") + else: + await message.reply_text("Something wrong happened.") + try: + await client.leave_chat(chat_id) + except: + pass + +@Client.on_message( + ~filters.scheduled + & filters.command(["whitelistchat"]) + & ~filters.forwarded +) +async def white_funciton(client, message: Message): + if message.chat.type.value != "supergroup": + return await message.reply_text("This command can only be used in supergroups.") + is_sudo = await db.get_alldlbot_sudouser(client.me.id, message.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(message.from_user.id) + if not protect_own and not is_sudo: + return await message.reply_text("You are not allowed here.") + if len(message.command) != 2: + return await message.reply_text("**Usage:**\n/whitelistchat [CHAT_ID]") + chat_id = int(message.text.strip().split()[1]) + if not await db.get_alldlbot_is_blacklist_chat(client.me.id, chat_id): + return await message.reply_text("Chat is already whitelisted") + whitelisted = await db.alldlbot_whitelist_chat(client.me.id, chat_id) + if whitelisted: + return await message.reply_text("Chat has been successfully whitelisted") + await message.reply_text("Something wrong happened.") + +@Client.on_message( + ~filters.scheduled + & filters.command(["blacklistedchat"]) + & ~filters.forwarded +) +async def all_chats(client, message: Message): + if message.chat.type.value != "supergroup": + return await message.reply_text("This command can only be used in supergroups.") + is_sudo = await db.get_alldlbot_sudouser(client.me.id, message.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(message.from_user.id) + if not protect_own and not is_sudo: + return await message.reply_text("You are not allowed here.") + text = "**Blacklisted Chats:**\n\n" + j = 0 + for count, chat_id in enumerate(await db.get_alldlbot_blacklist_chat(client.me.id), 1): + try: + title = (await client.get_chat(chat_id)).title + except Exception: + title = "Private" + j = 1 + text += f"**{count}. {title}** [`{chat_id}`]\n" + if j == 0: + await message.reply_text("No Blacklisted Chats") + else: + await message.reply_text(text) + +@Client.on_message( + ~filters.scheduled + & filters.command(["listsudo"]) + & ~filters.forwarded +) +async def list_sudo_func(client, message: Message): + if message.chat.type.value != "supergroup": + return await message.reply_text("This command can only be used in supergroups.") + is_sudo = await db.get_alldlbot_sudouser(client.me.id, message.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(message.from_user.id) + if not protect_own and not is_sudo: + return await message.reply_text("You are not allowed here.") + text = "**List SudoUser:**\n\n" + j = 0 + for count, user_id in enumerate(await db.get_alldlbot_allsudouser(client.me.id), 1): + try: + title = (await client.get_users(user_id)).first_name + except Exception: + title = "Private" + j = 1 + text += f"**{count}. {title}** [`{user_id}`]\n" + if j == 0: + await message.reply_text("No List SudoUser") + else: + await message.reply_text(text) + +@Client.on_message( + ~filters.scheduled + & filters.command(["viewblacklistuser"]) + & ~filters.forwarded +) +async def view_blacklist_user_func(client, message: Message): + if message.chat.type.value != "supergroup": + return await message.reply_text("This command can only be used in supergroups.") + is_sudo = await db.get_alldlbot_sudouser(client.me.id, message.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(message.from_user.id) + if not protect_own and not is_sudo: + return await message.reply_text("You are not allowed here.") + text = "**Blacklisted Users:**\n\n" + j = 0 + for count, user_id in enumerate(await db.get_alldlbot_allblacklist_user(client.me.id), 1): + try: + title = (await client.get_users(user_id)).first_name + except Exception: + title = "Private" + j = 1 + text += f"**{count}. {title}** [`{user_id}`]\n" + if j == 0: + await message.reply_text("No Blacklisted Users") + else: + await message.reply_text(text) \ No newline at end of file diff --git a/akn/AllDownloaderBot/broadcast.py b/akn/AllDownloaderBot/broadcast.py new file mode 100755 index 0000000000000000000000000000000000000000..b18d615ee4b720ddceafcc272e2b0fb98b44caf2 --- /dev/null +++ b/akn/AllDownloaderBot/broadcast.py @@ -0,0 +1,110 @@ +# credits original: yukki music +# kurigram versions: latest +# code by @xpushz + +import time +import os +import asyncio +from datetime import datetime +from pyrogram import * +from pyrogram.types import * +from pyrogram.errors import * +from akn.utils.logger import LOGS +from akn.utils.database import db + +@Client.on_message( + ~filters.scheduled + & filters.command(["broadcast"]) + & ~filters.forwarded +) +async def braodcast_message(client, message): + global IS_BROADCASTING + if message.reply_to_message: + x = message.reply_to_message.id + y = message.chat.id + else: + if len(message.command) < 2: + return await message.reply_text("**Usage**:\n/broadcast [MESSAGE] or [Reply to a Message]") + query = message.text.split(None, 1)[1] + if "-pin" in query: + query = query.replace("-pin", "") + if "-nobot" in query: + query = query.replace("-nobot", "") + if "-pinloud" in query: + query = query.replace("-pinloud", "") + if "-user" in query: + query = query.replace("-user", "") + if query == "": + return await message.reply_text("Please provide some text to broadcast.") + + IS_BROADCASTING = True + + if "-nobot" not in message.text: + sent = 0 + pin = 0 + chats = [] + schats = await db.alldlbot_all_broadcast_group(client.me.id) + for chat in schats: + chats.append(int(chat)) + for i in chats: + try: + m = ( + await client.forward_messages(i, y, x) + if message.reply_to_message + else await client.send_message(i, text=query) + ) + if "-pin" in message.text: + try: + await m.pin(disable_notification=True) + pin += 1 + except Exception: + continue + elif "-pinloud" in message.text: + try: + await m.pin(disable_notification=False) + pin += 1 + except Exception: + continue + sent += 1 + except FloodWait as e: + flood_time = int(e.x) + if flood_time > 200: + continue + await asyncio.sleep(flood_time) + except Exception: + continue + try: + await message.reply_text( + f"Broadcasted Message In {sent} Chats with {pin} Pins from Bot" + ) + except: + pass + + if "-user" in message.text: + susr = 0 + served_users = [] + susers = await db.alldlbot_all_broadcast(client.me.id) + for user in susers: + served_users.append(int(user)) + for i in served_users: + try: + m = ( + await client.forward_messages(i, y, x) + if message.reply_to_message + else await client.send_message(i, text=query) + ) + susr += 1 + except FloodWait as e: + flood_time = int(e.x) + if flood_time > 200: + continue + await asyncio.sleep(flood_time) + except Exception: + pass + try: + await message.reply_text( + f"**Broadcasted Message to {susr} Users.**" + ) + except: + pass + IS_BROADCASTING = False \ No newline at end of file diff --git a/akn/AllDownloaderBot/main.py b/akn/AllDownloaderBot/main.py new file mode 100755 index 0000000000000000000000000000000000000000..5d92a185fe70ff42a7aa1cf4eed6cddc96f89bde --- /dev/null +++ b/akn/AllDownloaderBot/main.py @@ -0,0 +1,1262 @@ +# All credits to @xpushz +# lu mau kanger kah pasti noob aja + +import time +import requests +import os +import re +import httpx +import aiofiles +import hashlib +import urllib.parse +import asyncio +from pyrogram import * +from pyrogram.enums import * +from pyrogram import Client, filters +from pyrogram.types import * +from pyrogram.errors import * + +from akn.utils.logger import LOGS +from akn.utils.scripts import progress +from youtube_search import YoutubeSearch +from yt_dlp import YoutubeDL + +from akn.utils.database import db +from akn.utils.driver import YoutubeDriver +from akn.utils.formatter import secs_to_mins + +import akenoai as js + +link_storage = {} +storage = {} + +custom_loading = "🗿" +TIKTOK_WEB = "https://www.tikwm.com" + +OWNER_BOT_ID = 8109052455 + +COMMAND = """ +**📥 Social Media Downloader Commands** + +**🔗 Direct Link Downloaders** +- `/fbdl` – Download Facebook videos. +- `/igdl` – Download Instagram videos/reels. +- `/twdl` – Download Twitter/X videos. +- `/ttdl` – Download TikTok videos. +- `/alldl` – Download Facebook, Instagram, Tiktok, Twitter(required cookies) etc videos. +- `/teraboxdl` – Download Terabox files (v1). +- `/terabox2dl` – Download Terabox files (v2). + +**🎵 YouTube Tools** +- `/ytv` – Download YouTube videos in **MP4** format. +- `/yta` – Extract audio from YouTube videos in **MP3** format. +- `/ytva` – Search & download YouTube videos as **MP4**. +- `/ytsa` – Search & download YouTube audio as **MP3**. +- `/ytlink` – Search for YouTube videos. +""" + +@Client.on_callback_query(filters.regex("^cclose")) +async def cb_cclose(client, query): + await query.message.delete() + +@Client.on_callback_query(filters.regex("^author_cmd")) +async def cb_author_command(client, query): + is_sudo = await db.get_alldlbot_sudouser(client.me.id, query.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(query.from_user.id) + if not protect_own and not is_sudo: + return await query.answer("You are not allowed here.", True) + + author_commands = """ +**🔐 Owner-Only Commands** + +**📌 Channel & User Management:** +- `/addjoin` – Enable auto **force-subscribe** to a channel. +- `/addblacklist` – Ban a user from using bot commands. +- `/addsudo` – Add a user to the sudo list. +- `/delsudo` – Remove a user from the sudo list. +- `/listsudo` – View the list of sudo users. +- `/rmblacklist` – Unban a blacklisted user. +- `/blacklistchat` – Block a chat from using the bot. +- `/viewblacklistuser` – View the list of blacklisted users. +- `/whitelistchat` – Unblock a chat. +- `/blacklistedchat` – View blacklisted chats. + +**📊 Stats & Maintenance:** +- `/stats` – View user statistics. +- `/rmdup` – Remove duplicate user entries. +- `/broadcast` – Send a message to all users. + +**⚙️ Bot Settings:** +- `/nobutton` – Toggle **ON/OFF** the `/start` button. +- `/setpic` – Change the bot's display picture (resend if needed). +- `/delpic` – Remove bot display picture (resend if needed). +""" + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Close", + callback_data="cclose" + ) + ] + ] + ) + await query.edit_message_text( + text=author_commands, + reply_markup=keyboard_back + ) + +@Client.on_message( + ~filters.scheduled + & filters.command(["start"]) + & filters.private + & ~filters.forwarded +) +async def startbot(c, m): + if await db.get_alldlbot_is_blacklist_user(c.me.id, m.from_user.id): + return + buttons = [ + [ + InlineKeyboardButton( + text="Developer", + url=f"https://t.me/xtdevs" + ), + InlineKeyboardButton( + text="Channel", + url='https://t.me/RendyProjects' + ), + ], + [ + InlineKeyboardButton( + text="Author Commands", + callback_data='author_cmd' + ) + ] + ] + buttons_start_in_group = [ + [ + InlineKeyboardButton( + text="Add to your group", + url=f"https://t.me/{c.me.username}?startgroup=true&admin=manage_chat+change_info+post_messages+edit_messages+delete_messages+invite_users+restrict_members+pin_messages+promote_members+manage_video_chats+anonymous=false" + ) + ], + [ + InlineKeyboardButton( + text="Author Commands", + callback_data='author_cmd' + ) + ] + ] + user_now = await db.get_alldlbot_by_no_button(c.me.id) + reply_markup = InlineKeyboardMarkup(buttons_start_in_group) if user_now else InlineKeyboardMarkup(buttons) + try: + await db.update_alldlbot_broadcast(c.me.id, m.from_user.id, "add") + is_pic, catbox_link = await db.get_pic_in_allbot(c.me.id) + if is_pic and catbox_link: + return await m.reply_photo( + photo=catbox_link, + caption=COMMAND, + reply_markup=reply_markup + ) + return await m.reply_text( + text=COMMAND, + disable_web_page_preview=True, + reply_markup=reply_markup + ) + except Exception as e: + await m.reply_text(f"Error: {e}") + +class Tiktok: + @staticmethod + async def download(api_name, url): + response = requests.get("{}/api/?url={}".format(api_name, url)) + if response.status_code != 200: + return "Error Response limits" + data_json = response.json() + author_tiktok = data_json["data"]["author"].get("nickname") or "Unknown" + play_tiktok = data_json["data"].get("play") + music_tiktok = data_json["data"]["music_info"].get("play") + return [ + play_tiktok, + music_tiktok, + author_tiktok + ] + +def is_tiktok_url(url): + pattern = r"(https?)://(vt|www)\.tiktok\.com/(\w+)" + match = re.search(pattern, url) + return bool(match) + +def generate_callback_data(user_id, query): + identifier = hashlib.md5(query.encode()).hexdigest() + callback_data = f"audiodownload_{user_id}_{identifier}" + link_storage[callback_data] = query + return callback_data + +@Client.on_callback_query(filters.regex("^audiodownload_")) +async def callback_button(client: Client, cb: CallbackQuery): + try: + data = cb.data + query = link_storage.get(data) + if query: + response = await Tiktok.download(TIKTOK_WEB, query) + await client.send_audio(cb.message.chat.id, response[1]) + await cb.answer("Audio sent successfully!") + else: + await cb.answer("Invalid or expired link.", show_alert=True) + except Exception as e: + await cb.answer(f"Error: {str(e)}", show_alert=True) + +@Client.on_message( + ~filters.scheduled + & filters.command(["stats"]) + & ~filters.forwarded +) +async def statscmd(c, m): + is_sudo = await db.get_alldlbot_sudouser(c.me.id, m.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(m.from_user.id) + if not protect_own and not is_sudo: + return await m.reply_text("You are not allowed here.") + try: + if m.chat.type.value != "supergroup": + return await m.reply_text("You can only group public not private") + await db.update_alldlbot_broadcast_in_group(c.me.id, m.chat.id, "add") + total_bl_users = await db.alldlbot_blacklist_stats(c.me.id) + total_users = await db.alldlbot_broadcast_stats(c.me.id) + await m.reply_text(f"**Total Users:** `{total_users}`\n**Total Blacklist Users:** `{total_bl_users}`") + except Exception as e: + await m.reply_text(f"Error: {e.MESSAGE}") + +@Client.on_message( + ~filters.scheduled + & filters.command(["delpic"]) + & ~filters.forwarded +) +async def delpicincatbox(c, m): + is_sudo = await db.get_alldlbot_sudouser(c.me.id, m.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(m.from_user.id) + if not protect_own and not is_sudo: + return await m.reply_text("You are not allowed here.") + mode = m.text.split(" ", 1)[1] if len(m.command) > 1 else None + if not mode: + return await m.reply_text("Example: `/delpic yes`") + try: + if mode == "yes": + _, catbox_link = await db.get_pic_in_allbot(c.me.id) + if not catbox_link: + return await m.reply_text("Not found pic") + await db.set_pic_in_allbot(c.me.id, catbox_link, False) + await m.reply_text(f"Successfully removed pic `{catbox_link}`.") + else: + await m.reply_text(f"Invalid command: /delpic yes") + except Exception as e: + await m.reply_text(f"Error: {e.MESSAGE}") + +@Client.on_message( + ~filters.scheduled + & filters.command(["setpic"]) + & ~filters.forwarded +) +async def setpicincatbox(c, m): + is_sudo = await db.get_alldlbot_sudouser(c.me.id, m.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(m.from_user.id) + if not protect_own and not is_sudo: + return await m.reply_text("You are not allowed here.") + link = m.text.split(" ", 1)[1] if len(m.command) > 1 else None + if not link: + return await m.reply_text("Example: `/setpic https://files.catbox.moe/y93h4b.jpg`") + if not link.startswith("https://files.catbox.moe/"): + return await m.reply_text("Invalid Link") + try: + await db.set_pic_in_allbot(c.me.id, link, True) + await m.reply_text(f"Successfully added pic set `{link}`.") + except Exception as e: + await m.reply_text(f"Error: {e.MESSAGE}") + +@Client.on_message( + ~filters.scheduled + & filters.command(["rmdup"]) + & ~filters.forwarded +) +async def duplicate_remove(c, m): + is_sudo = await db.get_alldlbot_sudouser(c.me.id, m.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(m.from_user.id) + if not protect_own and not is_sudo: + return await m.reply_text("You are not allowed here.") + if m.chat.type.value != "supergroup": + return await m.reply_text("You can only group public not private") + await db.update_alldlbot_broadcast_in_group(c.me.id, m.chat.id, "add") + user_id = None + if not m.reply_to_message: + if len(m.command) < 2: + return await m.reply_text( + "Reply to a user or pass a user_id to remvoe duplicate" + ) + try: + getuser = m.command[1] + except Exception as e: + return await m.reply_text(f"`{str(e)}`") + else: + getuser = m.reply_to_message.from_user.id + try: + user_id = (await c.get_users(getuser)).id + await db.update_alldlbot_broadcast(c.me.id, user_id, "remove") + await m.reply_text(f"Successfully remove duplicate `{user_id}` from bots.") + except Exception as e: + await m.reply_text(f"Error: {e.MESSAGE}") + +@Client.on_message( + ~filters.scheduled + & filters.command(["addjoin"]) + & ~filters.forwarded +) +async def auto_force_sub(client: Client, message: Message): + protect_own = await db.get_alldlbot_by_user_id(message.from_user.id) + if not protect_own: + return await message.reply_text("You are not allowed to add a force sub.") + + if len(message.command) < 2: + return await message.reply_text("Please provide a channel username or ID.") + + channel = message.command[1] + await db.add_forcesub_only_bot(client.me.id, channel) + await message.reply_text("Successfully added to force sub.") + +@Client.on_message( + ~filters.scheduled + & filters.command(["nobutton"]) + & ~filters.forwarded +) +async def mode_button(client, message: Message): + is_sudo = await db.get_alldlbot_sudouser(client.me.id, message.from_user.id) + protect_own = await db.get_alldlbot_by_user_id(message.from_user.id) + if not protect_own and not is_sudo: + return await m.reply_text("You are not allowed here.") # type: ignore + + if len(message.command) < 2: + return await message.reply_text(f"**Please provide a cmd /nobutton on/off to start button disabled or enabled") + + cmd = message.command[1].lower().strip() + if cmd in ["on", "yes"]: + await db.add_alldlbot_by_no_button(client.me.id, True) + await message.reply_text(f"**Button disabled now!**") + elif cmd in ["off", "no"]: + await db.add_alldlbot_by_no_button(client.me.id, False) + await message.reply_text(f"**Button enabled now!**") + +@Client.on_message( + ~filters.scheduled + & filters.command(["ttdl"]) + & ~filters.forwarded +) +async def tiktok_downloader(client: Client, message: Message): + user_id = message.from_user.id + if await db.get_alldlbot_is_blacklist_user(client.me.id, user_id): + return + if message.chat.type.value != "supergroup": + return await message.reply_text("You can only group public not private") + await db.update_alldlbot_broadcast_in_group(client.me.id, message.chat.id, "add") + user_name = message.from_user.first_name + nn = "[" + user_name + "](tg://user?id=" + str(user_id) + ")" + if not await db.get_forcesub_only_bot(client.me.id): + return await message.reply_text("This is the command /addjoin username channel and becomes admin on the channel") + update_channel = await db.get_forcesub_only_bot(client.me.id) + if update_channel: + try: + user = await client.get_chat_member(update_channel, user_id) + if user.status == ChatMemberStatus.BANNED: + await client.send_message( + message.chat.id, + text=f"**❌ {nn} anda telah di blokir dari grup dukungan**", + disable_web_page_preview=True, + ) + return + except UserNotParticipant: + await client.send_message( + message.chat.id, + text=f"**👋🏻 Halo {nn}\nᴜɴᴛᴜᴋ ᴍᴇɴɢʜɪɴᴅᴀʀɪ ᴘᴇɴɢɢᴜɴᴀᴀɴ ʏᴀɴɢ ʙᴇʀʟᴇʙɪʜᴀɴ ʙᴏᴛ ɪɴɪ ᴅɪ ᴋʜᴜsᴜsᴋᴀɴ ᴜɴᴛᴜᴋ ʏᴀɴɢ sᴜᴅᴀʜ ᴊᴏɪɴ ᴅɪ ᴄʜᴀɴɴᴇʟ ᴋᴀᴍɪ​!**", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Jᴏɪɴ Cʜᴀɴɴᴇʟ Dᴜʟᴜ", + url=f"https://t.me/{update_channel}", + ) + ] + ] + ), + ) + except ChatAdminRequired: + return await message.reply_text("Chat admins Required: before /addjoin username without @ and add bot to your channel as admin") + return + query_url = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + if not query_url: + return await message.reply_text("?") + if not is_tiktok_url(query_url): + return await message.reply_text("Invalid link") + callback_data = generate_callback_data(message.from_user.id, query_url) + keyboard = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Audio Download", + callback_data=callback_data + ) + ] + ] + ) + try: + dll = await message.reply_text("Processing....") + response = await Tiktok.download(TIKTOK_WEB, query_url) + await message.reply_video( + response[0], + reply_markup=keyboard, + disable_notification=True + ) + await dll.delete() + except Exception as e: + LOGS.info(str(e)) + await dll.delete() + await message.reply_text(f"Error: {str(e)}") + +async def TeraboxDL(url): + try: + headers = {"x-api-key": os.environ.get("AKENOX_KEY")} + async with httpx.AsyncClient() as clientv: + response = await clientv.get( + f"https://randydev-ryu-js.hf.space/api/v1/dl/terabox-v4?url={url}", + headers=headers + ) + response_json = response.json() + data = response_json.get("message", {}).get("resuls", "") + + pattern = r"#EXTINF:\d+,\s*(https[^\s]+)" + matches = re.findall(pattern, data) + + return { + "video_url": matches[0].split("?ulink=")[1] if matches else None, + "video_url_2": matches[1].split("?ulink=")[1] if len(matches) > 1 else None + } + + except Exception as e: + return {"error": str(e)} + +async def download_m3u8(url, save_path="terabox.mp4"): + api_url = f"https://teraboxdownloaderonline.com/api/download-m3u8?terabox_link={url}" + + async with httpx.AsyncClient() as clientv: + response = await clientv.get(api_url) + if response.status_code != 200: + return None + with open(save_path, "wb") as file: + file.write(response.content) + return save_path + +@Client.on_message( + ~filters.scheduled + & filters.command(["terabox2dl"]) + & ~filters.forwarded +) +async def terabox2_cmd(client: Client, message: Message): + user_id = message.from_user.id + user_name = message.from_user.first_name + nn = f"[{user_name}](tg://user?id={user_id})" + + update_channel = await db.get_forcesub_only_bot(client.me.id) + if update_channel: + try: + user = await client.get_chat_member(update_channel, user_id) + if user.status == ChatMemberStatus.BANNED: + return await message.reply_text(f"❌ {nn} Anda telah diblokir dari grup dukungan.") + except UserNotParticipant: + return await message.reply_text( + f"👋🏻 Halo {nn}, Anda perlu join channel kami untuk menggunakan bot ini.", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("Join Channel", url=f"https://t.me/{update_channel}")] + ]) + ) + + link = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + if not link: + return await message.reply_text("Silakan masukkan link Terabox v2.") + + pro = await message.reply_text("🚀 **Processing...**") + + mp4_file = await download_m3u8(link) + if not mp4_file: + return await pro.edit_text("❌ Gagal mendapatkan file mp4.") + + upload_text = "**⬆️ Uploading video...**" + thumb_path = "terabox.jpg" + + async with httpx.AsyncClient() as clientv: + async with clientv.stream("GET", "https://images3.memedroid.com/images/UPLOADED822/63c5a9ca185df.jpeg") as thumb_response: + async with aiofiles.open(thumb_path, "wb") as file: + await file.write(await thumb_response.aread()) + + await pro.edit_text(upload_text) + await message.reply_video( + mp4_file, + caption=f"• Powered by {client.me.mention}", + thumb=thumb_path, + progress=progress, + progress_args=( + pro, + time.time(), + "⬆️ Uploading video...." + ) + ) + os.remove(thumb_path) + os.remove(mp4_file) + await pro.delete() + + +@Client.on_message( + ~filters.scheduled & filters.command(["teraboxdl"]) & ~filters.forwarded +) +async def terabox_cmd(client: Client, message): + user_id = message.from_user.id + if await db.get_alldlbot_is_blacklist_user(client.me.id, user_id): + return + + user_name = message.from_user.first_name + nn = f"[{user_name}](tg://user?id={user_id})" + + update_channel = await db.get_forcesub_only_bot(client.me.id) + if update_channel: + try: + user = await client.get_chat_member(update_channel, user_id) + if user.status == ChatMemberStatus.BANNED: + return await message.reply_text(f"❌ {nn}, Anda telah diblokir dari grup dukungan.") + except UserNotParticipant: + return await message.reply_text( + f"👋🏻 Halo {nn}, untuk menggunakan bot ini, silakan join channel kami!", + reply_markup=InlineKeyboardMarkup( + [[InlineKeyboardButton("Join Channel", url=f"https://t.me/{update_channel}")]] + ), + ) + except ChatAdminRequired: + return await message.reply_text("Chat admin diperlukan: /addjoin username tanpa @ dan tambahkan bot ke channel sebagai admin.") + + if len(message.command) < 2: + return await message.reply_text("❌ Harap masukkan link untuk Terabox Downloader.") + + link = message.text.split(" ", 1)[1] + pro = await message.reply_text("⏳ Processing...") + + try: + response = await TeraboxDL(link) + if "error" in response or not response["video_url_2"]: + return await pro.edit_text("❌ Error: Gagal mendapatkan URL video.") + + video_url = urllib.parse.unquote(response["video_url_2"]) + video_path = "terabox.mp4" + thumb_path = "terabox.jpg" + + async with httpx.AsyncClient() as clientv: + async with clientv.stream("GET", video_url) as vid_response: + if vid_response.status_code != 200: + return await pro.edit_text("❌ Error saat mengunduh video.") + + async with aiofiles.open(video_path, "wb") as file: + async for chunk in vid_response.aiter_bytes(): + await file.write(chunk) + + async with clientv.stream("GET", "https://images3.memedroid.com/images/UPLOADED822/63c5a9ca185df.jpeg") as thumb_response: + async with aiofiles.open(thumb_path, "wb") as file: + await file.write(await thumb_response.aread()) + + await pro.edit_text("⬆️ Uploading video...") + await message.reply_video( + video_path, + caption=f"• Powered by {client.me.mention}", + thumb=thumb_path, + progress=progress, + progress_args=( + pro, + time.time(), + "⬆️ Uploading video...." + ) + ) + + await pro.delete() + os.remove(video_path) + os.remove(thumb_path) + + except Exception as e: + await pro.edit_text(f"❌ Error: {str(e)}") + +@Client.on_message( + ~filters.scheduled + & filters.command(["twdl"]) + & ~filters.forwarded +) +async def twdl_cmd(client: Client, message: Message): + user_id = message.from_user.id + if await db.get_alldlbot_is_blacklist_user(client.me.id, user_id): + return + if message.chat.type.value != "supergroup": + return await message.reply_text("You can only group public not private") + await db.update_alldlbot_broadcast_in_group(client.me.id, message.chat.id, "add") + user_name = message.from_user.first_name + nn = "[" + user_name + "](tg://user?id=" + str(user_id) + ")" + if not await db.get_forcesub_only_bot(client.me.id): + return await message.reply_text("This is the command /addjoin username channel and becomes admin on the channel") + update_channel = await db.get_forcesub_only_bot(client.me.id) + if update_channel: + try: + user = await client.get_chat_member(update_channel, user_id) + if user.status == ChatMemberStatus.BANNED: + await client.send_message( + message.chat.id, + text=f"**❌ {nn} anda telah di blokir dari grup dukungan**", + disable_web_page_preview=True, + ) + return + except UserNotParticipant: + await client.send_message( + message.chat.id, + text=f"**👋🏻 Halo {nn}\nᴜɴᴛᴜᴋ ᴍᴇɴɢʜɪɴᴅᴀʀɪ ᴘᴇɴɢɢᴜɴᴀᴀɴ ʏᴀɴɢ ʙᴇʀʟᴇʙɪʜᴀɴ ʙᴏᴛ ɪɴɪ ᴅɪ ᴋʜᴜsᴜsᴋᴀɴ ᴜɴᴛᴜᴋ ʏᴀɴɢ sᴜᴅᴀʜ ᴊᴏɪɴ ᴅɪ ᴄʜᴀɴɴᴇʟ ᴋᴀᴍɪ​!**", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Jᴏɪɴ Cʜᴀɴɴᴇʟ Dᴜʟᴜ", + url=f"https://t.me/{update_channel}", + ) + ] + ] + ), + ) + return + except ChatAdminRequired: + return await message.reply_text("Chat admins Required: before /addjoin username without @ and add bot to your channel as admin") + + link = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + pro = await message.reply_text("Processing.....") + if not link: + return await pro.edit_text("Please link for Twitter.") + urls = re.sub(r"(https?:\/\/)(?:www\.)?x\.com", r"\1twitter.com", link) + if not urls: + return await pro.edit_text("invalid link.") + try: + response = await js.fetch_and_extract_urls( + f"https://snapdownloader.com/tools/twitter-video-downloader/download?url={urls}", + href_url=r"https://video", + return_unsafe_href=True + ) + upload_text = f"**⬆️ 𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 video ...**" + await pro.edit_text(upload_text) + await message.reply_video( + response[0], + caption=f"• Powered by {client.me.mention}", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text + ) + ) + await pro.delete() + except Exception as e: + LOGS.error(str(e)) + await pro.edit_text("Error: Try invalid") + +@Client.on_message( + ~filters.scheduled + & filters.command(["fbdl"]) + & ~filters.forwarded +) +async def fbdl_cmd(client: Client, message: Message): + user_id = message.from_user.id + if await db.get_maintance(): + return await message.reply_text("Bot is in maintance mode. By @xpushz") + + if await db.get_alldlbot_is_blacklist_user(client.me.id, user_id): + return + + if message.chat.type.value != "supergroup": + return await message.reply_text("You can only group public not private") + await db.update_alldlbot_broadcast_in_group(client.me.id, message.chat.id, "add") + user_name = message.from_user.first_name + nn = "[" + user_name + "](tg://user?id=" + str(user_id) + ")" + if not await db.get_forcesub_only_bot(client.me.id): + return await message.reply_text("This is the command /addjoin username channel and becomes admin on the channel") + update_channel = await db.get_forcesub_only_bot(client.me.id) + if update_channel: + try: + user = await client.get_chat_member(update_channel, user_id) + if user.status == ChatMemberStatus.BANNED: + await client.send_message( + message.chat.id, + text=f"**❌ {nn} anda telah di blokir dari grup dukungan**", + disable_web_page_preview=True, + ) + return + except UserNotParticipant: + await client.send_message( + message.chat.id, + text=f"**👋🏻 Halo {nn}\nᴜɴᴛᴜᴋ ᴍᴇɴɢʜɪɴᴅᴀʀɪ ᴘᴇɴɢɢᴜɴᴀᴀɴ ʏᴀɴɢ ʙᴇʀʟᴇʙɪʜᴀɴ ʙᴏᴛ ɪɴɪ ᴅɪ ᴋʜᴜsᴜsᴋᴀɴ ᴜɴᴛᴜᴋ ʏᴀɴɢ sᴜᴅᴀʜ ᴊᴏɪɴ ᴅɪ ᴄʜᴀɴɴᴇʟ ᴋᴀᴍɪ​!**", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Jᴏɪɴ Cʜᴀɴɴᴇʟ Dᴜʟᴜ", + url=f"https://t.me/{update_channel}", + ) + ] + ] + ), + ) + return + except ChatAdminRequired: + return await message.reply_text("Chat admins Required: before /addjoin username without @ and add bot to your channel as admin") + + link = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + pro = await message.reply_text("Processing.....") + if not link: + return await pro.edit_text("Please link for facebook.") + if not link.startswith("https://www.facebook.com/"): + return await pro.edit_text("invalid link.") + try: + response = await js.AkenoXJs( + js.types.DifferentAPIDefault() + ).connect().downloader.create( + "fb", + params_data={"url": link}, + is_obj=True + ) + upload_text = f"**⬆️ 𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 video ...**" + await pro.edit_text(upload_text) + await message.reply_video( + response.results.video[0].url, + caption=f"• Powered by {client.me.mention}", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text + ) + ) + await pro.delete() + except Exception as e: + LOGS.error(str(e)) + await pro.edit_text("Error: Try invalid") + +@Client.on_message( + ~filters.scheduled + & filters.command(["igdl"]) + & ~filters.forwarded +) +async def igdl_cmd(client: Client, message: Message): + user_id = message.from_user.id + if await db.get_maintance(): + return await message.reply_text("Bot is in maintance mode. By @xpushz") + + if await db.get_alldlbot_is_blacklist_user(client.me.id, user_id): + return + if message.chat.type.value != "supergroup": + return await message.reply_text("You can only group public not private") + await db.update_alldlbot_broadcast_in_group(client.me.id, message.chat.id, "add") + user_name = message.from_user.first_name + nn = "[" + user_name + "](tg://user?id=" + str(user_id) + ")" + if not await db.get_forcesub_only_bot(client.me.id): + return await message.reply_text("This is the command /addjoin username channel and becomes admin on the channel") + update_channel = await db.get_forcesub_only_bot(client.me.id) + if update_channel: + try: + user = await client.get_chat_member(update_channel, user_id) + if user.status == ChatMemberStatus.BANNED: + await client.send_message( + message.chat.id, + text=f"**❌ {nn} anda telah di blokir dari grup dukungan**", + disable_web_page_preview=True, + ) + return + except UserNotParticipant: + await client.send_message( + message.chat.id, + text=f"**👋🏻 Halo {nn}\nᴜɴᴛᴜᴋ ᴍᴇɴɢʜɪɴᴅᴀʀɪ ᴘᴇɴɢɢᴜɴᴀᴀɴ ʏᴀɴɢ ʙᴇʀʟᴇʙɪʜᴀɴ ʙᴏᴛ ɪɴɪ ᴅɪ ᴋʜᴜsᴜsᴋᴀɴ ᴜɴᴛᴜᴋ ʏᴀɴɢ sᴜᴅᴀʜ ᴊᴏɪɴ ᴅɪ ᴄʜᴀɴɴᴇʟ ᴋᴀᴍɪ!**", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Jᴏɪɴ Cʜᴀɴɴᴇʟ Dᴜʟᴜ", + url=f"https://t.me/{update_channel}", + ) + ] + ] + ), + ) + return + except ChatAdminRequired: + return await message.reply_text("Chat admins Required: before /addjoin username without @ and add bot to your channel as admin") + + link = message.text.split(" ", 1)[1] if len(message.command) > 1 else None + pro = await message.reply_text("Processing.....") + if not link: + return await pro.edit_text("Please link for Instagram.") + if not link.startswith("https://www.instagram.com/"): + return await pro.edit_text("invalid link.") + try: + params = {"link": link, "version": "v4"} + response = requests.get(f"https://learn.maiysacollection.com/api/v1/dl/ig/custom", params=params).json() + if response["response"]["results"] is None: + return await pro.edit_text("Not Found.") + upload_text = f"**⬆️ 𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 video ...**" + await pro.edit_text(upload_text) + await message.reply_video( + response["response"]["results"]["results"][0]["variants"][0]["url"], + caption=f"• Powered by {client.me.mention}", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text + ) + ) + await pro.delete() + except Exception as e: + LOGS.error(str(e)) + await pro.edit_text("Error: Try invalid") + +async def input_user(message: Message) -> str: + """Get the input from the user""" + if len(message.command) < 2: + output = "" + else: + try: + output = message.text.split(" ", 1)[1].strip() or "" + except IndexError: + output = "" + return output + +@Client.on_message( + ~filters.scheduled + & filters.command(["ytsa"]) + & ~filters.forwarded +) +async def youtube_search_audio(client: Client, message: Message): + user_id = message.from_user.id + if await db.get_alldlbot_is_blacklist_user(client.me.id, user_id): + return + user_name = message.from_user.first_name + nn = "[" + user_name + "](tg://user?id=" + str(user_id) + ")" + if not await db.get_forcesub_only_bot(client.me.id): + return await message.reply_text("This is the command /addjoin username channel and becomes admin on the channel") + update_channel = await db.get_forcesub_only_bot(client.me.id) + if update_channel: + try: + user = await client.get_chat_member(update_channel, user_id) + if user.status == ChatMemberStatus.BANNED: + await client.send_message( + message.chat.id, + text=f"**❌ {nn} anda telah di blokir dari grup dukungan**", + disable_web_page_preview=True, + ) + return + except UserNotParticipant: + await client.send_message( + message.chat.id, + text=f"**👋🏻 Halo {nn}\nᴜɴᴛᴜᴋ ᴍᴇɴɢʜɪɴᴅᴀʀɪ ᴘᴇɴɢɢᴜɴᴀᴀɴ ʏᴀɴɢ ʙᴇʀʟᴇʙɪʜᴀɴ ʙᴏᴛ ɪɴɪ ᴅɪ ᴋʜᴜsᴜsᴋᴀɴ ᴜɴᴛᴜᴋ ʏᴀɴɢ sᴜᴅᴀʜ ᴊᴏɪɴ ᴅɪ ᴄʜᴀɴɴᴇʟ ᴋᴀᴍɪ​!**", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Jᴏɪɴ Cʜᴀɴɴᴇʟ Dᴜʟᴜ", + url=f"https://t.me/{update_channel}", + ) + ] + ] + ), + ) + return + except ChatAdminRequired: + return await message.reply_text(f"Chat admins Required: before /addjoin username without @ and add bot to your channel as admin") + + if len(message.command) < 2: + return await message.reply_text( + "Give a valid youtube search to download audio." + ) + query = await input_user(message) + results = YoutubeSearch(query, max_results=5).to_dict() + watch = results[0]["url_suffix"] + url_suffix = watch.split("/")[1] + okk = f"https://youtube.com/{url_suffix}" + pro = await message.reply_text("Checking ...") + status, url = YoutubeDriver.check_url(okk) + if not status: + return await pro.edit_text(url) + if client.me.is_premium: + await pro.edit_text(f"{custom_loading}__Downloading audio ...__") + else: + await pro.edit_text(f"__Downloading audio ...__") + try: + with YoutubeDL(YoutubeDriver.song_options()) as ytdl: + yt_data = ytdl.extract_info(url, False) + yt_file = ytdl.prepare_filename(yt_data) + ytdl.process_info(yt_data) + if client.me.is_premium: + upload_text = f"**{custom_loading}𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + else: + upload_text = f"**𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + await pro.edit_text(upload_text) + response = requests.get(f"https://i.ytimg.com/vi/{yt_data['id']}/hqdefault.jpg") + with open(f"{yt_file}.jpg", "wb") as f: + f.write(response.content) + await message.reply_audio( + f"{yt_file}.mp3", + caption=f"**🎧 𝖳𝗂𝗍𝗅𝖾:** {yt_data['title']} \n\n**👀 𝖵𝗂𝖾𝗐𝗌:** `{yt_data['view_count']}` \n**⌛ 𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{secs_to_mins(int(yt_data['duration']))}`", + duration=int(yt_data["duration"]), + performer="[Akeno UB]", + title=yt_data["title"], + thumb=f"{yt_file}.jpg", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text, + ), + ) + await pro.delete() + except Exception as e: + return await pro.edit_text(f"**🍀 Audio not Downloaded:** `{e}`") + try: + os.remove(f"{yt_file}.jpg") + os.remove(f"{yt_file}.mp3") + except: + pass + +@Client.on_message( + ~filters.scheduled + & filters.command(["yta"]) + & ~filters.forwarded +) +async def youtube_audio(client: Client, message: Message): + user_id = message.from_user.id + if await db.get_alldlbot_is_blacklist_user(client.me.id, user_id): + return + user_name = message.from_user.first_name + nn = "[" + user_name + "](tg://user?id=" + str(user_id) + ")" + if not await db.get_forcesub_only_bot(client.me.id): + return await message.reply_text("This is the command /addjoin username channel and becomes admin on the channel") + update_channel = await db.get_forcesub_only_bot(client.me.id) + if update_channel: + try: + user = await client.get_chat_member(update_channel, user_id) + if user.status == ChatMemberStatus.BANNED: + await client.send_message( + message.chat.id, + text=f"**❌ {nn} anda telah di blokir dari grup dukungan**", + disable_web_page_preview=True, + ) + return + except UserNotParticipant: + await client.send_message( + message.chat.id, + text=f"**👋🏻 Halo {nn}\nᴜɴᴛᴜᴋ ᴍᴇɴɢʜɪɴᴅᴀʀɪ ᴘᴇɴɢɢᴜɴᴀᴀɴ ʏᴀɴɢ ʙᴇʀʟᴇʙɪʜᴀɴ ʙᴏᴛ ɪɴɪ ᴅɪ ᴋʜᴜsᴜsᴋᴀɴ ᴜɴᴛᴜᴋ ʏᴀɴɢ sᴜᴅᴀʜ ᴊᴏɪɴ ᴅɪ ᴄʜᴀɴɴᴇʟ ᴋᴀᴍɪ​!**", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Jᴏɪɴ Cʜᴀɴɴᴇʟ Dᴜʟᴜ", + url=f"https://t.me/{update_channel}", + ) + ] + ] + ), + ) + return + except ChatAdminRequired: + return await message.reply_text("Chat admins Required: before /addjoin username without @ and add bot to your channel as admin") + + if len(message.command) < 2: + return await message.reply_text( + "Give a valid youtube link to download audio." + ) + query = await input_user(message) + pro = await message.reply_text("Checking ...") + status, url = YoutubeDriver.check_url(query) + if not status: + return await pro.edit_text(url) + if client.me.is_premium: + await pro.edit_text(f"{custom_loading}__Downloading audio ...__") + else: + await pro.edit_text(f"__Downloading audio ...__") + try: + with YoutubeDL(YoutubeDriver.song_options()) as ytdl: + yt_data = ytdl.extract_info(url, False) + yt_file = ytdl.prepare_filename(yt_data) + ytdl.process_info(yt_data) + if client.me.is_premium: + upload_text = f"**{custom_loading}𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + else: + upload_text = f"**𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + await pro.edit_text(upload_text) + response = requests.get(f"https://i.ytimg.com/vi/{yt_data['id']}/hqdefault.jpg") + with open(f"{yt_file}.jpg", "wb") as f: + f.write(response.content) + await message.reply_audio( + f"{yt_file}.mp3", + caption=f"**🎧 𝖳𝗂𝗍𝗅𝖾:** {yt_data['title']} \n\n**👀 𝖵𝗂𝖾𝗐𝗌:** `{yt_data['view_count']}` \n**⌛ 𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{secs_to_mins(int(yt_data['duration']))}`", + duration=int(yt_data["duration"]), + performer="[Akeno UB]", + title=yt_data["title"], + thumb=f"{yt_file}.jpg", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text, + ), + ) + await pro.delete() + except Exception as e: + return await pro.edit_text(f"**🍀 Audio not Downloaded:** `{e}`") + try: + os.remove(f"{yt_file}.jpg") + os.remove(f"{yt_file}.mp3") + except: + pass + +@Client.on_message( + ~filters.scheduled + & filters.command(["ytva"]) + & ~filters.forwarded +) +async def ytvideo_search(client: Client, message: Message): + user_id = message.from_user.id + if await db.get_alldlbot_is_blacklist_user(client.me.id, user_id): + return + user_name = message.from_user.first_name + nn = "[" + user_name + "](tg://user?id=" + str(user_id) + ")" + if not await db.get_forcesub_only_bot(client.me.id): + return await message.reply_text("This is the command /addjoin username channel and becomes admin on the channel") + update_channel = await db.get_forcesub_only_bot(client.me.id) + if update_channel: + try: + user = await client.get_chat_member(update_channel, user_id) + if user.status == ChatMemberStatus.BANNED: + await client.send_message( + message.chat.id, + text=f"**❌ {nn} anda telah di blokir dari grup dukungan**", + disable_web_page_preview=True, + ) + return + except UserNotParticipant: + await client.send_message( + message.chat.id, + text=f"**👋🏻 Halo {nn}\nᴜɴᴛᴜᴋ ᴍᴇɴɢʜɪɴᴅᴀʀɪ ᴘᴇɴɢɢᴜɴᴀᴀɴ ʏᴀɴɢ ʙᴇʀʟᴇʙɪʜᴀɴ ʙᴏᴛ ɪɴɪ ᴅɪ ᴋʜᴜsᴜsᴋᴀɴ ᴜɴᴛᴜᴋ ʏᴀɴɢ sᴜᴅᴀʜ ᴊᴏɪɴ ᴅɪ ᴄʜᴀɴɴᴇʟ ᴋᴀᴍɪ​!**", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Jᴏɪɴ Cʜᴀɴɴᴇʟ Dᴜʟᴜ", + url=f"https://t.me/{update_channel}", + ) + ] + ] + ), + ) + return + except ChatAdminRequired: + return await message.reply_text(f"Chat admins Required: before /addjoin username without @ and add bot to your channel as admin") + + if len(message.command) < 2: + return await message.reply_text( + "Give a valid youtube search to download video." + ) + query = await input_user(message) + results = YoutubeSearch(query, max_results=5).to_dict() + watch = results[0]["url_suffix"] + url_suffix = watch.split("/")[1] + okk = f"https://youtube.com/{url_suffix}" + pro = await message.reply_text("Checking ...") + status, url = YoutubeDriver.check_url(okk) + if not status: + return await pro.edit_text(url) + if client.me.is_premium: + await pro.edit_text(f"{custom_loading}__Downloading audio ...__") + else: + await pro.edit_text(f"__Downloading audio ...__") + try: + with YoutubeDL(YoutubeDriver.video_options()) as ytdl: + yt_data = ytdl.extract_info(url, True) + yt_file = yt_data["id"] + + if client.me.is_premium: + upload_text = f"**{custom_loading}𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + else: + upload_text = f"**𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + await pro.edit_text(upload_text) + response = requests.get(f"https://i.ytimg.com/vi/{yt_data['id']}/hqdefault.jpg") + with open(f"{yt_file}.jpg", "wb") as f: + f.write(response.content) + await message.reply_video( + f"{yt_file}.mp4", + caption=f"**🎧 𝖳𝗂𝗍𝗅𝖾:** {yt_data['title']} \n\n**👀 𝖵𝗂𝖾𝗐𝗌:** `{yt_data['view_count']}` \n**⌛ 𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{secs_to_mins(int(yt_data['duration']))}`", + duration=int(yt_data["duration"]), + thumb=f"{yt_file}.jpg", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text, + ), + ) + await pro.delete() + except Exception as e: + return await pro.edit_text(f"**🍀 Video not Downloaded:** `{e}`") + try: + os.remove(f"{yt_file}.jpg") + os.remove(f"{yt_file}.mp4") + except: + pass + +@Client.on_message( + ~filters.scheduled + & filters.command(["ytv"]) + & ~filters.forwarded +) +async def ytvideo(client: Client, message: Message): + user_id = message.from_user.id + if await db.get_alldlbot_is_blacklist_user(client.me.id, user_id): + return + user_name = message.from_user.first_name + nn = "[" + user_name + "](tg://user?id=" + str(user_id) + ")" + if not await db.get_forcesub_only_bot(client.me.id): + return await message.reply_text("This is the command /addjoin username channel and becomes admin on the channel") + update_channel = await db.get_forcesub_only_bot(client.me.id) + if update_channel: + try: + user = await client.get_chat_member(update_channel, user_id) + if user.status == ChatMemberStatus.BANNED: + await client.send_message( + message.chat.id, + text=f"**❌ {nn} anda telah di blokir dari grup dukungan**", + disable_web_page_preview=True, + ) + return + except UserNotParticipant: + await client.send_message( + message.chat.id, + text=f"**👋🏻 Halo {nn}\nᴜɴᴛᴜᴋ ᴍᴇɴɢʜɪɴᴅᴀʀɪ ᴘᴇɴɢɢᴜɴᴀᴀɴ ʏᴀɴɢ ʙᴇʀʟᴇʙɪʜᴀɴ ʙᴏᴛ ɪɴɪ ᴅɪ ᴋʜᴜsᴜsᴋᴀɴ ᴜɴᴛᴜᴋ ʏᴀɴɢ sᴜᴅᴀʜ ᴊᴏɪɴ ᴅɪ ᴄʜᴀɴɴᴇʟ ᴋᴀᴍɪ​!**", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Jᴏɪɴ Cʜᴀɴɴᴇʟ Dᴜʟᴜ", + url=f"https://t.me/{update_channel}", + ) + ] + ] + ), + ) + return + except ChatAdminRequired: + return await message.reply_text("Chat admins Required: before /addjoin username without @ and add bot to your channel as admin") + + if len(message.command) < 2: + return await message.reply_text( + "Give a valid youtube link to download video." + ) + query = await input_user(message) + pro = await message.reply_text("Checking ...") + status, url = YoutubeDriver.check_url(query) + if not status: + return await pro.edit_text(url) + if client.me.is_premium: + await pro.edit_text(f"{custom_loading}__Downloading audio ...__") + else: + await pro.edit_text(f"__Downloading audio ...__") + try: + with YoutubeDL(YoutubeDriver.video_options()) as ytdl: + yt_data = ytdl.extract_info(url, True) + yt_file = yt_data["id"] + + if client.me.is_premium: + upload_text = f"**{custom_loading}𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + else: + upload_text = f"**𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + await pro.edit_text(upload_text) + response = requests.get(f"https://i.ytimg.com/vi/{yt_data['id']}/hqdefault.jpg") + with open(f"{yt_file}.jpg", "wb") as f: + f.write(response.content) + await message.reply_video( + f"{yt_file}.mp4", + caption=f"**🎧 𝖳𝗂𝗍𝗅𝖾:** {yt_data['title']} \n\n**👀 𝖵𝗂𝖾𝗐𝗌:** `{yt_data['view_count']}` \n**⌛ 𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{secs_to_mins(int(yt_data['duration']))}`", + duration=int(yt_data["duration"]), + thumb=f"{yt_file}.jpg", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text, + ), + ) + await pro.delete() + except Exception as e: + return await pro.edit_text(f"**🍀 Video not Downloaded:** `{e}`") + try: + os.remove(f"{yt_file}.jpg") + os.remove(f"{yt_file}.mp4") + except: + pass + +@Client.on_message( + ~filters.scheduled + & filters.command(["ytlink"]) + & ~filters.forwarded +) +async def ytlink(client: Client, message: Message): + user_id = message.from_user.id + if await db.get_alldlbot_is_blacklist_user(client.me.id, user_id): + return + user_name = message.from_user.first_name + nn = "[" + user_name + "](tg://user?id=" + str(user_id) + ")" + if not await db.get_forcesub_only_bot(client.me.id): + return await message.reply_text("This is the command /addjoin username channel and becomes admin on the channel") + update_channel = await db.get_forcesub_only_bot(client.me.id) + if update_channel: + try: + user = await client.get_chat_member(update_channel, user_id) + if user.status == ChatMemberStatus.BANNED: + await client.send_message( + message.chat.id, + text=f"**❌ {nn} anda telah di blokir dari grup dukungan**", + disable_web_page_preview=True, + ) + return + except UserNotParticipant: + await client.send_message( + message.chat.id, + text=f"**👋🏻 Halo {nn}\nᴜɴᴛᴜᴋ ᴍᴇɴɢʜɪɴᴅᴀʀɪ ᴘᴇɴɢɢᴜɴᴀᴀɴ ʏᴀɴɢ ʙᴇʀʟᴇʙɪʜᴀɴ ʙᴏᴛ ɪɴɪ ᴅɪ ᴋʜᴜsᴜsᴋᴀɴ ᴜɴᴛᴜᴋ ʏᴀɴɢ sᴜᴅᴀʜ ᴊᴏɪɴ ᴅɪ ᴄʜᴀɴɴᴇʟ ᴋᴀᴍɪ​!**", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Jᴏɪɴ Cʜᴀɴɴᴇʟ Dᴜʟᴜ", + url=f"https://t.me/{update_channel}", + ) + ] + ] + ), + ) + return + except ChatAdminRequired: + return await message.reply_text("Chat admins Required: before /addjoin username without @ and add bot to your channel as admin") + + if len(message.command) < 2: + return await message.reply_text("Give something to search on youtube.") + query = await input_user(message) + pro = await message.reply_text("Searching ...") + try: + results = YoutubeDriver(query, 7).to_dict() + except Exception as e: + return await pro.edit_text(f"**🍀 Error:** `{e}`") + if not results: + return await pro.edit_text("No results found.") + text = f"**🔎 𝖳𝗈𝗍𝖺𝗅 𝖱𝖾𝗌𝗎𝗅𝗍𝗌 𝖥𝗈𝗎𝗇𝖽:** `{len(results)}`\n\n" + for result in results: + text += f"**𝖳𝗂𝗍𝗅𝖾:** `{result['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{result['channel']}`\n**𝖵𝗂𝖾𝗐𝗌:** `{result['views']}`\n**𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{result['duration']}`\n**𝖫𝗂𝗇𝗄:** `https://youtube.com{result['url_suffix']}`\n\n" + await pro.edit_text(text, disable_web_page_preview=True) \ No newline at end of file diff --git a/akn/AllDownloaderBot/support_sites.py b/akn/AllDownloaderBot/support_sites.py new file mode 100644 index 0000000000000000000000000000000000000000..5f8cde89fb229c05576fc215f36ae15ffe0a2db5 --- /dev/null +++ b/akn/AllDownloaderBot/support_sites.py @@ -0,0 +1,21 @@ +import yt_dlp +import os +import uuid +from akn.utils.logger import LOGS + +def all_one_downloader(url: str, download_path: str = "./downloads/"): + unique_id = str(uuid.uuid4()) + + ydl_opts = { + "outtmpl": os.path.join(download_path, f"{unique_id}.%(ext)s"), + "quiet": True, + "noplaylist": True, + "format": "best", + } + + with yt_dlp.YoutubeDL(ydl_opts) as ydl: + info = ydl.extract_info(url, download=True) + video_title = info.get("title", "Video") + video_path = ydl.prepare_filename(info) + + return video_path, video_title \ No newline at end of file diff --git a/akn/ApproveBot/__init__.py b/akn/ApproveBot/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/akn/ApproveBot/join_request.py b/akn/ApproveBot/join_request.py new file mode 100755 index 0000000000000000000000000000000000000000..52141403b1faba9e439e9f87e0a2b0ab14059615 --- /dev/null +++ b/akn/ApproveBot/join_request.py @@ -0,0 +1,428 @@ +import os +import time +import json +import asyncio +import io +import re +import logging +import string +import random +import requests +from pyrogram import Client, filters +from pyrogram.types import * +from pyrogram.enums import * +from pyrogram.errors import * + +from PIL import Image, ImageDraw, ImageFont, ImageFilter + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +captcha_texts = {} +captcha_modes = {} + +NOT_ALLOWED_NON_PROGRAMMER = [ + 5575183435, # suku + 948247711, # akay +] + +def generate_math_captcha(): + operations = ['+', '-', '*'] + operation = random.choice(operations) + num1 = random.randint(1, 20) + num2 = random.randint(1, 20) + + if operation == '+': + correct_answer = num1 + num2 + elif operation == '-': + correct_answer = num1 - num2 + else: + correct_answer = num1 * num2 + captcha_text = f"{num1} {operation} {num2} = ?" + choices = [str(correct_answer)] + while len(choices) < 3: + wrong_answer = correct_answer + random.choice([-5, -3, -2, 2, 3, 5]) + if str(wrong_answer) not in choices: + choices.append(str(wrong_answer)) + random.shuffle(choices) + + width, height = 250, 100 + background_color = (random.randint(200, 255), random.randint(200, 255), random.randint(200, 255)) # Warna pastel + img = Image.new('RGB', (width, height), color=background_color) + d = ImageDraw.Draw(img) + + for _ in range(1000): + x = random.randint(0, width) + y = random.randint(0, height) + noise_color = (random.randint(150, 200), random.randint(150, 200), random.randint(150, 200)) + d.point((x, y), fill=noise_color) + + try: + font = ImageFont.truetype("arial.ttf", 40) + except IOError: + font = ImageFont.load_default() + + text_width, text_height = d.textsize(captcha_text, font=font) + text_x = (width - text_width) / 2 + text_y = (height - text_height) / 2 - 20 + + text_image = Image.new('RGBA', (text_width, text_height), (255, 255, 255, 0)) + text_draw = ImageDraw.Draw(text_image) + text_draw.text((0, 0), captcha_text, font=font, fill=(0, 0, 0)) + rotated_text = text_image.rotate(random.randint(-25, 25), expand=1) + img.paste(rotated_text, (int(text_x), int(text_y)), rotated_text) + + choice_font = ImageFont.truetype("arial.ttf", 30) if font else ImageFont.load_default() + for idx, choice in enumerate(choices): + choice_text = f"{idx + 1}. {choice}" + choice_width, choice_height = d.textsize(choice_text, font=choice_font) + choice_x = 50 + idx * 80 + choice_y = height - choice_height - 20 + d.text((choice_x, choice_y), choice_text, font=choice_font, fill=(0, 0, 0)) + + for _ in range(5): + start = (random.randint(0, width), random.randint(0, height)) + end = (random.randint(0, width), random.randint(0, height)) + line_color = (random.randint(0, 150), random.randint(0, 150), random.randint(0, 150)) + d.line([start, end], fill=line_color, width=2) + + img = img.filter(ImageFilter.BLUR) + + img_path = f"captcha_math_{captcha_text}.png" + img.save(img_path) + + return captcha_text, img_path, choices, correct_answer + +def generate_text_captcha(): + letters = string.ascii_uppercase + string.digits + captcha_text = ''.join(random.choice(letters) for _ in range(5)) + + choices = [captcha_text] + while len(choices) < 3: + wrong_choice = ''.join(random.choice(letters) for _ in range(5)) + if wrong_choice not in choices: + choices.append(wrong_choice) + random.shuffle(choices) + + width, height = 200, 80 + background_color = (random.randint(200, 255), random.randint(200, 255), random.randint(200, 255)) # Warna pastel + img = Image.new('RGB', (width, height), color=background_color) + d = ImageDraw.Draw(img) + + for _ in range(500): + x = random.randint(0, width) + y = random.randint(0, height) + noise_color = (random.randint(150, 200), random.randint(150, 200), random.randint(150, 200)) + d.point((x, y), fill=noise_color) + + try: + font = ImageFont.truetype("arial.ttf", 45) + except IOError: + font = ImageFont.load_default() + + text_width, text_height = d.textsize(captcha_text, font=font) + text_x = (width - text_width) / 2 + text_y = (height - text_height) / 2 + + text_image = Image.new('RGBA', (text_width, text_height), (255, 255, 255, 0)) + text_draw = ImageDraw.Draw(text_image) + text_draw.text((0, 0), captcha_text, font=font, fill=(0, 0, 0)) + rotated_text = text_image.rotate(random.randint(-25, 25), expand=1) + img.paste(rotated_text, (int(text_x), int(text_y)), rotated_text) + + choice_font = ImageFont.truetype("arial.ttf", 30) if font else ImageFont.load_default() + for idx, choice in enumerate(choices): + choice_text = f"{idx + 1}. {choice}" + choice_width, choice_height = d.textsize(choice_text, font=choice_font) + choice_x = 50 + idx * 80 + choice_y = height - choice_height - 20 + d.text((choice_x, choice_y), choice_text, font=choice_font, fill=(0, 0, 0)) + + for _ in range(5): + start = (random.randint(0, width), random.randint(0, height)) + end = (random.randint(0, width), random.randint(0, height)) + line_color = (random.randint(0, 150), random.randint(0, 150), random.randint(0, 150)) + d.line([start, end], fill=line_color, width=2) + + img = img.filter(ImageFilter.BLUR) + img_path = f"captcha_text_{captcha_text}.png" + img.save(img_path) + + return captcha_text, img_path, choices, captcha_text + +def generate_captcha(user_id, mode='math'): + if mode == 'math': + return generate_math_captcha() + else: + return generate_text_captcha() + +def thanks_hacker_by_randydev(): + url = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR0u8UqJ2JDhfmPOCb_zAHjUQG2NYMjTwLbkq_sQhCQOxX8hn66YbaGFvLL&s=10" + response = requests.get(url) + image_hacker = "hacker.png" + with open(image_hacker, "wb") as f: + f.write(response.content) + return image_hacker + +def failed_hacker_by_randydev(): + url = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTM0vb4s59H9F1-_7FyELiLU04e8bCHy7o6KQV2mG3DFRLnzP547KjckKG2&s=10" + response = requests.get(url) + image_hacker = "failed_hacker.png" + with open(image_hacker, "wb") as f: + f.write(response.content) + return image_hacker + +async def remove_captcha_after_timeout(client, user_id, delay=300): + await asyncio.sleep(delay) + if user_id in captcha_texts: + captcha_data = captcha_texts.get(user_id) + chat_id = captcha_data['chat_id'] + await client.decline_chat_join_request( + chat_id=chat_id, + user_id=user_id + ) + await client.send_message(user_id, "⏰ Your CAPTCHA verification has expired. Please try again.") + del captcha_texts[user_id] + logger.info(f"CAPTCHA for user {user_id} has expired and been removed.") + +@Client.on_message(filters.command("settingmode") & filters.private) +async def setting_mode(client: Client, message: Message): + if message.from_user.id in NOT_ALLOWED_NON_PROGRAMMER: + return + user_id = message.from_user.id + keyboard = InlineKeyboardMarkup( + [ + [InlineKeyboardButton("🔢 Mathematics", callback_data="mode_math")], + [InlineKeyboardButton("🔤 Text", callback_data="mode_text")], + [InlineKeyboardButton("❌ Cancel", callback_data="cancel_mode")] + ] + ) + await message.reply_text( + "📍 Select the CAPTCHA mode you want:", + reply_markup=keyboard + ) + +@Client.on_callback_query(filters.regex("^mode_")) +async def mode_callback(client: Client, cb: CallbackQuery): + user_id = cb.from_user.id + data = cb.data.split("_") + if len(data) != 2: + await cb.answer("❌ Invalid selection.", show_alert=True) + return + mode = data[1] + if mode not in ['math', 'text']: + await cb.answer("❌ Invalid mode.", show_alert=True) + return + captcha_modes[user_id] = mode + keyboard = InlineKeyboardMarkup( + [ + [InlineKeyboardButton("🔢 Mathematics", callback_data="mode_math")], + [InlineKeyboardButton("🔤 Text", callback_data="mode_text")], + [InlineKeyboardButton("❌ Cancel", callback_data="cancel_mode")] + ] + ) + await cb.edit_message_text( + f"✅ CAPTCHA mode has been set to **{'Mathematics' if mode == 'math' else 'Text'}**.", + reply_markup=keyboard + ) + await cb.answer("The mode has been changed.", show_alert=False) + logger.info(f"User {user_id} set CAPTCHA mode to {mode}.") + +@Client.on_callback_query(filters.regex("^cancel_mode$")) +async def cancel_mode_callback(client: Client, cb: CallbackQuery): + await cb.edit_message_text("❌ CAPTCHA mode setting has been canceled.") + await cb.answer("Cancellation successful.", show_alert=False) + logger.info(f"User {cb.from_user.id} canceled CAPTCHA mode setting.") + +@Client.on_chat_join_request(filters.chat("KillerXSupport")) +async def join_request(client: Client, event: ChatJoinRequest): + member = await client.get_chat_member(event.chat.id, "me") + if member.status != ChatMemberStatus.ADMINISTRATOR: + return await client.send_message(event.chat.id, text="I am not an administrator in this group.") + + try: + chat_link = await client.export_chat_invite_link(event.chat.id) + except ChatAdminRequired: + await client.send_message(event.chat.id, text="I need to be an administrator to perform this action.") + return + + mode = captcha_modes.get(event.from_user.id, "text") + captcha_text, img_path, choices, correct_answer = generate_captcha(event.from_user.id, mode) + captcha_texts[event.from_user.id] = { + "captcha_text": captcha_text, + "correct_answer": correct_answer, + "chat_id": event.chat.id, + "chat_link": chat_link, + "first_name": event.from_user.first_name + } + + buttons = [ + [InlineKeyboardButton(choice, callback_data=f"verify_{event.from_user.id}_{choice}")] + for choice in choices + ] + buttons.append([ + InlineKeyboardButton("🔄 Refresh CAPTCHA", callback_data="refresh_captcha"), + InlineKeyboardButton("❌ Cancel", callback_data="cancel_captcha") + ]) + keyboard = InlineKeyboardMarkup(buttons) + + if event.chat.type == ChatType.SUPERGROUP: + try: + await client.send_message( + event.chat.id, + text=f" 🕦 Verify that you {event.from_user.first_name} are human!", + reply_markup=create_button_userinfo(event.from_user.id, client.me.username) + ) + await client.send_photo( + event.from_user.id, + photo=img_path, + caption=f"❗️ **Verify that you are human!**\n\n❔ Please select the correct CAPTCHA text shown in the image below.", + reply_markup=keyboard + ) + os.remove(img_path) + asyncio.create_task(remove_captcha_after_timeout(client, event.from_user.id)) + except Exception as e: + await client.send_message( + event.chat.id, + text=str(e) + ) + logger.error(str(e)) + +@Client.on_callback_query(filters.regex("^verify_")) +async def verify_captcha_callback(client: Client, cb: CallbackQuery): + data = cb.data.split("_") + if len(data) != 3: + await cb.answer("❌ Format data tidak valid.", show_alert=True) + return + _, user_id_str, user_choice = data + try: + user_id = int(user_id_str) + except ValueError: + await cb.answer("❌ Invalid user ID.", show_alert=True) + return + if cb.from_user.id != user_id: + await cb.answer("❌ You have no right to do this.", show_alert=True) + logger.warning(f"User {cb.from_user.id} mencoba memverifikasi CAPTCHA milik user {user_id}.") + return + if user_id not in captcha_texts: + await cb.answer("❗️ No active CAPTCHA verification.", show_alert=True) + logger.warning(f"User {user_id} mencoba memverifikasi CAPTCHA tanpa aktif.") + return + captcha_data = captcha_texts.get(user_id) + captcha_text = captcha_data["captcha_text"] + correct_answer = captcha_data["correct_answer"] + chat_id = captcha_data["chat_id"] + chat_link = captcha_data["chat_link"] + first_name = captcha_data["first_name"] + + failed_image = failed_hacker_by_randydev() + hacker_image = thanks_hacker_by_randydev() + + try: + if str(user_choice) == str(correct_answer): + await cb.edit_message_media( + media=InputMediaPhoto( + hacker_image, + caption="✅ CAPTCHA verification successful!" + ), + reply_markup=create_button_join_group(chat_link) + ) + logger.info(f"User {user_id} berhasil memverifikasi CAPTCHA.") + if user_id in NOT_ALLOWED_NON_PROGRAMMER: + await client.ban_chat_member(chat_id=chat_id, user_id=user_id) + return + await client.approve_chat_join_request( + chat_id=chat_id, + user_id=user_id + ) + await client.send_message(chat_id, f"Thank you for joining {first_name}") + del captcha_texts[user_id] + else: + await cb.edit_message_media( + media=InputMediaPhoto( + failed_image, + caption="❌ **CAPTCHA verification failed.**\n\nPlease try again." + ) + ) + await client.decline_chat_join_request( + chat_id=chat_id, + user_id=user_id + ) + await client.send_message(chat_id, f"Failed to join {first_name}") + logger.info(f"User {user_id} gagal memverifikasi CAPTCHA.") + del captcha_texts[user_id] + except Exception as e: + await cb.answer(f"Error CAPTCHA: {e}", show_alert=True) + +@Client.on_callback_query(filters.regex("^refresh_captcha$")) +async def refresh_captcha_callback(client: Client, cb: CallbackQuery): + user_id = cb.from_user.id + mode = captcha_modes.get(user_id, 'math') + if user_id in captcha_texts: + del captcha_texts[user_id] + logger.info(f"Old CAPTCHA for user {user_id} has been removed.") + captcha_text, img_path, choices, correct_answer = generate_captcha(user_id, mode) + captcha_texts[user_id] = { + "captcha_text": captcha_text, + "correct_answer": correct_answer, + "chat_id": captcha_texts[user_id]["chat_id"], + "chat_link": captcha_texts[user_id]["chat_link"], + "first_name": captcha_texts[user_id]["first_name"] + + } + logger.info(f"Generated new {mode} CAPTCHA for user {user_id}: {captcha_text}") + buttons = [ + [InlineKeyboardButton(choice, callback_data=f"verify_{user_id}_{choice}")] + for choice in choices + ] + buttons.append([ + InlineKeyboardButton("🔄 Refresh CAPTCHA", callback_data="refresh_captcha"), + InlineKeyboardButton("❌ Cancel", callback_data="cancel_captcha") + ]) + keyboard = InlineKeyboardMarkup(buttons) + try: + await cb.edit_message_media( + media=InputMediaPhoto(img_path), + reply_markup=keyboard + ) + logger.info(f"Updated CAPTCHA image for user {user_id}.") + except Exception as e: + await cb.answer("❌ Failed to update CAPTCHA.", show_alert=True) + logger.error(f"Error refreshing CAPTCHA for user {user_id}: {e}") + os.remove(img_path) + await cb.answer("🔄 CAPTCHA has been updated!", show_alert=False) + +@Client.on_callback_query(filters.regex("^cancel_captcha$")) +async def cancel_captcha_callback(client: Client, cb: CallbackQuery): + user_id = cb.from_user.id + if user_id in captcha_texts: + del captcha_texts[user_id] + logger.info(f"User {user_id} has canceled CAPTCHA verification.") + await cb.edit_message_caption( + caption="❌ **CAPTCHA verification has been canceled.**\n\nIf you want to try again.", + ) + await cb.answer("CAPTCHA verification canceled.", show_alert=False) + else: + await cb.answer("❗️ No active CAPTCHA verification found.", show_alert=True) + logger.warning(f"User {user_id} attempted to cancel CAPTCHA without active verification.") + +@Client.on_callback_query(filters.regex("^close$")) +async def close_final(client: Client, cb: CallbackQuery): + await cb.message.delete() + await cb.answer() + +def create_button_join_group(chat_link): + return InlineKeyboardMarkup( + [ + [InlineKeyboardButton("👁️ Join chat", url=chat_link)], + [InlineKeyboardButton("🔘 Close", callback_data="close")], + ] + ) + +def create_button_userinfo(user_id, username): + return InlineKeyboardMarkup( + [ + [InlineKeyboardButton("👤 Chmod +W $USER", user_id=user_id)], + [InlineKeyboardButton("🔔 Check human Bot", url=f"https://t.me/{username}")], + ] + ) \ No newline at end of file diff --git a/akn/ApproveBot/start.py b/akn/ApproveBot/start.py new file mode 100755 index 0000000000000000000000000000000000000000..4d18fbf9e59019586d99553b4ad50e8364474eac --- /dev/null +++ b/akn/ApproveBot/start.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2020-2024 (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 time +import json +import asyncio +import io +import os +import re +import logging + +from pyrogram import * +from pyrogram.enums import ChatMemberStatus, ChatType +from pyrogram import enums +from pyrogram import Client, filters +from pyrogram.types import * +from pyrogram.errors import * + +START_TEXT = """ +👋 **Hey {name}!** + +I’m excited to let you know that I’m ready to serve as your **Approve Join Request CAPTCHA Bot Developer**. + +✨ **What I Offer**: +- **Approve Join Requests**: Automatically approve or reject join requests based on your settings. +- **CAPTCHA Verification**: Add an extra layer of security with CAPTCHA challenges for new members. + +🔧 **How to Get Started**: +1. Use the command `/settingmode` to configure your preferences. +2. Customize the bot to suit your group’s needs. + +🚀 Let’s make your group safer and more efficient together! +""" + +NOT_ALLOWED_NON_PROGRAMMER = [ + 5575183435, #suku + 948247711, # akay +] + +@Client.on_message( + ~filters.scheduled + & filters.command(["start"]) + & filters.private + & ~filters.forwarded +) +async def startbot(client: Client, message: Message): + if message.from_user.id in NOT_ALLOWED_NON_PROGRAMMER: + return + buttons = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Add your to group", + url=f"https://t.me/{client.me.username}?startgroup=True" + ), + ], + [ + InlineKeyboardButton( + text="Developer", + url=f"https://t.me/xpushz" + ), + InlineKeyboardButton( + text="Channel", + url='https://t.me/RendyProjects' + ) + ], + ] + ) + await message.reply_text( + text=START_TEXT.format(name=message.from_user.mention), + disable_web_page_preview=True, + reply_markup=buttons + ) \ No newline at end of file diff --git a/akn/Gemini/__init__.py b/akn/Gemini/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/akn/Gemini/gemini.py b/akn/Gemini/gemini.py new file mode 100755 index 0000000000000000000000000000000000000000..460a07b462ecbd26c589aa0bc6c53acc6adb3d0b --- /dev/null +++ b/akn/Gemini/gemini.py @@ -0,0 +1,335 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2020-2024 (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 requests +import time +import json +import asyncio +import io +import os +import re +from PIL import Image + +from pyrogram import * +from pyrogram import enums +from pyrogram import Client, filters +from pyrogram.types import * +from pyrogram.errors import * +from RyuzakiLib import FaceAI, FullStackDev, GeminiLatest, RendyDevChat +from config import * + +from akn import send_log +from akn.utils.database import db +from akn.utils.logger import LOGS + +import google.generativeai as genai +from google.api_core.exceptions import InvalidArgument + +async def geni_files_delete(name: str): + url = f"https://generativelanguage.googleapis.com/v1beta/{name}" + params = {"key": GOOGLE_API_KEY} + response = requests.delete(url, params=params) + if response.status_code != 200: + return None + return response.text + +DISABLED_COMMNAD = [ + "onchat", + "offchat", + "start" +] + +GEMINI_START_TEXT = """ +Hey! {name} + +I am ready to be a gemini bot developer + +- Command: /onchat (pm or group) +- Command: /offchat (pm or group) +""" + +@Client.on_message( + ~filters.scheduled + & filters.command(["start"]) + & ~filters.forwarded +) +async def startbot(client: Client, message: Message): + buttons = [ + [ + InlineKeyboardButton( + text="Developer", + url=f"https://t.me/xtdevs" + ), + InlineKeyboardButton( + text="Channel", + url='https://t.me/RendyProjects' + ), + ], + [ + InlineKeyboardButton( + text="Donate Via Web", + web_app=WebAppInfo(url="https://sociabuzz.com/randydev99/tribe") + ) + ] + ] + await message.reply_text( + text=GEMINI_START_TEXT.format(name=message.from_user.mention), + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(buttons) + ) + +@Client.on_message( + ~filters.scheduled + & filters.command(["onchat"]) + & ~filters.forwarded +) +async def addchatbot_user(client: Client, message: Message): + await db.add_chatbot(message.chat.id, client.me.id) + await message.reply_text("Added chatbot user") + +@Client.on_message( + ~filters.scheduled + & filters.command(["offchat"]) + & ~filters.forwarded +) +async def rmchatbot_user(client: Client, message: Message): + await db.remove_chatbot(message.chat.id) + await message.reply_text("ok stopped gemini") + +@Client.on_message( + filters.incoming + & ( + filters.text + | filters.photo + | filters.video + | filters.audio + | filters.voice + | filters.regex(r"\b(Randy|Rendi)\b(.*)", flags=re.IGNORECASE) + ) + & (filters.private | filters.group) + & ~filters.command(DISABLED_COMMNAD) + & ~filters.bot + & ~filters.via_bot + & ~filters.forwarded, + group=2, +) +async def chatbot_talk(client: Client, message: Message): + genai.configure(api_key=GOOGLE_API_KEY) + chat_user = await db.get_chatbot(message.chat.id) + if not chat_user: + return + if message.reply_to_message and message.reply_to_message.from_user: + if message.reply_to_message.from_user.id != client.me.id: + return + if message.photo: + await client.send_chat_action(message.chat.id, enums.ChatAction.UPLOAD_PHOTO) + await asyncio.sleep(1.5) + file_path = await message.download() + caption = message.caption or "What's this?" + x = GeminiLatest(api_keys=GOOGLE_API_KEY) + if client.me.is_premium: + ai_reply = await message.reply_text(f"{custom_loading}Processing...") + else: + ai_reply = await message.reply_text(f"Processing...") + try: + await client.send_chat_action(message.chat.id, enums.ChatAction.TYPING) + await asyncio.sleep(1.5) + backup_chat = await db._get_chatbot_chat_from_db(message.from_user.id) + backup_chat.append({"role": "user", "parts": [{"text": caption}]}) + response_reads = x.get_response_image(caption, file_path) + if len(response_reads) > 4096: + with open("chat.txt", "w+", encoding="utf8") as out_file: + out_file.write(response_reads) + await message.reply_document( + document="chat.txt", + disable_notification=True + ) + await ai_reply.delete() + os.remove("chat.txt") + else: + await ai_reply.edit_text(response_reads) + backup_chat.append({"role": "model", "parts": [{"text": response_reads}]}) + await db._update_chatbot_chat_in_db(message.from_user.id, backup_chat) + await client.send_chat_action(message.chat.id, enums.ChatAction.CANCEL) + os.remove(file_path) + return + except InvalidArgument as e: + return await ai_reply.edit_text(f"Error: {e}") + except Exception as e: + return await ai_reply.edit_text(f"Error: {e}") + + if message.audio or message.voice: + await client.send_chat_action(message.chat.id, enums.ChatAction.UPLOAD_AUDIO) + await asyncio.sleep(1.5) + if client.me.is_premium: + ai_reply = await message.reply_text(f"{custom_loading}Processing...") + else: + ai_reply = await message.reply_text(f"Processing...") + if message.audio: + audio_file_name = await message.download() + if message.voice: + audio_file_name = await message.download() + caption = message.caption or "What's this?" + model = genai.GenerativeModel( + model_name="gemini-1.5-flash", + safety_settings={ + genai.types.HarmCategory.HARM_CATEGORY_HATE_SPEECH: genai.types.HarmBlockThreshold.BLOCK_NONE, + genai.types.HarmCategory.HARM_CATEGORY_HARASSMENT: genai.types.HarmBlockThreshold.BLOCK_NONE, + genai.types.HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: genai.types.HarmBlockThreshold.BLOCK_NONE, + genai.types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: genai.types.HarmBlockThreshold.BLOCK_NONE, + } + ) + backup_chat = await db._get_chatbot_chat_from_db(message.from_user.id) + backup_chat.append({"role": "user", "parts": [{"text": caption}]}) + if client.me.is_premium: + await ai_reply.edit_text(f"{custom_loading}Uploading file..") + else: + await ai_reply.edit_text("Uploading file..") + audio_file = genai.upload_file(path=audio_file_name) + while audio_file.state.name == "PROCESSING": + await asyncio.sleep(10) + audio_file = genai.get_file(audio_file.name) + if audio_file.state.name == "FAILED": + return await ai_reply.edit_text(f"Error: {audio_file.state.name}") + try: + await client.send_chat_action(message.chat.id, enums.ChatAction.TYPING) + await asyncio.sleep(1.5) + response = model.generate_content( + [audio_file, caption], + request_options={"timeout": 600} + ) + if len(response.text) > 4096: + with open("chat.txt", "w+", encoding="utf8") as out_file: + out_file.write(response.text) + await message.reply_document( + document="chat.txt", + disable_notification=True + ) + await ai_reply.delete() + os.remove("chat.txt") + else: + await ai_reply.edit_text(response.text) + backup_chat.append({"role": "model", "parts": [{"text": response.text}]}) + await db._update_chatbot_chat_in_db(message.from_user.id, backup_chat) + await client.send_chat_action(message.chat.id, enums.ChatAction.CANCEL) + audio_file.delete() + os.remove(audio_file_name) + return + except InvalidArgument as e: + return await ai_reply.edit_text(f"Error: {e}") + except Exception as e: + return await ai_reply.edit_text(f"Error: {e}") + + if message.video: + await client.send_chat_action(message.chat.id, enums.ChatAction.UPLOAD_VIDEO) + await asyncio.sleep(1.5) + if client.me.is_premium: + ai_reply = await message.reply_text(f"{custom_loading}Processing...") + else: + ai_reply = await message.reply_text(f"Processing...") + video_file_name = await message.download(file_name="newvideo.mp4") + caption = message.caption or "What's this?" + model = genai.GenerativeModel( + model_name="gemini-1.5-pro", + safety_settings={ + genai.types.HarmCategory.HARM_CATEGORY_HATE_SPEECH: genai.types.HarmBlockThreshold.BLOCK_NONE, + genai.types.HarmCategory.HARM_CATEGORY_HARASSMENT: genai.types.HarmBlockThreshold.BLOCK_NONE, + genai.types.HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: genai.types.HarmBlockThreshold.BLOCK_NONE, + genai.types.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: genai.types.HarmBlockThreshold.BLOCK_NONE, + } + ) + backup_chat = await db._get_chatbot_chat_from_db(message.from_user.id) + backup_chat.append({"role": "user", "parts": [{"text": caption}]}) + if client.me.is_premium: + await ai_reply.edit_text(f"{custom_loading}Uploading file..") + else: + await ai_reply.edit_text("Uploading file..") + video_file = genai.upload_file(path=video_file_name) + while video_file.state.name == "PROCESSING": + await asyncio.sleep(10) + video_file = genai.get_file(video_file.name) + if video_file.state.name == "FAILED": + return await ai_reply.edit_text(f"Error: {video_file.state.name}") + try: + await client.send_chat_action(message.chat.id, enums.ChatAction.TYPING) + await asyncio.sleep(1.5) + response = model.generate_content( + [video_file, caption], + request_options={"timeout": 600} + ) + if len(response.text) > 4096: + with open("chat.txt", "w+", encoding="utf8") as out_file: + out_file.write(response.text) + await message.reply_document( + document="chat.txt", + disable_notification=True + ) + await ai_reply.delete() + os.remove("chat.txt") + else: + await ai_reply.edit_text(response.text) + backup_chat.append({"role": "model", "parts": [{"text": response.text}]}) + await db._update_chatbot_chat_in_db(message.from_user.id, backup_chat) + await client.send_chat_action(message.chat.id, enums.ChatAction.CANCEL) + video_file.delete() + os.remove(video_file_name) + return + except InvalidArgument as e: + return await ai_reply.edit_text(f"Error: {e}") + except Exception as e: + return await ai_reply.edit_text(f"Error: {e}") + + if message.text: + await client.send_chat_action(message.chat.id, enums.ChatAction.TYPING) + await asyncio.sleep(1.5) + query = message.text.strip() + match = re.search(r"\b(Randy|Rendi)\b(.*)", query, flags=re.IGNORECASE) + if match: + rest_of_sentence = match.group(2).strip() + query_base = rest_of_sentence if rest_of_sentence else query + else: + query_base = query + parts = query.split(maxsplit=1) + command = parts[0].lower() + pic_query = parts[1].strip() if len(parts) > 1 else "" + try: + model_flash = genai.GenerativeModel( + model_name="gemini-1.5-flash" + ) + backup_chat = await db._get_chatbot_chat_from_db(message.from_user.id) + backup_chat.append({"role": "user", "parts": [{"text": query_base}]}) + chat_session = model_flash.start_chat(history=backup_chat) + response_data = chat_session.send_message(query_base) + output = response_data.text + if len(output) > 4096: + with open("chat.txt", "w+", encoding="utf8") as out_file: + out_file.write(output) + await message.reply_document( + document="chat.txt", + disable_notification=True + ) + os.remove("chat.txt") + else: + await message.reply_text(output) + backup_chat.append({"role": "model", "parts": [{"text": output}]}) + await db._update_chatbot_chat_in_db(message.from_user.id, backup_chat) + await client.send_chat_action(message.chat.id, enums.ChatAction.CANCEL) + return + except Exception as e: + return await message.reply_text(f"Error: {e}") diff --git a/akn/MagicFonts/__init__.py b/akn/MagicFonts/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/akn/MagicFonts/commands.py b/akn/MagicFonts/commands.py new file mode 100755 index 0000000000000000000000000000000000000000..915274bd94cb0690b6f2cd2fbdebb28dfe8816a1 --- /dev/null +++ b/akn/MagicFonts/commands.py @@ -0,0 +1,206 @@ +import os +from akn.MagicFonts.fonts import Fonts +from pyrogram import Client, filters +from pyrogram import * +from pyrogram.types import * +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup + + +@Client.on_message( + filters.command(["start"]) + & filters.private + & ~filters.forwarded +) +async def start(c, m): + text = f"""Hey! {m.from_user.mention}, + +💡 ** I am Stylish Fonts Bot** + +• I can help you to get stylish fonts +• Just send me some text and see magic + +- maintenance by @xtdevs +""" + buttons = [ + [ + InlineKeyboardButton('Developer', url=f"https://t.me/xtsea"), + InlineKeyboardButton('Channel', url='https://t.me/RendyProjects'), + ], + [ + InlineKeyboardButton('Fonts Via Web', url='https://fsymbols.com/generators/smallcaps/') + ], + [ + InlineKeyboardButton(text="Donate Via Web", web_app=WebAppInfo(url="https://sociabuzz.com/randydev99/tribe")) + ] + ] + await m.reply_text( + text=text, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(buttons) + ) + await m.stop_propagation() + +@Client.on_message(filters.private & filters.text) +async def style_buttons(c, m, cb=False): + buttons = [[ + InlineKeyboardButton('𝚃𝚢𝚙𝚎𝚠𝚛𝚒𝚝𝚎𝚛', callback_data='style+typewriter'), + InlineKeyboardButton('𝕆𝕦𝕥𝕝𝕚𝕟𝕖', callback_data='style+outline'), + InlineKeyboardButton('𝐒𝐞𝐫𝐢𝐟', callback_data='style+serif'), + ],[ + InlineKeyboardButton('𝑺𝒆𝒓𝒊𝒇', callback_data='style+bold_cool'), + InlineKeyboardButton('𝑆𝑒𝑟𝑖𝑓', callback_data='style+cool'), + InlineKeyboardButton('Sᴍᴀʟʟ Cᴀᴘs', callback_data='style+small_cap'), + ],[ + InlineKeyboardButton('𝓈𝒸𝓇𝒾𝓅𝓉', callback_data='style+script'), + InlineKeyboardButton('𝓼𝓬𝓻𝓲𝓹𝓽', callback_data='style+script_bolt'), + InlineKeyboardButton('ᵗⁱⁿʸ', callback_data='style+tiny'), + ],[ + InlineKeyboardButton('ᑕOᗰIᑕ', callback_data='style+comic'), + InlineKeyboardButton('𝗦𝗮𝗻𝘀', callback_data='style+sans'), + InlineKeyboardButton('𝙎𝙖𝙣𝙨', callback_data='style+slant_sans'), + ],[ + InlineKeyboardButton('𝘚𝘢𝘯𝘴', callback_data='style+slant'), + InlineKeyboardButton('𝖲𝖺𝗇𝗌', callback_data='style+sim'), + InlineKeyboardButton('Ⓒ︎Ⓘ︎Ⓡ︎Ⓒ︎Ⓛ︎Ⓔ︎Ⓢ︎', callback_data='style+circles'), + ],[ + InlineKeyboardButton('🅒︎🅘︎🅡︎🅒︎🅛︎🅔︎🅢︎', callback_data='style+circle_dark'), + InlineKeyboardButton('𝔊𝔬𝔱𝔥𝔦𝔠', callback_data='style+gothic'), + InlineKeyboardButton('𝕲𝖔𝖙𝖍𝖎𝖈', callback_data='style+gothic_bolt'), + ],[ + InlineKeyboardButton('C͜͡l͜͡o͜͡u͜͡d͜͡s͜͡', callback_data='style+cloud'), + InlineKeyboardButton('H̆̈ă̈p̆̈p̆̈y̆̈', callback_data='style+happy'), + InlineKeyboardButton('S̑̈ȃ̈d̑̈', callback_data='style+sad'), + ],[ + InlineKeyboardButton('Next ➡️', callback_data="nxt") + ]] + if not cb: + await m.reply_text(m.text, reply_markup=InlineKeyboardMarkup(buttons), quote=True) + else: + await m.answer() + await m.message.edit_reply_markup(InlineKeyboardMarkup(buttons)) + + +@Client.on_callback_query(filters.regex('^nxt')) +async def nxt(c, m): + if m.data == "nxt": + buttons = [[ + InlineKeyboardButton('🇸 🇵 🇪 🇨 🇮 🇦 🇱 ', callback_data='style+special'), + InlineKeyboardButton('🅂🅀🅄🄰🅁🄴🅂', callback_data='style+squares'), + InlineKeyboardButton('🆂︎🆀︎🆄︎🅰︎🆁︎🅴︎🆂︎', callback_data='style+squares_bold'), + ],[ + InlineKeyboardButton('ꪖꪀᦔꪖꪶꪊᥴ𝓲ꪖ', callback_data='style+andalucia'), + InlineKeyboardButton('爪卂几ᘜ卂', callback_data='style+manga'), + InlineKeyboardButton('S̾t̾i̾n̾k̾y̾', callback_data='style+stinky'), + ],[ + InlineKeyboardButton('B̥ͦu̥ͦb̥ͦb̥ͦl̥ͦe̥ͦs̥ͦ', callback_data='style+bubbles'), + InlineKeyboardButton('U͟n͟d͟e͟r͟l͟i͟n͟e͟', callback_data='style+underline'), + InlineKeyboardButton('꒒ꍏꀷꌩꌃꀎꁅ', callback_data='style+ladybug'), + ],[ + InlineKeyboardButton('R҉a҉y҉s҉', callback_data='style+rays'), + InlineKeyboardButton('B҈i҈r҈d҈s҈', callback_data='style+birds'), + InlineKeyboardButton('S̸l̸a̸s̸h̸', callback_data='style+slash'), + ],[ + InlineKeyboardButton('s⃠t⃠o⃠p⃠', callback_data='style+stop'), + InlineKeyboardButton('S̺͆k̺͆y̺͆l̺͆i̺͆n̺͆e̺͆', callback_data='style+skyline'), + InlineKeyboardButton('A͎r͎r͎o͎w͎s͎', callback_data='style+arrows'), + ],[ + InlineKeyboardButton('ዪሀክቿነ', callback_data='style+qvnes'), + InlineKeyboardButton('S̶t̶r̶i̶k̶e̶', callback_data='style+strike'), + InlineKeyboardButton('F༙r༙o༙z༙e༙n༙', callback_data='style+frozen') + ],[ + InlineKeyboardButton('⬅️ Back', callback_data='nxt+0') + ]] + await m.answer() + await m.message.edit_reply_markup(InlineKeyboardMarkup(buttons)) + else: + await style_buttons(c, m, cb=True) + + +@Client.on_callback_query(filters.regex('^style')) +async def style(c, m): + await m.answer() + cmd, style = m.data.split('+') + + if style == 'typewriter': + cls = Fonts.typewriter + if style == 'outline': + cls = Fonts.outline + if style == 'serif': + cls = Fonts.serief + if style == 'bold_cool': + cls = Fonts.bold_cool + if style == 'cool': + cls = Fonts.cool + if style == 'small_cap': + cls = Fonts.smallcap + if style == 'script': + cls = Fonts.script + if style == 'script_bolt': + cls = Fonts.bold_script + if style == 'tiny': + cls = Fonts.tiny + if style == 'comic': + cls = Fonts.comic + if style == 'sans': + cls = Fonts.san + if style == 'slant_sans': + cls = Fonts.slant_san + if style == 'slant': + cls = Fonts.slant + if style == 'sim': + cls = Fonts.sim + if style == 'circles': + cls = Fonts.circles + if style == 'circle_dark': + cls = Fonts.dark_circle + if style == 'gothic': + cls = Fonts.gothic + if style == 'gothic_bolt': + cls = Fonts.bold_gothic + if style == 'cloud': + cls = Fonts.cloud + if style == 'happy': + cls = Fonts.happy + if style == 'sad': + cls = Fonts.sad + if style == 'special': + cls = Fonts.special + if style == 'squares': + cls = Fonts.square + if style == 'squares_bold': + cls = Fonts.dark_square + if style == 'andalucia': + cls = Fonts.andalucia + if style == 'manga': + cls = Fonts.manga + if style == 'stinky': + cls = Fonts.stinky + if style == 'bubbles': + cls = Fonts.bubbles + if style == 'underline': + cls = Fonts.underline + if style == 'ladybug': + cls = Fonts.ladybug + if style == 'rays': + cls = Fonts.rays + if style == 'birds': + cls = Fonts.birds + if style == 'slash': + cls = Fonts.slash + if style == 'stop': + cls = Fonts.stop + if style == 'skyline': + cls = Fonts.skyline + if style == 'arrows': + cls = Fonts.arrows + if style == 'qvnes': + cls = Fonts.rvnes + if style == 'strike': + cls = Fonts.strike + if style == 'frozen': + cls = Fonts.frozen + new_text = cls(m.message.reply_to_message.text) + try: + await m.message.edit_text(new_text, reply_markup=m.message.reply_markup) + except: + pass diff --git a/akn/MagicFonts/fonts.py b/akn/MagicFonts/fonts.py new file mode 100755 index 0000000000000000000000000000000000000000..5816f0cdf84f6fcc679b92dfbe3c13343e37f1ea --- /dev/null +++ b/akn/MagicFonts/fonts.py @@ -0,0 +1,2364 @@ + +class Fonts: + def typewriter(text): + style = { + 'a': '𝚊', + 'b': '𝚋', + 'c': '𝚌', + 'd': '𝚍', + 'e': '𝚎', + 'f': '𝚏', + 'g': '𝚐', + 'h': '𝚑', + 'i': '𝚒', + 'j': '𝚓', + 'k': '𝚔', + 'l': '𝚕', + 'm': '𝚖', + 'n': '𝚗', + 'o': '𝚘', + 'p': '𝚙', + 'q': '𝚚', + 'r': '𝚛', + 's': '𝚜', + 't': '𝚝', + 'u': '𝚞', + 'v': '𝚟', + 'w': '𝚠', + 'x': '𝚡', + 'y': '𝚢', + 'z': '𝚣', + 'A': '𝙰', + 'B': '𝙱', + 'C': '𝙲', + 'D': '𝙳', + 'E': '𝙴', + 'F': '𝙵', + 'G': '𝙶', + 'H': '𝙷', + 'I': '𝙸', + 'J': '𝙹', + 'K': '𝙺', + 'L': '𝙻', + 'M': '𝙼', + 'N': '𝙽', + 'O': '𝙾', + 'P': '𝙿', + 'Q': '𝚀', + 'R': '𝚁', + 'S': '𝚂', + 'T': '𝚃', + 'U': '𝚄', + 'V': '𝚅', + 'W': '𝚆', + 'X': '𝚇', + 'Y': '𝚈', + 'Z': '𝚉' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def outline(text): + style = { + 'a': '𝕒', + 'b': '𝕓', + 'c': '𝕔', + 'd': '𝕕', + 'e': '𝕖', + 'f': '𝕗', + 'g': '𝕘', + 'h': '𝕙', + 'i': '𝕚', + 'j': '𝕛', + 'k': '𝕜', + 'l': '𝕝', + 'm': '𝕞', + 'n': '𝕟', + 'o': '𝕠', + 'p': '𝕡', + 'q': '𝕢', + 'r': '𝕣', + 's': '𝕤', + 't': '𝕥', + 'u': '𝕦', + 'v': '𝕧', + 'w': '𝕨', + 'x': '𝕩', + 'y': '𝕪', + 'z': '𝕫', + 'A': '𝔸', + 'B': '𝔹', + 'C': 'ℂ', + 'D': '𝔻', + 'E': '𝔼', + 'F': '𝔽', + 'G': '𝔾', + 'H': 'ℍ', + 'I': '𝕀', + 'J': '𝕁', + 'K': '𝕂', + 'L': '𝕃', + 'M': '𝕄', + 'N': 'ℕ', + 'O': '𝕆', + 'P': 'ℙ', + 'Q': 'ℚ', + 'R': 'ℝ', + 'S': '𝕊', + 'T': '𝕋', + 'U': '𝕌', + 'V': '𝕍', + 'W': '𝕎', + 'X': '𝕏', + 'Y': '𝕐', + 'Z': 'ℤ', + '0': '𝟘', + '1': '𝟙', + '2': '𝟚', + '3': '𝟛', + '4': '𝟜', + '5': '𝟝', + '6': '𝟞', + '7': '𝟟', + '8': '𝟠', + '9': '𝟡' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def serief(text): + style = { + 'a': '𝐚', + 'b': '𝐛', + 'c': '𝐜', + 'd': '𝐝', + 'e': '𝐞', + 'f': '𝐟', + 'g': '𝐠', + 'h': '𝐡', + 'i': '𝐢', + 'j': '𝐣', + 'k': '𝐤', + 'l': '𝐥', + 'm': '𝐦', + 'n': '𝐧', + 'o': '𝐨', + 'p': '𝐩', + 'q': '𝐪', + 'r': '𝐫', + 's': '𝐬', + 't': '𝐭', + 'u': '𝐮', + 'v': '𝐯', + 'w': '𝐰', + 'x': '𝐱', + 'y': '𝐲', + 'z': '𝐳', + 'A': '𝐀', + 'B': '𝐁', + 'C': '𝐂', + 'D': '𝐃', + 'E': '𝐄', + 'F': '𝐅', + 'G': '𝐆', + 'H': '𝐇', + 'I': '𝐈', + 'J': '𝐉', + 'K': '𝐊', + 'L': '𝐋', + 'M': '𝐌', + 'N': '𝐍', + 'O': '𝐎', + 'P': '𝐏', + 'Q': '𝐐', + 'R': '𝐑', + 'S': '𝐒', + 'T': '𝐓', + 'U': '𝐔', + 'V': '𝐕', + 'W': '𝐖', + 'X': '𝐗', + 'Y': '𝐘', + 'Z': '𝐙', + '0': '𝟎', + '1': '𝟏', + '2': '𝟐', + '3': '𝟑', + '4': '𝟒', + '5': '𝟓', + '6': '𝟔', + '7': '𝟕', + '8': '𝟖', + '9': '𝟗' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def bold_cool(text): + style = { + 'a': '𝒂', + 'b': '𝒃', + 'c': '𝒄', + 'd': '𝒅', + 'e': '𝒆', + 'f': '𝒇', + 'g': '𝒈', + 'h': '𝒉', + 'i': '𝒊', + 'j': '𝒋', + 'k': '𝒌', + 'l': '𝒍', + 'm': '𝒎', + 'n': '𝒏', + 'o': '𝒐', + 'p': '𝒑', + 'q': '𝒒', + 'r': '𝒓', + 's': '𝒔', + 't': '𝒕', + 'u': '𝒖', + 'v': '𝒗', + 'w': '𝒘', + 'x': '𝒙', + 'y': '𝒚', + 'z': '𝒛', + 'A': '𝑨', + 'B': '𝑩', + 'C': '𝑪', + 'D': '𝑫', + 'E': '𝑬', + 'F': '𝑭', + 'G': '𝑮', + 'H': '𝑯', + 'I': '𝑰', + 'J': '𝑱', + 'K': '𝑲', + 'L': '𝑳', + 'M': '𝑴', + 'N': '𝑵', + 'O': '𝑶', + 'P': '𝑷', + 'Q': '𝑸', + 'R': '𝑹', + 'S': '𝑺', + 'T': '𝑻', + 'U': '𝑼', + 'V': '𝑽', + 'W': '𝑾', + 'X': '𝑿', + 'Y': '𝒀', + 'Z': '𝒁' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def cool(text): + style = { + 'a': '𝑎', + 'b': '𝑏', + 'c': '𝑐', + 'd': '𝑑', + 'e': '𝑒', + 'f': '𝑓', + 'g': '𝑔', + 'h': 'ℎ', + 'i': '𝑖', + 'j': '𝑗', + 'k': '𝑘', + 'l': '𝑙', + 'm': '𝑚', + 'n': '𝑛', + 'o': '𝑜', + 'p': '𝑝', + 'q': '𝑞', + 'r': '𝑟', + 's': '𝑠', + 't': '𝑡', + 'u': '𝑢', + 'v': '𝑣', + 'w': '𝑤', + 'x': '𝑥', + 'y': '𝑦', + 'z': '𝑧', + 'A': '𝐴', + 'B': '𝐵', + 'C': '𝐶', + 'D': '𝐷', + 'E': '𝐸', + 'F': '𝐹', + 'G': '𝐺', + 'H': '𝐻', + 'I': '𝐼', + 'J': '𝐽', + 'K': '𝐾', + 'L': '𝐿', + 'M': '𝑀', + 'N': '𝑁', + 'O': '𝑂', + 'P': '𝑃', + 'Q': '𝑄', + 'R': '𝑅', + 'S': '𝑆', + 'T': '𝑇', + 'U': '𝑈', + 'V': '𝑉', + 'W': '𝑊', + 'X': '𝑋', + 'Y': '𝑌', + 'Z': '𝑍' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def smallcap(text): + style = { + 'a': 'ᴀ', + 'b': 'ʙ', + 'c': 'ᴄ', + 'd': 'ᴅ', + 'e': 'ᴇ', + 'f': 'ғ', + 'g': 'ɢ', + 'h': 'ʜ', + 'i': 'ɪ', + 'j': 'ɪ', + 'k': 'ᴋ', + 'l': 'ʟ', + 'm': 'ᴍ', + 'n': 'ɴ', + 'o': 'ᴏ', + 'p': 'ᴘ', + 'q': 'ǫ', + 'r': 'ʀ', + 's': 's', + 't': 'ᴛ', + 'u': 'ᴜ', + 'v': 'ᴠ', + 'w': 'ᴡ', + 'x': 'x', + 'y': 'ʏ', + 'z': 'ᴢ', + 'A': 'A', + 'B': 'B', + 'C': 'C', + 'D': 'D', + 'E': 'E', + 'F': 'F', + 'G': 'G', + 'H': 'H', + 'I': 'I', + 'J': 'J', + 'K': 'K', + 'L': 'L', + 'M': 'M', + 'N': 'N', + 'O': 'O', + 'P': 'P', + 'Q': 'Q', + 'R': 'R', + 'S': 'S', + 'T': 'T', + 'U': 'U', + 'V': 'V', + 'W': 'W', + 'X': 'X', + 'Y': 'Y', + 'Z': 'Z', + '0': '𝟶', + '1': '𝟷', + '2': '𝟸', + '3': '𝟹', + '4': '𝟺', + '5': '𝟻', + '6': '𝟼', + '7': '𝟽', + '8': '𝟾', + '9': '𝟿' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def script(text): + style = { + 'a': '𝒶', + 'b': '𝒷', + 'c': '𝒸', + 'd': '𝒹', + 'e': 'ℯ', + 'f': '𝒻', + 'g': 'ℊ', + 'h': '𝒽', + 'i': '𝒾', + 'j': '𝒿', + 'k': '𝓀', + 'l': '𝓁', + 'm': '𝓂', + 'n': '𝓃', + 'o': 'ℴ', + 'p': '𝓅', + 'q': '𝓆', + 'r': '𝓇', + 's': '𝓈', + 't': '𝓉', + 'u': '𝓊', + 'v': '𝓋', + 'w': '𝓌', + 'x': '𝓍', + 'y': '𝓎', + 'z': '𝓏', + 'A': '𝒜', + 'B': 'ℬ', + 'C': '𝒞', + 'D': '𝒟', + 'E': 'ℰ', + 'F': 'ℱ', + 'G': '𝒢', + 'H': 'ℋ', + 'I': 'ℐ', + 'J': '𝒥', + 'K': '𝒦', + 'L': 'ℒ', + 'M': 'ℳ', + 'N': '𝒩', + 'O': '𝒪', + 'P': '𝒫', + 'Q': '𝒬', + 'R': 'ℛ', + 'S': '𝒮', + 'T': '𝒯', + 'U': '𝒰', + 'V': '𝒱', + 'W': '𝒲', + 'X': '𝒳', + 'Y': '𝒴', + 'Z': '𝒵' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def bold_script(text): + style = { + 'a': '𝓪', + 'b': '𝓫', + 'c': '𝓬', + 'd': '𝓭', + 'e': '𝓮', + 'f': '𝓯', + 'g': '𝓰', + 'h': '𝓱', + 'i': '𝓲', + 'j': '𝓳', + 'k': '𝓴', + 'l': '𝓵', + 'm': '𝓶', + 'n': '𝓷', + 'o': '𝓸', + 'p': '𝓹', + 'q': '𝓺', + 'r': '𝓻', + 's': '𝓼', + 't': '𝓽', + 'u': '𝓾', + 'v': '𝓿', + 'w': '𝔀', + 'x': '𝔁', + 'y': '𝔂', + 'z': '𝔃', + 'A': '𝓐', + 'B': '𝓑', + 'C': '𝓒', + 'D': '𝓓', + 'E': '𝓔', + 'F': '𝓕', + 'G': '𝓖', + 'H': '𝓗', + 'I': '𝓘', + 'J': '𝓙', + 'K': '𝓚', + 'L': '𝓛', + 'M': '𝓜', + 'N': '𝓝', + 'O': '𝓞', + 'P': '𝓟', + 'Q': '𝓠', + 'R': '𝓡', + 'S': '𝓢', + 'T': '𝓣', + 'U': '𝓤', + 'V': '𝓥', + 'W': '𝓦', + 'X': '𝓧', + 'Y': '𝓨', + 'Z': '𝓩' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def tiny(text): + style = { + 'a': 'ᵃ', + 'b': 'ᵇ', + 'c': 'ᶜ', + 'd': 'ᵈ', + 'e': 'ᵉ', + 'f': 'ᶠ', + 'g': 'ᵍ', + 'h': 'ʰ', + 'i': 'ⁱ', + 'j': 'ʲ', + 'k': 'ᵏ', + 'l': 'ˡ', + 'm': 'ᵐ', + 'n': 'ⁿ', + 'o': 'ᵒ', + 'p': 'ᵖ', + 'q': 'ᵠ', + 'r': 'ʳ', + 's': 'ˢ', + 't': 'ᵗ', + 'u': 'ᵘ', + 'v': 'ᵛ', + 'w': 'ʷ', + 'x': 'ˣ', + 'y': 'ʸ', + 'z': 'ᶻ', + 'A': 'ᵃ', + 'B': 'ᵇ', + 'C': 'ᶜ', + 'D': 'ᵈ', + 'E': 'ᵉ', + 'F': 'ᶠ', + 'G': 'ᵍ', + 'H': 'ʰ', + 'I': 'ⁱ', + 'J': 'ʲ', + 'K': 'ᵏ', + 'L': 'ˡ', + 'M': 'ᵐ', + 'N': 'ⁿ', + 'O': 'ᵒ', + 'P': 'ᵖ', + 'Q': 'ᵠ', + 'R': 'ʳ', + 'S': 'ˢ', + 'T': 'ᵗ', + 'U': 'ᵘ', + 'V': 'ᵛ', + 'W': 'ʷ', + 'X': 'ˣ', + 'Y': 'ʸ', + 'Z': 'ᶻ' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def comic(text): + style = { + 'a': 'ᗩ', + 'b': 'ᗷ', + 'c': 'ᑕ', + 'd': 'ᗪ', + 'e': 'ᗴ', + 'f': 'ᖴ', + 'g': 'ᘜ', + 'h': 'ᕼ', + 'i': 'I', + 'j': 'ᒍ', + 'k': 'K', + 'l': 'ᒪ', + 'm': 'ᗰ', + 'n': 'ᑎ', + 'o': 'O', + 'p': 'ᑭ', + 'q': 'ᑫ', + 'r': 'ᖇ', + 's': 'Տ', + 't': 'T', + 'u': 'ᑌ', + 'v': 'ᐯ', + 'w': 'ᗯ', + 'x': '᙭', + 'y': 'Y', + 'z': 'ᘔ', + 'A': 'ᗩ', + 'B': 'ᗷ', + 'C': 'ᑕ', + 'D': 'ᗪ', + 'E': 'ᗴ', + 'F': 'ᖴ', + 'G': 'ᘜ', + 'H': 'ᕼ', + 'I': 'I', + 'J': 'ᒍ', + 'K': 'K', + 'L': 'ᒪ', + 'M': 'ᗰ', + 'N': 'ᑎ', + 'O': 'O', + 'P': 'ᑭ', + 'Q': 'ᑫ', + 'R': 'ᖇ', + 'S': 'Տ', + 'T': 'T', + 'U': 'ᑌ', + 'V': 'ᐯ', + 'W': 'ᗯ', + 'X': '᙭', + 'Y': 'Y', + 'Z': 'ᘔ' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def san(text): + style = { + 'a': '𝗮', + 'b': '𝗯', + 'c': '𝗰', + 'd': '𝗱', + 'e': '𝗲', + 'f': '𝗳', + 'g': '𝗴', + 'h': '𝗵', + 'i': '𝗶', + 'j': '𝗷', + 'k': '𝗸', + 'l': '𝗹', + 'm': '𝗺', + 'n': '𝗻', + 'o': '𝗼', + 'p': '𝗽', + 'q': '𝗾', + 'r': '𝗿', + 's': '𝘀', + 't': '𝘁', + 'u': '𝘂', + 'v': '𝘃', + 'w': '𝘄', + 'x': '𝘅', + 'y': '𝘆', + 'z': '𝘇', + 'A': '𝗔', + 'B': '𝗕', + 'C': '𝗖', + 'D': '𝗗', + 'E': '𝗘', + 'F': '𝗙', + 'G': '𝗚', + 'H': '𝗛', + 'I': '𝗜', + 'J': '𝗝', + 'K': '𝗞', + 'L': '𝗟', + 'M': '𝗠', + 'N': '𝗡', + 'O': '𝗢', + 'P': '𝗣', + 'Q': '𝗤', + 'R': '𝗥', + 'S': '𝗦', + 'T': '𝗧', + 'U': '𝗨', + 'V': '𝗩', + 'W': '𝗪', + 'X': '𝗫', + 'Y': '𝗬', + 'Z': '𝗭', + '0': '𝟬', + '1': '𝟭', + '2': '𝟮', + '3': '𝟯', + '4': '𝟰', + '5': '𝟱', + '6': '𝟲', + '7': '𝟳', + '8': '𝟴', + '9': '𝟵' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def slant_san(text): + style = { + 'a': '𝙖', + 'b': '𝙗', + 'c': '𝙘', + 'd': '𝙙', + 'e': '𝙚', + 'f': '𝙛', + 'g': '𝙜', + 'h': '𝙝', + 'i': '𝙞', + 'j': '𝙟', + 'k': '𝙠', + 'l': '𝙡', + 'm': '𝙢', + 'n': '𝙣', + 'o': '𝙤', + 'p': '𝙥', + 'q': '𝙦', + 'r': '𝙧', + 's': '𝙨', + 't': '𝙩', + 'u': '𝙪', + 'v': '𝙫', + 'w': '𝙬', + 'x': '𝙭', + 'y': '𝙮', + 'z': '𝙯', + 'A': '𝘼', + 'B': '𝘽', + 'C': '𝘾', + 'D': '𝘿', + 'E': '𝙀', + 'F': '𝙁', + 'G': '𝙂', + 'H': '𝙃', + 'I': '𝙄', + 'J': '𝙅', + 'K': '𝙆', + 'L': '𝙇', + 'M': '𝙈', + 'N': '𝙉', + 'O': '𝙊', + 'P': '𝙋', + 'Q': '𝙌', + 'R': '𝙍', + 'S': '𝙎', + 'T': '𝙏', + 'U': '𝙐', + 'V': '𝙑', + 'W': '𝙒', + 'X': '𝙓', + 'Y': '𝙔', + 'Z': '𝙕' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def slant(text): + style = { + 'a': '𝘢', + 'b': '𝘣', + 'c': '𝘤', + 'd': '𝘥', + 'e': '𝘦', + 'f': '𝘧', + 'g': '𝘨', + 'h': '𝘩', + 'i': '𝘪', + 'j': '𝘫', + 'k': '𝘬', + 'l': '𝘭', + 'm': '𝘮', + 'n': '𝘯', + 'o': '𝘰', + 'p': '𝘱', + 'q': '𝘲', + 'r': '𝘳', + 's': '𝘴', + 't': '𝘵', + 'u': '𝘶', + 'v': '𝘷', + 'w': '𝘸', + 'x': '𝘹', + 'y': '𝘺', + 'z': '𝘻', + 'A': '𝘈', + 'B': '𝘉', + 'C': '𝘊', + 'D': '𝘋', + 'E': '𝘌', + 'F': '𝘍', + 'G': '𝘎', + 'H': '𝘏', + 'I': '𝘐', + 'J': '𝘑', + 'K': '𝘒', + 'L': '𝘓', + 'M': '𝘔', + 'N': '𝘕', + 'O': '𝘖', + 'P': '𝘗', + 'Q': '𝘘', + 'R': '𝘙', + 'S': '𝘚', + 'T': '𝘛', + 'U': '𝘜', + 'V': '𝘝', + 'W': '𝘞', + 'X': '𝘟', + 'Y': '𝘠', + 'Z': '𝘡' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def sim(text): + style = { + 'a': '𝖺', + 'b': '𝖻', + 'c': '𝖼', + 'd': '𝖽', + 'e': '𝖾', + 'f': '𝖿', + 'g': '𝗀', + 'h': '𝗁', + 'i': '𝗂', + 'j': '𝗃', + 'k': '𝗄', + 'l': '𝗅', + 'm': '𝗆', + 'n': '𝗇', + 'o': '𝗈', + 'p': '𝗉', + 'q': '𝗊', + 'r': '𝗋', + 's': '𝗌', + 't': '𝗍', + 'u': '𝗎', + 'v': '𝗏', + 'w': '𝗐', + 'x': '𝗑', + 'y': '𝗒', + 'z': '𝗓', + 'A': '𝖠', + 'B': '𝖡', + 'C': '𝖢', + 'D': '𝖣', + 'E': '𝖤', + 'F': '𝖥', + 'G': '𝖦', + 'H': '𝖧', + 'I': '𝖨', + 'J': '𝖩', + 'K': '𝖪', + 'L': '𝖫', + 'M': '𝖬', + 'N': '𝖭', + 'O': '𝖮', + 'P': '𝖯', + 'Q': '𝖰', + 'R': '𝖱', + 'S': '𝖲', + 'T': '𝖳', + 'U': '𝖴', + 'V': '𝖵', + 'W': '𝖶', + 'X': '𝖷', + 'Y': '𝖸', + 'Z': '𝖹' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def circles(text): + style = { + 'a': 'Ⓐ︎', + 'b': 'Ⓑ︎', + 'c': 'Ⓒ︎', + 'd': 'Ⓓ︎', + 'e': 'Ⓔ︎', + 'f': 'Ⓕ︎', + 'g': 'Ⓖ︎', + 'h': 'Ⓗ︎', + 'i': 'Ⓘ︎', + 'j': 'Ⓙ︎', + 'k': 'Ⓚ︎', + 'l': 'Ⓛ︎', + 'm': 'Ⓜ︎', + 'n': 'Ⓝ︎', + 'o': 'Ⓞ︎', + 'p': 'Ⓟ︎', + 'q': 'Ⓠ︎', + 'r': 'Ⓡ︎', + 's': 'Ⓢ︎', + 't': 'Ⓣ︎', + 'u': 'Ⓤ︎', + 'v': 'Ⓥ︎', + 'w': 'Ⓦ︎', + 'x': 'Ⓧ︎', + 'y': 'Ⓨ︎', + 'z': 'Ⓩ︎', + 'A': 'Ⓐ︎', + 'B': 'Ⓑ︎', + 'C': 'Ⓒ︎', + 'D': 'Ⓓ︎', + 'E': 'Ⓔ︎', + 'F': 'Ⓕ︎', + 'G': 'Ⓖ︎', + 'H': 'Ⓗ︎', + 'I': 'Ⓘ︎', + 'J': 'Ⓙ︎', + 'K': 'Ⓚ︎', + 'L': 'Ⓛ︎', + 'M': 'Ⓜ︎', + 'N': 'Ⓝ︎', + 'O': 'Ⓞ︎', + 'P': 'Ⓟ︎', + 'Q': 'Ⓠ︎', + 'R': 'Ⓡ︎', + 'S': 'Ⓢ︎', + 'T': 'Ⓣ︎', + 'U': 'Ⓤ︎', + 'V': 'Ⓥ︎', + 'W': 'Ⓦ︎', + 'X': 'Ⓧ︎', + 'Y': 'Ⓨ︎', + 'Z': 'Ⓩ︎', + '0': '⓪', + '1': '①', + '2': '②', + '3': '③', + '4': '④', + '5': '⑤', + '6': '⑥', + '7': '⑦', + '8': '⑧', + '9': '⑨' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def dark_circle(text): + style = { + 'a': '🅐︎', + 'b': '🅑︎', + 'c': '🅒︎', + 'd': '🅓︎', + 'e': '🅔︎', + 'f': '🅕︎', + 'g': '🅖︎', + 'h': '🅗︎', + 'i': '🅘︎', + 'j': '🅙︎', + 'k': '🅚︎', + 'l': '🅛︎', + 'm': '🅜︎', + 'n': '🅝︎', + 'o': '🅞︎', + 'p': '🅟︎', + 'q': '🅠︎', + 'r': '🅡︎', + 's': '🅢︎', + 't': '🅣︎', + 'u': '🅤︎', + 'v': '🅥︎', + 'w': '🅦︎', + 'x': '🅧︎', + 'y': '🅨︎', + 'z': '🅩︎', + 'A': '🅐︎', + 'B': '🅑︎', + 'C': '🅒︎', + 'D': '🅓︎', + 'E': '🅔︎', + 'F': '🅕︎', + 'G': '🅖︎', + 'H': '🅗︎', + 'I': '🅘︎', + 'J': '🅙︎', + 'K': '🅚︎', + 'L': '🅛︎', + 'M': '🅜︎', + 'N': '🅝︎', + 'O': '🅞︎', + 'P': '🅟︎', + 'Q': '🅠︎', + 'R': '🅡︎', + 'S': '🅢︎', + 'T': '🅣︎', + 'U': '🅤︎', + 'V': '🅥︎', + 'W': '🅦︎', + 'X': '🅧︎', + 'Y': '🅨︎', + 'Z': '🅩', + '0': '⓿', + '1': '➊', + '2': '➋', + '3': '➌', + '4': '➍', + '5': '➎', + '6': '➏', + '7': '➐', + '8': '➑', + '9': '➒' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def gothic(text): + style = { + 'a': '𝔞', + 'b': '𝔟', + 'c': '𝔠', + 'd': '𝔡', + 'e': '𝔢', + 'f': '𝔣', + 'g': '𝔤', + 'h': '𝔥', + 'i': '𝔦', + 'j': '𝔧', + 'k': '𝔨', + 'l': '𝔩', + 'm': '𝔪', + 'n': '𝔫', + 'o': '𝔬', + 'p': '𝔭', + 'q': '𝔮', + 'r': '𝔯', + 's': '𝔰', + 't': '𝔱', + 'u': '𝔲', + 'v': '𝔳', + 'w': '𝔴', + 'x': '𝔵', + 'y': '𝔶', + 'z': '𝔷', + 'A': '𝔄', + 'B': '𝔅', + 'C': 'ℭ', + 'D': '𝔇', + 'E': '𝔈', + 'F': '𝔉', + 'G': '𝔊', + 'H': 'ℌ', + 'I': 'ℑ', + 'J': '𝔍', + 'K': '𝔎', + 'L': '𝔏', + 'M': '𝔐', + 'N': '𝔑', + 'O': '𝔒', + 'P': '𝔓', + 'Q': '𝔔', + 'R': 'ℜ', + 'S': '𝔖', + 'T': '𝔗', + 'U': '𝔘', + 'V': '𝔙', + 'W': '𝔚', + 'X': '𝔛', + 'Y': '𝔜', + 'Z': 'ℨ' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + + def bold_gothic(text): + style = { + 'a': '𝖆', + 'b': '𝖇', + 'c': '𝖈', + 'd': '𝖉', + 'e': '𝖊', + 'f': '𝖋', + 'g': '𝖌', + 'h': '𝖍', + 'i': '𝖎', + 'j': '𝖏', + 'k': '𝖐', + 'l': '𝖑', + 'm': '𝖒', + 'n': '𝖓', + 'o': '𝖔', + 'p': '𝖕', + 'q': '𝖖', + 'r': '𝖗', + 's': '𝖘', + 't': '𝖙', + 'u': '𝖚', + 'v': '𝖛', + 'w': '𝖜', + 'x': '𝖝', + 'y': '𝖞', + 'z': '𝖟', + 'A': '𝕬', + 'B': '𝕭', + 'C': '𝕮', + 'D': '𝕺', + 'E': '𝕰', + 'F': '𝕱', + 'G': '𝕲', + 'H': '𝕳', + 'I': '𝕴', + 'J': '𝕵', + 'K': '𝕶', + 'L': '𝕷', + 'M': '𝕸', + 'N': '𝕹', + 'O': '𝕺', + 'P': '𝕻', + 'Q': '𝕼', + 'R': '𝕽', + 'S': '𝕾', + 'T': '𝕿', + 'U': '𝖀', + 'V': '𝖁', + 'W': '𝖂', + 'X': '𝖃', + 'Y': '𝖄', + 'Z': '𝖅' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def cloud(text): + style = { + 'a': 'a͜͡', + 'b': 'b͜͡', + 'c': 'c͜͡', + 'd': 'd͜͡', + 'e': 'e͜͡', + 'f': 'f͜͡', + 'g': 'g͜͡', + 'h': 'h͜͡', + 'i': 'i͜͡', + 'j': 'j͜͡', + 'k': 'k͜͡', + 'l': 'l͜͡', + 'm': 'm͜͡', + 'n': 'n͜͡', + 'o': 'o͜͡', + 'p': 'p͜͡', + 'q': 'q͜͡', + 'r': 'r͜͡', + 's': 's͜͡', + 't': 't͜͡', + 'u': 'u͜͡', + 'v': 'v͜͡', + 'w': 'w͜͡', + 'x': 'x͜͡', + 'y': 'y͜͡', + 'z': 'z͜͡', + 'A': 'A͜͡', + 'B': 'B͜͡', + 'C': 'C͜͡', + 'D': 'D͜͡', + 'E': 'E͜͡', + 'F': 'F͜͡', + 'G': 'G͜͡', + 'H': 'H͜͡', + 'I': 'I͜͡', + 'J': 'J͜͡', + 'K': 'K͜͡', + 'L': 'L͜͡', + 'M': 'M͜͡', + 'N': 'N͜͡', + 'O': 'O͜͡', + 'P': 'P͜͡', + 'Q': 'Q͜͡', + 'R': 'R͜͡', + 'S': 'S͜͡', + 'T': 'T͜͡', + 'U': 'U͜͡', + 'V': 'V͜͡', + 'W': 'W͜͡', + 'X': 'X͜͡', + 'Y': 'Y͜͡', + 'Z': 'Z͜͡' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def happy(text): + style = { + 'a': 'ă̈', + 'b': 'b̆̈', + 'c': 'c̆̈', + 'd': 'd̆̈', + 'e': 'ĕ̈', + 'f': 'f̆̈', + 'g': 'ğ̈', + 'h': 'h̆̈', + 'i': 'ĭ̈', + 'j': 'j̆̈', + 'k': 'k̆̈', + 'l': 'l̆̈', + 'm': 'm̆̈', + 'n': 'n̆̈', + 'o': 'ŏ̈', + 'p': 'p̆̈', + 'q': 'q̆̈', + 'r': 'r̆̈', + 's': 's̆̈', + 't': 't̆̈', + 'u': 'ŭ̈', + 'v': 'v̆̈', + 'w': 'w̆̈', + 'x': 'x̆̈', + 'y': 'y̆̈', + 'z': 'z̆̈', + 'A': 'Ă̈', + 'B': 'B̆̈', + 'C': 'C̆̈', + 'D': 'D̆̈', + 'E': 'Ĕ̈', + 'F': 'F̆̈', + 'G': 'Ğ̈', + 'H': 'H̆̈', + 'I': 'Ĭ̈', + 'J': 'J̆̈', + 'K': 'K̆̈', + 'L': 'L̆̈', + 'M': 'M̆̈', + 'N': 'N̆̈', + 'O': 'Ŏ̈', + 'P': 'P̆̈', + 'Q': 'Q̆̈', + 'R': 'R̆̈', + 'S': 'S̆̈', + 'T': 'T̆̈', + 'U': 'Ŭ̈', + 'V': 'V̆̈', + 'W': 'W̆̈', + 'X': 'X̆̈', + 'Y': 'Y̆̈', + 'Z': 'Z̆̈' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def sad(text): + style = { + 'a': 'ȃ̈', + 'b': 'b̑̈', + 'c': 'c̑̈', + 'd': 'd̑̈', + 'e': 'ȇ̈', + 'f': 'f̑̈', + 'g': 'g̑̈', + 'h': 'h̑̈', + 'i': 'ȋ̈', + 'j': 'j̑̈', + 'k': 'k̑̈', + 'l': 'l̑̈', + 'm': 'm̑̈', + 'n': 'n̑̈', + 'o': 'ȏ̈', + 'p': 'p̑̈', + 'q': 'q̑̈', + 'r': 'ȓ̈', + 's': 's̑̈', + 't': 't̑̈', + 'u': 'ȗ̈', + 'v': 'v̑̈', + 'w': 'w̑̈', + 'x': 'x̑̈', + 'y': 'y̑̈', + 'z': 'z̑̈', + 'A': 'Ȃ̈', + 'B': 'B̑̈', + 'C': 'C̑̈', + 'D': 'D̑̈', + 'E': 'Ȇ̈', + 'F': 'F̑̈', + 'G': 'G̑̈', + 'H': 'H̑̈', + 'I': 'Ȋ̈', + 'J': 'J̑̈', + 'K': 'K̑̈', + 'L': 'L̑̈', + 'M': 'M̑̈', + 'N': 'N̑̈', + 'O': 'Ȏ̈', + 'P': 'P̑̈', + 'Q': 'Q̑̈', + 'R': 'Ȓ̈', + 'S': 'S̑̈', + 'T': 'T̑̈', + 'U': 'Ȗ̈', + 'V': 'V̑̈', + 'W': 'W̑̈', + 'X': 'X̑̈', + 'Y': 'Y̑̈', + 'Z': 'Z̑̈' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def special(text): + style = { + 'a': '🇦 ', + 'b': '🇧 ', + 'c': '🇨 ', + 'd': '🇩 ', + 'e': '🇪 ', + 'f': '🇫 ', + 'g': '🇬 ', + 'h': '🇭 ', + 'i': '🇮 ', + 'j': '🇯 ', + 'k': '🇰 ', + 'l': '🇱 ', + 'm': '🇲 ', + 'n': '🇳 ', + 'o': '🇴 ', + 'p': '🇵 ', + 'q': '🇶 ', + 'r': '🇷 ', + 's': '🇸 ', + 't': '🇹 ', + 'u': '🇺 ', + 'v': '🇻 ', + 'w': '🇼 ', + 'x': '🇽 ', + 'y': '🇾 ', + 'z': '🇿 ', + 'A': '🇦 ', + 'B': '🇧 ', + 'C': '🇨 ', + 'D': '🇩 ', + 'E': '🇪 ', + 'F': '🇫 ', + 'G': '🇬 ', + 'H': '🇭 ', + 'I': '🇮 ', + 'J': '🇯 ', + 'K': '🇰 ', + 'L': '🇱 ', + 'M': '🇲 ', + 'N': '🇳 ', + 'O': '🇴 ', + 'P': '🇵 ', + 'Q': '🇶 ', + 'R': '🇷 ', + 'S': '🇸 ', + 'T': '🇹 ', + 'U': '🇺 ', + 'V': '🇻 ', + 'W': '🇼 ', + 'X': '🇽 ', + 'Y': '🇾 ', + 'Z': '🇿 ' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def square(text): + style = { + 'a': '🄰', + 'b': '🄱', + 'c': '🄲', + 'd': '🄳', + 'e': '🄴', + 'f': '🄵', + 'g': '🄶', + 'h': '🄷', + 'i': '🄸', + 'j': '🄹', + 'k': '🄺', + 'l': '🄻', + 'm': '🄼', + 'n': '🄽', + 'o': '🄾', + 'p': '🄿', + 'q': '🅀', + 'r': '🅁', + 's': '🅂', + 't': '🅃', + 'u': '🅄', + 'v': '🅅', + 'w': '🅆', + 'x': '🅇', + 'y': '🅈', + 'z': '🅉', + 'A': '🄰', + 'B': '🄱', + 'C': '🄲', + 'D': '🄳', + 'E': '🄴', + 'F': '🄵', + 'G': '🄶', + 'H': '🄷', + 'I': '🄸', + 'J': '🄹', + 'K': '🄺', + 'L': '🄻', + 'M': '🄼', + 'N': '🄽', + 'O': '🄾', + 'P': '🄿', + 'Q': '🅀', + 'R': '🅁', + 'S': '🅂', + 'T': '🅃', + 'U': '🅄', + 'V': '🅅', + 'W': '🅆', + 'X': '🅇', + 'Y': '🅈', + 'Z': '🅉' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def dark_square(text): + style = { + 'a': '🅰︎', + 'b': '🅱︎', + 'c': '🅲︎', + 'd': '🅳︎', + 'e': '🅴︎', + 'f': '🅵︎', + 'g': '🅶︎', + 'h': '🅷︎', + 'i': '🅸︎', + 'j': '🅹︎', + 'k': '🅺︎', + 'l': '🅻︎', + 'm': '🅼︎', + 'n': '🅽︎', + 'o': '🅾︎', + 'p': '🅿︎', + 'q': '🆀︎', + 'r': '🆁︎', + 's': '🆂︎', + 't': '🆃︎', + 'u': '🆄︎', + 'v': '🆅︎', + 'w': '🆆︎', + 'x': '🆇︎', + 'y': '🆈︎', + 'z': '🆉︎', + 'A': '🅰︎', + 'B': '🅱︎', + 'C': '🅲︎', + 'D': '🅳︎', + 'E': '🅴︎', + 'F': '🅵︎', + 'G': '🅶︎', + 'H': '🅷︎', + 'I': '🅸︎', + 'J': '🅹︎', + 'K': '🅺︎', + 'L': '🅻︎', + 'M': '🅼︎', + 'N': '🅽︎', + 'O': '🅾︎', + 'P': '🅿︎', + 'Q': '🆀︎', + 'R': '🆁︎', + 'S': '🆂︎', + 'T': '🆃︎', + 'U': '🆄︎', + 'V': '🆅︎', + 'W': '🆆︎', + 'X': '🆇︎', + 'Y': '🆈︎', + 'Z': '🆉︎' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def andalucia(text): + style = { + 'a': 'ꪖ', + 'b': '᥇', + 'c': 'ᥴ', + 'd': 'ᦔ', + 'e': 'ꫀ', + 'f': 'ᠻ', + 'g': 'ᧁ', + 'h': 'ꫝ', + 'i': '𝓲', + 'j': '𝓳', + 'k': '𝘬', + 'l': 'ꪶ', + 'm': 'ꪑ', + 'n': 'ꪀ', + 'o': 'ꪮ', + 'p': 'ρ', + 'q': '𝘲', + 'r': '𝘳', + 's': '𝘴', + 't': '𝓽', + 'u': 'ꪊ', + 'v': 'ꪜ', + 'w': '᭙', + 'x': '᥊', + 'y': 'ꪗ', + 'z': 'ɀ', + 'A': 'ꪖ', + 'B': '᥇', + 'C': 'ᥴ', + 'D': 'ᦔ', + 'E': 'ꫀ', + 'F': 'ᠻ', + 'G': 'ᧁ', + 'H': 'ꫝ', + 'I': '𝓲', + 'J': '𝓳', + 'K': '𝘬', + 'L': 'ꪶ', + 'M': 'ꪑ', + 'N': 'ꪀ', + 'O': 'ꪮ', + 'P': 'ρ', + 'Q': '𝘲', + 'R': '𝘳', + 'S': '𝘴', + 'T': '𝓽', + 'U': 'ꪊ', + 'V': 'ꪜ', + 'W': '᭙', + 'X': '᥊', + 'Y': 'ꪗ', + 'Z': 'ɀ' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def manga(text): + style = { + 'a': '卂', + 'b': '乃', + 'c': '匚', + 'd': 'ᗪ', + 'e': '乇', + 'f': '千', + 'g': 'ᘜ', + 'h': '卄', + 'i': '|', + 'j': 'フ', + 'k': 'Ҝ', + 'l': 'ㄥ', + 'm': '爪', + 'n': '几', + 'o': 'ㄖ', + 'p': '卩', + 'q': 'Ҩ', + 'r': '尺', + 's': '丂', + 't': 'ㄒ', + 'u': 'ㄩ', + 'v': 'ᐯ', + 'w': '山', + 'x': '乂', + 'y': 'ㄚ', + 'z': '乙', + 'A': '卂', + 'B': '乃', + 'C': '匚', + 'D': 'ᗪ', + 'E': '乇', + 'F': '千', + 'G': 'ᘜ', + 'H': '卄', + 'I': '|', + 'J': 'フ', + 'K': 'Ҝ', + 'L': 'ㄥ', + 'M': '爪', + 'N': '几', + 'O': 'ㄖ', + 'P': '卩', + 'Q': 'Ҩ', + 'R': '尺', + 'S': '丂', + 'T': 'ㄒ', + 'U': 'ㄩ', + 'V': 'ᐯ', + 'W': '山', + 'X': '乂', + 'Y': 'ㄚ', + 'Z': '乙' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def stinky(text): + style = { + 'a': 'a̾', + 'b': 'b̾', + 'c': 'c̾', + 'd': 'd̾', + 'e': 'e̾', + 'f': 'f̾', + 'g': 'g̾', + 'h': 'h̾', + 'i': 'i̾', + 'j': 'j̾', + 'k': 'k̾', + 'l': 'l̾', + 'm': 'm̾', + 'n': 'n̾', + 'o': 'o̾', + 'p': 'p̾', + 'q': 'q̾', + 'r': 'r̾', + 's': 's̾', + 't': 't̾', + 'u': 'u̾', + 'v': 'v̾', + 'w': 'w̾', + 'x': 'x̾', + 'y': 'y̾', + 'z': 'z̾', + 'A': 'A̾', + 'B': 'B̾', + 'C': 'C̾', + 'D': 'D̾', + 'E': 'E̾', + 'F': 'F̾', + 'G': 'G̾', + 'H': 'H̾', + 'I': 'I̾', + 'J': 'J̾', + 'K': 'K̾', + 'L': 'L̾', + 'M': 'M̾', + 'N': 'N̾', + 'O': 'O̾', + 'P': 'P̾', + 'Q': 'Q̾', + 'R': 'R̾', + 'S': 'S̾', + 'T': 'T̾', + 'U': 'U̾', + 'V': 'V̾', + 'W': 'W̾', + 'X': 'X̾', + 'Y': 'Y̾', + 'Z': 'Z̾' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def bubbles(text): + style = { + 'a': 'ḁͦ', + 'b': 'b̥ͦ', + 'c': 'c̥ͦ', + 'd': 'd̥ͦ', + 'e': 'e̥ͦ', + 'f': 'f̥ͦ', + 'g': 'g̥ͦ', + 'h': 'h̥ͦ', + 'i': 'i̥ͦ', + 'j': 'j̥ͦ', + 'k': 'k̥ͦ', + 'l': 'l̥ͦ', + 'm': 'm̥ͦ', + 'n': 'n̥ͦ', + 'o': 'o̥ͦ', + 'p': 'p̥ͦ', + 'q': 'q̥ͦ', + 'r': 'r̥ͦ', + 's': 's̥ͦ', + 't': 't̥ͦ', + 'u': 'u̥ͦ', + 'v': 'v̥ͦ', + 'w': 'w̥ͦ', + 'x': 'x̥ͦ', + 'y': 'y̥ͦ', + 'z': 'z̥ͦ', + 'A': 'Ḁͦ', + 'B': 'B̥ͦ', + 'C': 'C̥ͦ', + 'D': 'D̥ͦ', + 'E': 'E̥ͦ', + 'F': 'F̥ͦ', + 'G': 'G̥ͦ', + 'H': 'H̥ͦ', + 'I': 'I̥ͦ', + 'J': 'J̥ͦ', + 'K': 'K̥ͦ', + 'L': 'L̥ͦ', + 'M': 'M̥ͦ', + 'N': 'N̥ͦ', + 'O': 'O̥ͦ', + 'P': 'P̥ͦ', + 'Q': 'Q̥ͦ', + 'R': 'R̥ͦ', + 'S': 'S̥ͦ', + 'T': 'T̥ͦ', + 'U': 'U̥ͦ', + 'V': 'V̥ͦ', + 'W': 'W̥ͦ', + 'X': 'X̥ͦ', + 'Y': 'Y̥ͦ', + 'Z': 'Z̥ͦ' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def underline(text): + style = { + 'a': 'a͟', + 'b': 'b͟', + 'c': 'c͟', + 'd': 'd͟', + 'e': 'e͟', + 'f': 'f͟', + 'g': 'g͟', + 'h': 'h͟', + 'i': 'i͟', + 'j': 'j͟', + 'k': 'k͟', + 'l': 'l͟', + 'm': 'm͟', + 'n': 'n͟', + 'o': 'o͟', + 'p': 'p͟', + 'q': 'q͟', + 'r': 'r͟', + 's': 's͟', + 't': 't͟', + 'u': 'u͟', + 'v': 'v͟', + 'w': 'w͟', + 'x': 'x͟', + 'y': 'y͟', + 'z': 'z͟', + 'A': 'A͟', + 'B': 'B͟', + 'C': 'C͟', + 'D': 'D͟', + 'E': 'E͟', + 'F': 'F͟', + 'G': 'G͟', + 'H': 'H͟', + 'I': 'I͟', + 'J': 'J͟', + 'K': 'K͟', + 'L': 'L͟', + 'M': 'M͟', + 'N': 'N͟', + 'O': 'O͟', + 'P': 'P͟', + 'Q': 'Q͟', + 'R': 'R͟', + 'S': 'S͟', + 'T': 'T͟', + 'U': 'U͟', + 'V': 'V͟', + 'W': 'W͟', + 'X': 'X͟', + 'Y': 'Y͟', + 'Z': 'Z͟' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def ladybug(text): + style = { + 'a': 'ꍏ', + 'b': 'ꌃ', + 'c': 'ꏳ', + 'd': 'ꀷ', + 'e': 'ꏂ', + 'f': 'ꎇ', + 'g': 'ꁅ', + 'h': 'ꀍ', + 'i': 'ꀤ', + 'j': '꒻', + 'k': 'ꀘ', + 'l': '꒒', + 'm': 'ꎭ', + 'n': 'ꈤ', + 'o': 'ꂦ', + 'p': 'ᖘ', + 'q': 'ꆰ', + 'r': 'ꋪ', + 's': 'ꌚ', + 't': '꓄', + 'u': 'ꀎ', + 'v': '꒦', + 'w': 'ꅐ', + 'x': 'ꉧ', + 'y': 'ꌩ', + 'z': 'ꁴ', + 'A': 'ꍏ', + 'B': 'ꌃ', + 'C': 'ꏳ', + 'D': 'ꀷ', + 'E': 'ꏂ', + 'F': 'ꎇ', + 'G': 'ꁅ', + 'H': 'ꀍ', + 'I': 'ꀤ', + 'J': '꒻', + 'K': 'ꀘ', + 'L': '꒒', + 'M': 'ꎭ', + 'N': 'ꈤ', + 'O': 'ꂦ', + 'P': 'ᖘ', + 'Q': 'ꆰ', + 'R': 'ꋪ', + 'S': 'ꌚ', + 'T': '꓄', + 'U': 'ꀎ', + 'V': '꒦', + 'W': 'ꅐ', + 'X': 'ꉧ', + 'Y': 'ꌩ', + 'Z': 'ꁴ' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def rays(text): + style = { + 'a': 'a҉', + 'b': 'b҉', + 'c': 'c҉', + 'd': 'd҉', + 'e': 'e҉', + 'f': 'f҉', + 'g': 'g҉', + 'h': 'h҉', + 'i': 'i҉', + 'j': 'j҉', + 'k': 'k҉', + 'l': 'l҉', + 'm': 'm҉', + 'n': 'n҉', + 'o': 'o҉', + 'p': 'p҉', + 'q': 'q҉', + 'r': 'r҉', + 's': 's҉', + 't': 't҉', + 'u': 'u҉', + 'v': 'v҉', + 'w': 'w҉', + 'x': 'x҉', + 'y': 'y҉', + 'z': 'z҉', + 'A': 'A҉', + 'B': 'B҉', + 'C': 'C҉', + 'D': 'D҉', + 'E': 'E҉', + 'F': 'F҉', + 'G': 'G҉', + 'H': 'H҉', + 'I': 'I҉', + 'J': 'J҉', + 'K': 'K҉', + 'L': 'L҉', + 'M': 'M҉', + 'N': 'N҉', + 'O': 'O҉', + 'P': 'P҉', + 'Q': 'Q҉', + 'R': 'R҉', + 'S': 'S҉', + 'T': 'T҉', + 'U': 'U҉', + 'V': 'V҉', + 'W': 'W҉', + 'X': 'X҉', + 'Y': 'Y҉', + 'Z': 'Z҉' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def birds(text): + style = { + 'a': 'a҈', + 'b': 'b҈', + 'c': 'c҈', + 'd': 'd҈', + 'e': 'e҈', + 'f': 'f҈', + 'g': 'g҈', + 'h': 'h҈', + 'i': 'i҈', + 'j': 'j҈', + 'k': 'k҈', + 'l': 'l҈', + 'm': 'm҈', + 'n': 'n҈', + 'o': 'o҈', + 'p': 'p҈', + 'q': 'q҈', + 'r': 'r҈', + 's': 's҈', + 't': 't҈', + 'u': 'u҈', + 'v': 'v҈', + 'w': 'w҈', + 'x': 'x҈', + 'y': 'y҈', + 'z': 'z҈', + 'A': 'A҈', + 'B': 'B҈', + 'C': 'C҈', + 'D': 'D҈', + 'E': 'E҈', + 'F': 'F҈', + 'G': 'G҈', + 'H': 'H҈', + 'I': 'I҈', + 'J': 'J҈', + 'K': 'K҈', + 'L': 'L҈', + 'M': 'M҈', + 'N': 'N҈', + 'O': 'O҈', + 'P': 'P҈', + 'Q': 'Q҈', + 'R': 'R҈', + 'S': 'S҈', + 'T': 'T҈', + 'U': 'U҈', + 'V': 'V҈', + 'W': 'W҈', + 'X': 'X҈', + 'Y': 'Y҈', + 'Z': 'Z҈' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def slash(text): + style = { + 'a': 'a̸', + 'b': 'b̸', + 'c': 'c̸', + 'd': 'd̸', + 'e': 'e̸', + 'f': 'f̸', + 'g': 'g̸', + 'h': 'h̸', + 'i': 'i̸', + 'j': 'j̸', + 'k': 'k̸', + 'l': 'l̸', + 'm': 'm̸', + 'n': 'n̸', + 'o': 'o̸', + 'p': 'p̸', + 'q': 'q̸', + 'r': 'r̸', + 's': 's̸', + 't': 't̸', + 'u': 'u̸', + 'v': 'v̸', + 'w': 'w̸', + 'x': 'x̸', + 'y': 'y̸', + 'z': 'z̸', + 'A': 'A̸', + 'B': 'B̸', + 'C': 'C̸', + 'D': 'D̸', + 'E': 'E̸', + 'F': 'F̸', + 'G': 'G̸', + 'H': 'H̸', + 'I': 'I̸', + 'J': 'J̸', + 'K': 'K̸', + 'L': 'L̸', + 'M': 'M̸', + 'N': 'N̸', + 'O': 'O̸', + 'P': 'P̸', + 'Q': 'Q̸', + 'R': 'R̸', + 'S': 'S̸', + 'T': 'T̸', + 'U': 'U̸', + 'V': 'V̸', + 'W': 'W̸', + 'X': 'X̸', + 'Y': 'Y̸', + 'Z': 'Z̸' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def stop(text): + style = { + 'a': 'a⃠', + 'b': 'b⃠', + 'c': 'c⃠', + 'd': 'd⃠', + 'e': 'e⃠', + 'f': 'f⃠', + 'g': 'g⃠', + 'h': 'h⃠', + 'i': 'i⃠', + 'j': 'j⃠', + 'k': 'k⃠', + 'l': 'l⃠', + 'm': 'm⃠', + 'n': 'n⃠', + 'o': 'o⃠', + 'p': 'p⃠', + 'q': 'q⃠', + 'r': 'r⃠', + 's': 's⃠', + 't': 't⃠', + 'u': 'u⃠', + 'v': 'v⃠', + 'w': 'w⃠', + 'x': 'x⃠', + 'y': 'y⃠', + 'z': 'z⃠', + 'A': 'A⃠', + 'B': 'B⃠', + 'C': 'C⃠', + 'D': 'D⃠', + 'E': 'E⃠', + 'F': 'F⃠', + 'G': 'G⃠', + 'H': 'H⃠', + 'I': 'I⃠', + 'J': 'J⃠', + 'K': 'K⃠', + 'L': 'L⃠', + 'M': 'M⃠', + 'N': 'N⃠', + 'O': 'O⃠', + 'P': 'P⃠', + 'Q': 'Q⃠', + 'R': 'R⃠', + 'S': 'S⃠', + 'T': 'T⃠', + 'U': 'U⃠', + 'V': 'V⃠', + 'W': 'W⃠', + 'X': 'X⃠', + 'Y': 'Y⃠', + 'Z': 'Z⃠' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def skyline(text): + style = { + 'a': 'a̺͆', + 'b': 'b̺͆', + 'c': 'c̺͆', + 'd': 'd̺͆', + 'e': 'e̺͆', + 'f': 'f̺͆', + 'g': 'g̺͆', + 'h': 'h̺͆', + 'i': 'i̺͆', + 'j': 'j̺͆', + 'k': 'k̺͆', + 'l': 'l̺͆', + 'm': 'm̺͆', + 'n': 'n̺͆', + 'o': 'o̺͆', + 'p': 'p̺͆', + 'q': 'q̺͆', + 'r': 'r̺͆', + 's': 's̺͆', + 't': 't̺͆', + 'u': 'u̺͆', + 'v': 'v̺͆', + 'w': 'w̺͆', + 'x': 'x̺͆', + 'y': 'y̺͆', + 'z': 'z̺͆', + 'A': 'A̺͆', + 'B': 'B̺͆', + 'C': 'C̺͆', + 'D': 'D̺͆', + 'E': 'E̺͆', + 'F': 'F̺͆', + 'G': 'G̺͆', + 'H': 'H̺͆', + 'I': 'I̺͆', + 'J': 'J̺͆', + 'K': 'K̺͆', + 'L': 'L̺͆', + 'M': 'M̺͆', + 'N': 'N̺͆', + 'O': 'O̺͆', + 'P': 'P̺͆', + 'Q': 'Q̺͆', + 'R': 'R̺͆', + 'S': 'S̺͆', + 'T': 'T̺͆', + 'U': 'U̺͆', + 'V': 'V̺͆', + 'W': 'W̺͆', + 'X': 'X̺͆', + 'Y': 'Y̺͆', + 'Z': 'Z̺͆' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def arrows(text): + style = { + 'a': 'a͎', + 'b': 'b͎', + 'c': 'c͎', + 'd': 'd͎', + 'e': 'e͎', + 'f': 'f͎', + 'g': 'g͎', + 'h': 'h͎', + 'i': 'i͎', + 'j': 'j͎', + 'k': 'k͎', + 'l': 'l͎', + 'm': 'm͎', + 'n': 'n͎', + 'o': 'o͎', + 'p': 'p͎', + 'q': 'q͎', + 'r': 'r͎', + 's': 's͎', + 't': 't͎', + 'u': 'u͎', + 'v': 'v͎', + 'w': 'w͎', + 'x': 'x͎', + 'y': 'y͎', + 'z': 'z͎', + 'A': 'A͎', + 'B': 'B͎', + 'C': 'C͎', + 'D': 'D͎', + 'E': 'E͎', + 'F': 'F͎', + 'G': 'G͎', + 'H': 'H͎', + 'I': 'I͎', + 'J': 'J͎', + 'K': 'K͎', + 'L': 'L͎', + 'M': 'M͎', + 'N': 'N͎', + 'O': 'O͎', + 'P': 'P͎', + 'Q': 'Q͎', + 'R': 'R͎', + 'S': 'S͎', + 'T': 'T͎', + 'U': 'U͎', + 'V': 'V͎', + 'W': 'W͎', + 'X': 'X͎', + 'Y': 'Y͎', + 'Z': 'Z͎' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def rvnes(text): + style = { + 'a': 'ል', + 'b': 'ጌ', + 'c': 'ር', + 'd': 'ዕ', + 'e': 'ቿ', + 'f': 'ቻ', + 'g': 'ኗ', + 'h': 'ዘ', + 'i': 'ጎ', + 'j': 'ጋ', + 'k': 'ጕ', + 'l': 'ረ', + 'm': 'ጠ', + 'n': 'ክ', + 'o': 'ዐ', + 'p': 'የ', + 'q': 'ዒ', + 'r': 'ዪ', + 's': 'ነ', + 't': 'ፕ', + 'u': 'ሁ', + 'v': 'ሀ', + 'w': 'ሠ', + 'x': 'ሸ', + 'y': 'ሃ', + 'z': 'ጊ', + 'A': 'ል', + 'B': 'ጌ', + 'C': 'ር', + 'D': 'ዕ', + 'E': 'ቿ', + 'F': 'ቻ', + 'G': 'ኗ', + 'H': 'ዘ', + 'I': 'ጎ', + 'J': 'ጋ', + 'K': 'ጕ', + 'L': 'ረ', + 'M': 'ጠ', + 'N': 'ክ', + 'O': 'ዐ', + 'P': 'የ', + 'Q': 'ዒ', + 'R': 'ዪ', + 'S': 'ነ', + 'T': 'ፕ', + 'U': 'ሁ', + 'V': 'ሀ', + 'W': 'ሠ', + 'X': 'ሸ', + 'Y': 'ሃ', + 'Z': 'ጊ' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def strike(text): + style = { + 'a': 'a̶', + 'b': 'b̶', + 'c': 'c̶', + 'd': 'd̶', + 'e': 'e̶', + 'f': 'f̶', + 'g': 'g̶', + 'h': 'h̶', + 'i': 'i̶', + 'j': 'j̶', + 'k': 'k̶', + 'l': 'l̶', + 'm': 'm̶', + 'n': 'n̶', + 'o': 'o̶', + 'p': 'p̶', + 'q': 'q̶', + 'r': 'r̶', + 's': 's̶', + 't': 't̶', + 'u': 'u̶', + 'v': 'v̶', + 'w': 'w̶', + 'x': 'x̶', + 'y': 'y̶', + 'z': 'z̶', + 'A': 'A̶', + 'B': 'B̶', + 'C': 'C̶', + 'D': 'D̶', + 'E': 'E̶', + 'F': 'F̶', + 'G': 'G̶', + 'H': 'H̶', + 'I': 'I̶', + 'J': 'J̶', + 'K': 'K̶', + 'L': 'L̶', + 'M': 'M̶', + 'N': 'N̶', + 'O': 'O̶', + 'P': 'P̶', + 'Q': 'Q̶', + 'R': 'R̶', + 'S': 'S̶', + 'T': 'T̶', + 'U': 'U̶', + 'V': 'V̶', + 'W': 'W̶', + 'X': 'X̶', + 'Y': 'Y̶', + 'Z': 'Z̶' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + + def frozen(text): + style = { + 'a': 'a༙', + 'b': 'b༙', + 'c': 'c༙', + 'd': 'd༙', + 'e': 'e༙', + 'f': 'f༙', + 'g': 'g༙', + 'h': 'h༙', + 'i': 'i༙', + 'j': 'j༙', + 'k': 'k༙', + 'l': 'l༙', + 'm': 'm༙', + 'n': 'n༙', + 'o': 'o༙', + 'p': 'p༙', + 'q': 'q༙', + 'r': 'r༙', + 's': 's༙', + 't': 't༙', + 'u': 'u༙', + 'v': 'v༙', + 'w': 'w༙', + 'x': 'x༙', + 'y': 'y༙', + 'z': 'z༙', + 'A': 'A༙', + 'B': 'B༙', + 'C': 'C༙', + 'D': 'D༙', + 'E': 'E༙', + 'F': 'F༙', + 'G': 'G༙', + 'H': 'H༙', + 'I': 'I༙', + 'J': 'J༙', + 'K': 'K༙', + 'L': 'L༙', + 'M': 'M༙', + 'N': 'N༙', + 'O': 'O༙', + 'P': 'P༙', + 'Q': 'Q༙', + 'R': 'R༙', + 'S': 'S༙', + 'T': 'T༙', + 'U': 'U༙', + 'V': 'V༙', + 'W': 'W༙', + 'X': 'X༙', + 'Y': 'Y༙', + 'Z': 'Z༙' + } + for i, j in style.items(): + text = text.replace(i, j) + return text + diff --git a/akn/Meta/__init__.py b/akn/Meta/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..b67d0728b501dddd359833e75c026c75a6475f07 --- /dev/null +++ b/akn/Meta/__init__.py @@ -0,0 +1,3 @@ +import akenoai.pyro_decorator as akeno + +force_sub = akeno.ForceSubscribe(where_from="RendyProjects", owner_id="xpushz") \ No newline at end of file diff --git a/akn/Meta/meta_ai.py b/akn/Meta/meta_ai.py new file mode 100755 index 0000000000000000000000000000000000000000..4ec3e1ddc9eb910b2f366bd9569aaacb8bd72db7 --- /dev/null +++ b/akn/Meta/meta_ai.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2020-2024 (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 os +from pyrogram import * +from pyrogram import enums +from pyrogram import Client, filters +from pyrogram.types import * +from pyrogram.errors import * +from config import * + +from akn.utils.logger import LOGS +import datetime + +from huggingface_hub import InferenceClient + + +SYSTEM_PROMPT = f""" +Your name is Randy Dev. A kind and friendly AI assistant that answers in a short and concise answer. +Give short step-by-step reasoning if required. + +python language powered by @xtdevs on telegram support and language models Meta AI + +{datetime.datetime.now()} +""" + +async def process_stream(message, prompt): + client_hf = InferenceClient(api_key=HF_KEY) + messages = [ + {"role": "system", "content": SYSTEM_PROMPT}, + {"role": "user", "content": prompt} + ] + stream = client_hf.chat.completions.create( + model="mistralai/Mixtral-8x7B-Instruct-v0.1", + messages=messages, + max_tokens=500, + stream=True + ) + accumulated_text = "" + for chunk in stream: + LOGS.info(chunk) + new_content = chunk.choices[0].delta.content + accumulated_text += new_content + return accumulated_text + +@Client.on_message( + ~filters.scheduled + & filters.command(["start"]) + & ~filters.forwarded +) +async def startbot(client: Client, message: Message): + buttons = [ + [ + InlineKeyboardButton( + text="Developer", + url=f"https://t.me/xtdevs" + ), + InlineKeyboardButton( + text="Channel", + url='https://t.me/RendyProjects' + ), + ] + ] + await message.reply_text( + text="Woohoo! Welcome! I'm excited to get started as a Meta AI bot!\n\n• Command /ask hello", + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(buttons) + ) + +@Client.on_message( + filters.private + & filters.command(["ask"]) + & ~filters.forwarded +) +async def askcmd(client: Client, message: Message): + if len(message.command) > 1: + prompt = message.text.split(maxsplit=1)[1] + elif message.reply_to_message: + prompt = message.reply_to_message.text + else: + return await message.reply_text("Give ask from Meta AI") + await client.send_chat_action(message.chat.id, enums.ChatAction.TYPING) + await asyncio.sleep(1.5) + try: + output = await process_stream(message, prompt) + if len(output) > 4096: + with open("chat.txt", "w+", encoding="utf8") as out_file: + out_file.write(output) + await message.reply_document( + document="chat.txt", + disable_notification=True + ) + os.remove("chat.txt") + else: + await message.reply_text(output, disable_web_page_preview=True) + await client.send_chat_action(message.chat.id, enums.ChatAction.CANCEL) + return + except Exception as e: + return await message.reply_text(f"Error: {e}") diff --git a/akn/SessionBot/__init__.py b/akn/SessionBot/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/akn/SessionBot/about.py b/akn/SessionBot/about.py new file mode 100755 index 0000000000000000000000000000000000000000..2192831e7f576f914df2e7d376caa4c354de81d9 --- /dev/null +++ b/akn/SessionBot/about.py @@ -0,0 +1,16 @@ +from Data import Data +from pyrogram import Client, filters +from pyrogram.types import InlineKeyboardMarkup + +@Client.on_message( + filters.private + & filters.incoming + & filters.command("about") +) +async def about(bot, msg): + await bot.send_message( + msg.chat.id, + Data.ABOUT, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(Data.home_buttons), + ) \ No newline at end of file diff --git a/akn/SessionBot/callbacks.py b/akn/SessionBot/callbacks.py new file mode 100755 index 0000000000000000000000000000000000000000..a5882339bb333654448e3c6d137b53af3877e2b6 --- /dev/null +++ b/akn/SessionBot/callbacks.py @@ -0,0 +1,61 @@ +from Data import Data +from pyrogram import Client +from pyrogram.types import CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton +from akn.SessionBot.generate import generate_session, ERROR_MESSAGE + + +@Client.on_callback_query() +async def _callbacks(bot: Client, callback_query: CallbackQuery): + user = await bot.get_me() + mention = user.mention + query = callback_query.data.lower() + if query.startswith("home"): + if query == 'home': + chat_id = callback_query.from_user.id + message_id = callback_query.message.id + await bot.edit_message_text( + chat_id=chat_id, + message_id=message_id, + text=Data.START.format(callback_query.from_user.mention, mention), + reply_markup=InlineKeyboardMarkup(Data.buttons), + ) + elif query == "close": + await callback_query.message.delete() + elif query == "about": + chat_id = callback_query.from_user.id + message_id = callback_query.message.id + await bot.edit_message_text( + chat_id=chat_id, + message_id=message_id, + text=Data.ABOUT, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(Data.home_buttons), + ) + elif query == "help": + chat_id = callback_query.from_user.id + message_id = callback_query.message.id + await bot.edit_message_text( + chat_id=chat_id, + message_id=message_id, + text="**Here's How to use me**\n" + Data.HELP, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(Data.home_buttons), + ) + elif query == "generate": + await callback_query.message.delete() + await callback_query.message.reply( + "Please Choose Which String You Want To Take", + reply_markup=InlineKeyboardMarkup([[ + InlineKeyboardButton("Pyrogram", callback_data="pyrogram"), + InlineKeyboardButton("Telethon", callback_data="telethon") + ]]) + ) + elif query in ["pyrogram", "telethon"]: + await callback_query.answer() + try: + if query == "pyrogram": + await generate_session(bot, callback_query.message) + else: + await generate_session(bot, callback_query.message, telethon=True) + except Exception as e: + await callback_query.message.reply(ERROR_MESSAGE.format(str(e))) \ No newline at end of file diff --git a/akn/SessionBot/generate.py b/akn/SessionBot/generate.py new file mode 100755 index 0000000000000000000000000000000000000000..8bf0c603ce071029d402bf950d879b7d20ce459c --- /dev/null +++ b/akn/SessionBot/generate.py @@ -0,0 +1,165 @@ +import string +from random import choice +from asyncio.exceptions import TimeoutError +from Data import Data +from pyrogram import Client, filters +from telethon import TelegramClient +from telethon.sessions import StringSession +from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton +from pyrogram.types import * +from pyrogram.errors import ( + ApiIdInvalid, + PhoneNumberInvalid, + PhoneCodeInvalid, + PhoneCodeExpired, + SessionPasswordNeeded, + PasswordHashInvalid +) +from telethon.errors import ( + ApiIdInvalidError, + PhoneNumberInvalidError, + PhoneCodeInvalidError, + PhoneCodeExpiredError, + SessionPasswordNeededError, + PasswordHashInvalidError +) + +def generate_random_string(length): + characters = string.ascii_uppercase + string.digits + random_string = ''.join(choice(characters) for _ in range(length)) + return random_string + +ERROR_MESSAGE = "Oops! An exception occurred! \n\n**Error** : {} " \ + "\n\nTolong Laporan ke [Support](t.me/xpushz) jika eror " \ + "sensitive information and you if want to report this as " \ + "this error message is not being logged by us!" + +@Client.on_message(filters.private & filters.command('generate')) +async def main(_, msg): + await msg.reply( + "Please press which string you want to take", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton("Pyrogram", callback_data="pyrogram"), + InlineKeyboardButton("Telethon", callback_data="telethon") + ] + ] + ) + ) + +async def generate_session(bot, msg, telethon=False): + await msg.reply("Starting {} Session Generation...".format("Telethon" if telethon else "Pyrogram")) + user_id = msg.chat.id + api_id_msg = await bot.ask(user_id, 'Please Send `API_ID`', filters=filters.text) + if await cancelled(api_id_msg): + return + try: + api_id = int(api_id_msg.text) + except ValueError: + await api_id_msg.reply('not true API_ID (which must be an integer). Please start generating session again.', quote=True, reply_markup=InlineKeyboardMarkup(Data.generate_button)) + return + api_hash_msg = await bot.ask(user_id, 'Please Send `API_HASH`', filters=filters.text) + if await cancelled(api_id_msg): + return + api_hash = api_hash_msg.text + phone_number_msg = await bot.ask(user_id, "**Please Enter Your Telegram Phone Number With Country Code Format.**\nExample: +1xxxxxxxx", filters=filters.text) + if await cancelled(api_id_msg): + return + phone_number = phone_number_msg.text + await msg.reply("Sending OTP...") + clients_name = generate_random_string(12) + if telethon: + client = TelegramClient(StringSession(), api_id, api_hash) + else: + client = Client("{}".format(clients_name), api_id, api_hash) + await client.connect() + try: + if telethon: + code = await client.send_code_request(phone_number) + else: + code = await client.send_code(phone_number) + except (ApiIdInvalid, ApiIdInvalidError): + await msg.reply('`API_ID` and `API_HASH` combination is invalid. Please start generating session again.', reply_markup=InlineKeyboardMarkup(Data.generate_button)) + return + except (PhoneNumberInvalid, PhoneNumberInvalidError): + await msg.reply('`PHONE_NUMBER` is invalid. Please start generating session again.', reply_markup=InlineKeyboardMarkup(Data.generate_button)) + return + try: + phone_code_msg = await bot.ask(user_id, "**Please Check OTP Code from Official [Telegram Account](tg://openmessage?user_id=777000).Send OTP Code here after reading Format below.\n\nIf OTP Code is 12345 Please [ ADD SPACE** ] send it Like this `1 2 3 4 5`", filters=filters.text, timeout=600) + if await cancelled(api_id_msg): + return + except TimeoutError: + await msg.reply('Time limit reached 10 minutes. Please start generating strings again.', reply_markup=InlineKeyboardMarkup(Data.generate_button)) + return + phone_code = phone_code_msg.text.replace(" ", "") + try: + if telethon: + await client.sign_in(phone_number, phone_code, password=None) + else: + await client.sign_in(phone_number, code.phone_code_hash, phone_code) + except (PhoneCodeInvalid, PhoneCodeInvalidError): + await msg.reply('OTP is invalid. Please start generating session again.', reply_markup=InlineKeyboardMarkup(Data.generate_button)) + return + except (PhoneCodeExpired, PhoneCodeExpiredError): + await msg.reply('OTP is expired. Please start generating session again.', reply_markup=InlineKeyboardMarkup(Data.generate_button)) + return + except (SessionPasswordNeeded, SessionPasswordNeededError): + try: + two_step_msg = await bot.ask(user_id, 'Your account has enabled two-step verification. Please provide the password.', filters=filters.text, timeout=300) + except TimeoutError: + await msg.reply('Time limit reached 10 minutes. Please start generating strings again.', reply_markup=InlineKeyboardMarkup(Data.generate_button)) + return + try: + password = two_step_msg.text + if telethon: + await client.sign_in(password=password) + else: + await client.check_password(password=password) + if await cancelled(api_id_msg): + return + except (PasswordHashInvalid, PasswordHashInvalidError): + await two_step_msg.reply('Invalid Password Provided. Please start generating session again.', quote=True, reply_markup=InlineKeyboardMarkup(Data.generate_button)) + return + if telethon: + string_session = client.session.save() + else: + string_session = await client.export_session_string() + text = "**{} STRING SESSION** \n\n`{}` \n\nGenerated by @RendyProjects".format("TELETHON" if telethon else "PYROGRAM", string_session) + close_bttn = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Click Me", + url=f"tg://openmessage?user_id={user_id}" + ) + ], + [ + InlineKeyboardButton( + text="Close", + callback_data="close" + ) + ] + ] + ) + await bot.send_message( + user_id, + text, + reply_markup=close_bttn + ) + await client.send_message("me", text) + await client.disconnect() + await phone_code_msg.reply("Successfully Fetched {} session string.\n\nPlease check the Saved Message!\n\nBy @rencprx".format("telethon" if telethon else "pyrogram")) + +async def cancelled(msg): + if "/cancel" in msg.text: + await msg.reply("Cancel Process!", quote=True, reply_markup=InlineKeyboardMarkup(Data.generate_button)) + return True + elif "/restart" in msg.text: + await msg.reply("Restarting Bots!", quote=True, reply_markup=InlineKeyboardMarkup(Data.generate_button)) + return True + elif msg.text.startswith("/"): # Bot Commands + await msg.reply("Cancel generation process!", quote=True) + return True + else: + return False \ No newline at end of file diff --git a/akn/SessionBot/start.py b/akn/SessionBot/start.py new file mode 100755 index 0000000000000000000000000000000000000000..9e7cf35bd05926ee4e9264962676f1482e9e3166 --- /dev/null +++ b/akn/SessionBot/start.py @@ -0,0 +1,21 @@ +from Data import Data +from pyrogram import Client, filters +from pyrogram.types import InlineKeyboardMarkup, Message + +@Client.on_message( + filters.private + & filters.incoming + & filters.command("start") +) +async def start(bot: Client, msg: Message): + user = await bot.get_me() + mention = user.mention + await bot.send_photo( + msg.chat.id, + photo="https://randydev-meta-ai.hf.space/image/share/image.jpg", + caption=Data.START.format( + msg.from_user.mention, + mention + ), + reply_markup=InlineKeyboardMarkup(Data.buttons) + ) \ No newline at end of file diff --git a/akn/Youtube/__init__.py b/akn/Youtube/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/akn/Youtube/youtube.py b/akn/Youtube/youtube.py new file mode 100755 index 0000000000000000000000000000000000000000..09d9ade22744420ae7f4331efb04485291dcd7d0 --- /dev/null +++ b/akn/Youtube/youtube.py @@ -0,0 +1,298 @@ +import os +import time + +import requests +from pyrogram.types import * +from pyrogram import Client, filters +from youtube_search import YoutubeSearch +from yt_dlp import YoutubeDL + +from akn.utils.database import db +from akn.utils.driver import YoutubeDriver +from akn.utils.formatter import secs_to_mins +from akn.utils.logger import LOGS +from akn.utils.scripts import progress + +custom_loading = "🗿" + +COMMAND_LIST = """ +/yta: Download the youtube link video in .mp3 format!. +/ytv: Download the youtube link video in .mp4 format!. +/ytsa: Download the youtube search video in .mp3 format!. +/ytva: Download the youtube search video in .mp4 format! +/ytlink: Search for a video on youtube +""" + +async def input_user(message: Message) -> str: + """Get the input from the user""" + if len(message.command) < 2: + output = "" + else: + try: + output = message.text.split(" ", 1)[1].strip() or "" + except IndexError: + output = "" + return output + +@Client.on_message( + filters.command(["start"]) + & ~filters.forwarded +) +async def startbot(client: Client, message: Message): + buttons = [ + [ + InlineKeyboardButton( + text="Developer", + url=f"https://t.me/xpushz" + ), + InlineKeyboardButton( + text="Channel", + url='https://t.me/RendyProjects' + ), + ] + ] + await message.reply_text( + text=COMMAND_LIST, + disable_web_page_preview=True, + reply_markup=InlineKeyboardMarkup(buttons) + ) + +@Client.on_message( + filters.command(["ytsa"]) + & ~filters.forwarded +) +async def youtube_search_audio(client: Client, message: Message): + if len(message.command) < 2: + return await message.reply_text( + "Give a valid youtube search to download audio." + ) + query = await input_user(message) + results = YoutubeSearch(query, max_results=5).to_dict() + watch = results[0]["url_suffix"] + url_suffix = watch.split("/")[1] + okk = f"https://youtube.com/{url_suffix}" + pro = await message.reply_text("Checking ...") + _, url = YoutubeDriver.check_url(okk) + #if not status: + # return await pro.edit_text(url) + if client.me.is_premium: + await pro.edit_text(f"{custom_loading}__Downloading audio ...__") + else: + await pro.edit_text(f"__Downloading audio ...__") + try: + with YoutubeDL(YoutubeDriver.song_options()) as ytdl: + yt_data = ytdl.extract_info(url, False) + yt_file = ytdl.prepare_filename(yt_data) + ytdl.process_info(yt_data) + if client.me.is_premium: + upload_text = f"**{custom_loading}𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + else: + upload_text = f"**𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + await pro.edit_text(upload_text) + response = requests.get(f"https://i.ytimg.com/vi/{yt_data['id']}/hqdefault.jpg") + with open(f"{yt_file}.jpg", "wb") as f: + f.write(response.content) + await message.reply_audio( + f"{yt_file}.mp3", + caption=f"**🎧 𝖳𝗂𝗍𝗅𝖾:** {yt_data['title']} \n\n**👀 𝖵𝗂𝖾𝗐𝗌:** `{yt_data['view_count']}` \n**⌛ 𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{secs_to_mins(int(yt_data['duration']))}`", + duration=int(yt_data["duration"]), + performer="[Akeno UB]", + title=yt_data["title"], + thumb=f"{yt_file}.jpg", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text, + ), + ) + await pro.delete() + except Exception as e: + return await pro.edit_text(f"**🍀 Audio not Downloaded:** `{e}`") + try: + os.remove(f"{yt_file}.jpg") + os.remove(f"{yt_file}.mp3") + except: + pass + +@Client.on_message( + filters.command(["yta"]) + & ~filters.forwarded +) +async def youtube_audio(client: Client, message: Message): + if len(message.command) < 2: + return await message.reply_text( + "Give a valid youtube link to download audio." + ) + query = await input_user(message) + pro = await message.reply_text("Checking ...") + _, url = YoutubeDriver.check_url(query) + #if not status: + # return await pro.edit_text(url) + if client.me.is_premium: + await pro.edit_text(f"{custom_loading}__Downloading audio ...__") + else: + await pro.edit_text(f"__Downloading audio ...__") + try: + with YoutubeDL(YoutubeDriver.song_options()) as ytdl: + yt_data = ytdl.extract_info(url, False) + yt_file = ytdl.prepare_filename(yt_data) + ytdl.process_info(yt_data) + if client.me.is_premium: + upload_text = f"**{custom_loading}𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + else: + upload_text = f"**𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + await pro.edit_text(upload_text) + response = requests.get(f"https://i.ytimg.com/vi/{yt_data['id']}/hqdefault.jpg") + with open(f"{yt_file}.jpg", "wb") as f: + f.write(response.content) + await message.reply_audio( + f"{yt_file}.mp3", + caption=f"**🎧 𝖳𝗂𝗍𝗅𝖾:** {yt_data['title']} \n\n**👀 𝖵𝗂𝖾𝗐𝗌:** `{yt_data['view_count']}` \n**⌛ 𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{secs_to_mins(int(yt_data['duration']))}`", + duration=int(yt_data["duration"]), + performer="[Akeno UB]", + title=yt_data["title"], + thumb=f"{yt_file}.jpg", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text, + ), + ) + await pro.delete() + except Exception as e: + return await pro.edit_text(f"**🍀 Audio not Downloaded:** `{e}`") + try: + os.remove(f"{yt_file}.jpg") + os.remove(f"{yt_file}.mp3") + except: + pass + +@Client.on_message( + filters.command(["ytva"]) + & ~filters.forwarded +) +async def ytvideo_search(client: Client, message: Message): + if len(message.command) < 2: + return await message.reply_text( + "Give a valid youtube search to download video." + ) + query = await input_user(message) + results = YoutubeSearch(query, max_results=5).to_dict() + watch = results[0]["url_suffix"] + url_suffix = watch.split("/")[1] + okk = f"https://youtube.com/{url_suffix}" + pro = await message.reply_text("Checking ...") + _, url = YoutubeDriver.check_url(okk) + #if not status: + # return await pro.edit_text(url) + if client.me.is_premium: + await pro.edit_text(f"{custom_loading}__Downloading audio ...__") + else: + await pro.edit_text(f"__Downloading audio ...__") + try: + with YoutubeDL(YoutubeDriver.video_options()) as ytdl: + yt_data = ytdl.extract_info(url, True) + yt_file = yt_data["id"] + + if client.me.is_premium: + upload_text = f"**{custom_loading}𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + else: + upload_text = f"**𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + await pro.edit_text(upload_text) + response = requests.get(f"https://i.ytimg.com/vi/{yt_data['id']}/hqdefault.jpg") + with open(f"{yt_file}.jpg", "wb") as f: + f.write(response.content) + await message.reply_video( + f"{yt_file}.mp4", + caption=f"**🎧 𝖳𝗂𝗍𝗅𝖾:** {yt_data['title']} \n\n**👀 𝖵𝗂𝖾𝗐𝗌:** `{yt_data['view_count']}` \n**⌛ 𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{secs_to_mins(int(yt_data['duration']))}`", + duration=int(yt_data["duration"]), + thumb=f"{yt_file}.jpg", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text, + ), + ) + await pro.delete() + except Exception as e: + return await pro.edit_text(f"**🍀 Video not Downloaded:** `{e}`") + try: + os.remove(f"{yt_file}.jpg") + os.remove(f"{yt_file}.mp4") + except: + pass + +@Client.on_message( + filters.command(["ytv"]) + & ~filters.forwarded +) +async def ytvideo(client: Client, message: Message): + if len(message.command) < 2: + return await message.reply_text( + "Give a valid youtube link to download video." + ) + query = await input_user(message) + pro = await message.reply_text("Checking ...") + _, url = YoutubeDriver.check_url(query) + #if not status: + # return await pro.edit_text(url) + if client.me.is_premium: + await pro.edit_text(f"{custom_loading}__Downloading audio ...__") + else: + await pro.edit_text(f"__Downloading audio ...__") + try: + with YoutubeDL(YoutubeDriver.video_options()) as ytdl: + yt_data = ytdl.extract_info(url, True) + yt_file = yt_data["id"] + + if client.me.is_premium: + upload_text = f"**{custom_loading}𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + else: + upload_text = f"**𝖴𝗉𝗅𝗈𝖺𝖽𝗂𝗇𝗀 𝖲𝗈𝗇𝗀 ...** \n\n**𝖳𝗂𝗍𝗅𝖾:** `{yt_data['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{yt_data['channel']}`" + await pro.edit_text(upload_text) + response = requests.get(f"https://i.ytimg.com/vi/{yt_data['id']}/hqdefault.jpg") + with open(f"{yt_file}.jpg", "wb") as f: + f.write(response.content) + await message.reply_video( + f"{yt_file}.mp4", + caption=f"**🎧 𝖳𝗂𝗍𝗅𝖾:** {yt_data['title']} \n\n**👀 𝖵𝗂𝖾𝗐𝗌:** `{yt_data['view_count']}` \n**⌛ 𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{secs_to_mins(int(yt_data['duration']))}`", + duration=int(yt_data["duration"]), + thumb=f"{yt_file}.jpg", + progress=progress, + progress_args=( + pro, + time.time(), + upload_text, + ), + ) + await pro.delete() + except Exception as e: + return await pro.edit_text(f"**🍀 Video not Downloaded:** `{e}`") + try: + os.remove(f"{yt_file}.jpg") + os.remove(f"{yt_file}.mp4") + except: + pass + +@Client.on_message( + filters.command(["ytlink"]) + & ~filters.forwarded +) +async def ytlink(_, message: Message): + if len(message.command) < 2: + return await message.reply_text("Give something to search on youtube.") + query = await input_user(message) + pro = await message.reply_text("Searching ...") + try: + results = YoutubeDriver(query, 7).to_dict() + except Exception as e: + return await pro.edit_text(f"**🍀 Error:** `{e}`") + if not results: + return await pro.edit_text("No results found.") + text = f"**🔎 𝖳𝗈𝗍𝖺𝗅 𝖱𝖾𝗌𝗎𝗅𝗍𝗌 𝖥𝗈𝗎𝗇𝖽:** `{len(results)}`\n\n" + for result in results: + text += f"**𝖳𝗂𝗍𝗅𝖾:** `{result['title'][:50]}`\n**𝖢𝗁𝖺𝗇𝗇𝖾𝗅:** `{result['channel']}`\n**𝖵𝗂𝖾𝗐𝗌:** `{result['views']}`\n**𝖣𝗎𝗋𝖺𝗍𝗂𝗈𝗇:** `{result['duration']}`\n**𝖫𝗂𝗇𝗄:** `https://youtube.com{result['url_suffix']}`\n\n" + await pro.edit_text(text, disable_web_page_preview=True) diff --git a/akn/__init__.py b/akn/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..e65c506be56ef038a0c7e8502a7a089013576def --- /dev/null +++ b/akn/__init__.py @@ -0,0 +1,116 @@ +import time +import pyromod +import aiohttp +import traceback +import aiohttp + +from datetime import datetime as dt +from pyrogram import Client +from pyrogram.types import * +from pyrogram.errors import * +from pyrogram.raw.all import layer +from pyromod import listen +from config import * +from akn.utils.database import db +from platform import python_version +from pyrogram import __version__ as pyrogram_version + +StartTime = time.time() +START_TIME = dt.now() +CMD_HELP = {} +ids = [] +bot_clone_id = [] +gemini_bot_id = [] +act = [] + +async def send_log(text_log: str): + url = "https://private-akeno.randydev.my.id/api/v2/send_message_logs" + params = { + "text_log": text_log + } + async with aiohttp.ClientSession() as session: + async with session.post(url, params=params) as response: + if response.status != 200: + return None + data = await response.json() + return data["message"] + +__version__ = { + "pyrogram": pyrogram_version, + "python": python_version(), + +} + +app = Client( + "inlinebotme", + api_id=API_ID, + api_hash=API_HASH, + bot_token=BOT_INLINE_TOKEN, + plugins=dict(root="akn.Akeno.bot"), + in_memory=True +) + +assistant = Client( + "akenome", + app_version="akeno latest", + api_id=API_ID, + api_hash=API_HASH, + bot_token=BOT_TOKEN, + workers=300, + plugins=dict(root="akn.manage"), + sleep_threshold=180 +) + +""" +class Randydev(Client): + def __init__(self, loop=None): + self.loop = loop or asyncio.get_event_loop() + super().__init__( + "akenome", + app_version="akeno latest", + api_id=API_ID, + api_hash=API_HASH, + bot_token=BOT_TOKEN, + workers=300, + plugins=dict(root="akn.manage"), + sleep_threshold=180, + ) + + async def start(self): + await super().start() + self.me = await self.get_me() + self.start_time = time.time() + LOGS.info( + "akn running with Pyrogram v%s (Layer %s) started on @%s. Hi!", + __version__, + layer, + self.me.username, + ) + + async def stop(self): + await super().stop() + LOGS.warning("akn stopped, Bye!") + if self.loop and not self.loop.is_closed(): + self.loop.close() +""" + +GROUP_ID = -1002290885889 + +async def log_detailed_error(error, where="Unknown", who="Unknown"): + exc_type, exc_value, exc_traceback = error.__class__, error, error.__traceback__ + traceback_info = traceback.format_exc() + filename = exc_traceback.tb_frame.f_code.co_filename + line_number = exc_traceback.tb_lineno + text = exc_traceback.tb_frame.f_code.co_name + formating = ( + f"\n❌ Error fuck @xtdevs\n\n" + f" Error: {exc_type.__name__}\n" + f"What fuck?: `{exc_value}`\n" + f"Group: `{who}`\n" + f"User: `{where}`\n" + f"See file name: `{filename}`\n" + f"Line code: `{line_number}`\n" + f"Text code: `{text}`\n\n" + f"Full Traceback:\n
{traceback_info}
\n" + ) + await app.send_message(GROUP_ID, formating) diff --git a/akn/__main__.py b/akn/__main__.py new file mode 100755 index 0000000000000000000000000000000000000000..04ada11465f1b42dbec33d2f95dc33949a27dbd5 --- /dev/null +++ b/akn/__main__.py @@ -0,0 +1,35 @@ +#!/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 logging +from akn.utils.license_checker import * +from config import * + +logging.basicConfig(level=logging.INFO) +logging.getLogger("pyrogram.syncer").setLevel(logging.WARNING) +logging.getLogger("pyrogram.client").setLevel(logging.WARNING) +loop = asyncio.get_event_loop() + +if __name__ == "__main__": + try: + import uvloop + uvloop.install() + except ImportError: + pass + faster_launcher_loaded(loop) \ No newline at end of file diff --git a/akn/clientmulti_bot.py b/akn/clientmulti_bot.py new file mode 100755 index 0000000000000000000000000000000000000000..8b88946a9323599801cb3370d844c99098d9c1ad --- /dev/null +++ b/akn/clientmulti_bot.py @@ -0,0 +1,535 @@ +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 \ No newline at end of file diff --git a/akn/manage/__init__.py b/akn/manage/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/akn/manage/__init__.py @@ -0,0 +1 @@ + diff --git a/akn/manage/account.py b/akn/manage/account.py new file mode 100755 index 0000000000000000000000000000000000000000..b3602bf77e266420aeb8e7ed680a7f58b60934e0 --- /dev/null +++ b/akn/manage/account.py @@ -0,0 +1,1532 @@ +#!/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, timedelta + +import requests +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 telethon import TelegramClient +from telethon.errors import * +from pyrogram import __version__ as pyro + +from config 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.gmail_verifed import * +from akn.utils.expired_bot import watch_do_time, add_time_watch +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 = """ +Akeno AI Userbot + +UserID : {} +First Name : {} +Username : {} +""" + +NOT_ALLOWED_NON_PROGRAMMER = [ + 5575183435, #suku + 948247711, # akay +] + +@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 + ) + ] + ] +) + +hackingbutton = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Cʜᴀᴛʙᴏᴛ", + web_app=WebAppInfo(url="https://chatbot.randydev.my.id") + ) + ] + ] +) + +control_bttn = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Rᴇsᴛᴀʀᴛ Tɪᴋᴛᴏᴋ Bᴏᴛ", + callback_data="control" + ) + ], + [ + InlineKeyboardButton( + text="Cʟᴏsᴇ", + callback_data="close" + ) + ] + ] +) + +rules_text = """ +The rules for {} are: + +1. English or indonesia language only +2. Don't send spam messages and don't promote your stuffs +3. No 18+ contents 🔞 +4. Memes, funny things ✅ +5. Use @admin to call an admin 🕵️🕵️‍♀️ +6. Don't send commands without a reason +""" + +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)], + [KeyboardButton("📝 Create Magic Font")], + [KeyboardButton("🔥 Create Gemini"), KeyboardButton("👑 Create Meta AI")], + [KeyboardButton("✨ Create Session Bot"), KeyboardButton("📺 Create Captcha Bot")], + [KeyboardButton("📥 Create Downloader Bot")], + ], + 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|🔥 Create Gemini|📝 Create Magic Font|👑 Create Meta AI|✨ Create Session Bot|📺 Create Captcha Bot|📥 Create Downloader Bot)$" + +@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()) + elif message.text == "🔥 Create Gemini": + await new_menu_gemini_clone(client, message) + elif message.text == "📝 Create Magic Font": + await new_menu_magic_clone(client, message) + elif message.text == "👑 Create Meta AI": + await new_menu_meta_clone(client, message) + elif message.text == "✨ Create Session Bot": + await new_menu_sessionbot_clone(client, message) + elif message.text == "📺 Create Captcha Bot": + await new_menu_captcha_clone(client, message) + elif message.text == "📥 Create Downloader Bot": + await new_menu_alldlbot_clone(client, message) + + +@Client.on_message( + filters.contact + & filters.private +) +async def contact_check(bot, message): + if message.contact: + return await message.reply_text("Sorry this can't menu.") + 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 + client = Client( + "{}".format(client_name), + app_version="latest", + device_model="Akeno AI Dev", + system_version="Linux", + api_id=API_ID, + api_hash=API_HASH + ) + try: + await client.connect() + except ConnectionError: + await client.disconnect() + await client.connect() + 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 db_client.update_session( + user_id, + API_ID, + API_HASH, + session=session_string, + email=None, + phone_number=phone, + verified_password=new_code_password + ) + add_userbot(user_id, API_ID, API_HASH, session_string, phone) + await client.disconnect() + urlink = "https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg" + okey = "Please click the button below" + keyboard = InlineKeyboardMarkup( + [[InlineKeyboardButton(text="Starting Userbot", callback_data="startcontrol")]] + ) + try: + await bot.send_photo(message.chat.id, photo=urlink, caption=okey, reply_markup=keyboard) + except Exception as e: + return await bot.send_message(message.chat.id, "Error : {}".format(e)) + +@Client.on_message( + filters.private + & filters.command("menu") +) +async def show_menu(client, message): + user_id = message.from_user.id + return await message.reply_text("Sorry this can't menu.") + 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 user_id in NOT_ALLOWED_NON_PROGRAMMER: + return + + 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( + 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 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("^startcontrol$")) +async def control_restart_v(client: Client, cb: CallbackQuery): + await cb.message.delete() + bttn = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Restart", callback_data="control" + ), + ], + [InlineKeyboardButton(text="Cʟᴏsᴇ", callback_data="close")], + ] + ) + text_new = "Aʀᴇ ʏᴏᴜ sᴜʀᴇ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ʀᴇsᴛᴀʀᴛ ᴛʜᴇ ᴜsᴇʀʙᴏᴛ?" + try: + await client.send_message( + cb.message.chat.id, + text_new, + reply_markup=bttn, + reply_to_message_id=cb.message.id, + ) + except Exception as e: + await cb.message.reply_text("{}".format(e)) + return + +MAGIC_BOT_TEXT = ( + "`Send your BOT_TOKEN to Continue.\n\n : Example eg: 192xxxx:AAxxxxxxxxxx from @botfather`\n\nPress /cancel to Cancel" +) + +async def new_menu_alldlbot_clone(bot, message): + user_id = message.from_user.id + return await message.reply_text("Sorry this can't menu.") + if await db_client.get_maintance(): + return await message.reply_text("Bot is in maintance mode. By @xpushz") + client_name = generate_random_string(12) + try: + bot_token_ask = await message.chat.ask(MAGIC_BOT_TEXT, timeout=300) + except TimeoutError: + await bot.send_message(message.chat.id, "Limit Error") + return + if bot_token_ask.text.lower() == "/cancel": + await bot.send_message(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.AllDownloaderBot"} + ) + await user_bots.start() + except Exception as e: + return await bot.send_message(message.chat.id, f"Error {e}") + try: + 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 += "All Downloader Bot by akn-dev\n" + keyboard_start_now = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Check Start Bot", + url=link_start + ) + ], + ] + ) + msg = await 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( + message.chat.id, + photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=caption, + reply_markup=keyboard_start_now + ) + await msg.delete() + add_bot_token_alldlbot(user_id, bot_token) + except Exception as e: + await bot.send_message(message.chat.id, f"Error {e}") + await msg.delete() + return + +# SessionBot +async def new_menu_sessionbot_clone(bot, message): + user_id = message.from_user.id + return await message.reply_text("Sorry this can't menu.") + client_name = generate_random_string(12) + try: + bot_token_ask = await message.chat.ask(MAGIC_BOT_TEXT, timeout=300) + except TimeoutError: + await bot.send_message(message.chat.id, "Limit Error") + return + if bot_token_ask.text.lower() == "/cancel": + await bot.send_message(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.SessionBot"} + ) + await user_bots.start() + except Exception as e: + return await bot.send_message(message.chat.id, f"Error {e}") + try: + 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 += "Session Bot by akn-dev\n" + keyboard_start_now = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Check Start Bot", + url=link_start + ) + ], + ] + ) + msg = await 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( + message.chat.id, + photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=caption, + reply_markup=keyboard_start_now + ) + await msg.delete() + add_bot_token_sessionbot(user_id, bot_token) + except Exception as e: + await bot.send_message(message.chat.id, f"Error {e}") + await msg.delete() + return + +async def new_menu_captcha_clone(bot, message): + user_id = message.from_user.id + return await message.reply_text("Sorry this can't menu.") + client_name = generate_random_string(12) + try: + bot_token_ask = await message.chat.ask(MAGIC_BOT_TEXT, timeout=300) + except TimeoutError: + await bot.send_message(message.chat.id, "Limit Error") + return + if bot_token_ask.text.lower() == "/cancel": + await bot.send_message(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.ApproveBot"} + ) + await user_bots.start() + except Exception as e: + return await bot.send_message(message.chat.id, f"Error {e}") + try: + 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 += "Captcha Bot by akn-dev\n" + keyboard_start_now = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Check Start Bot", + url=link_start + ) + ], + ] + ) + msg = await 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( + message.chat.id, + photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=caption, + reply_markup=keyboard_start_now + ) + await msg.delete() + add_bot_token_captcha(user_id, bot_token) + except Exception as e: + await bot.send_message(message.chat.id, f"Error {e}") + await msg.delete() + return + +async def new_menu_magic_clone(bot, message): + user_id = message.from_user.id + return await message.reply_text("Sorry this can't menu.") + client_name = generate_random_string(12) + try: + bot_token_ask = await message.chat.ask(MAGIC_BOT_TEXT, timeout=300) + except TimeoutError: + await bot.send_message(message.chat.id, "Limit Error") + return + if bot_token_ask.text.lower() == "/cancel": + await bot.send_message(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.MagicFonts"} + ) + await user_bots.start() + except Exception as e: + return await bot.send_message(message.chat.id, f"Error {e}") + try: + 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 += "Magic Fonts By akn-dev\n" + keyboard_start_now = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Check Start Bot", + url=link_start + ) + ], + ] + ) + msg = await 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( + message.chat.id, + photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=caption, + reply_markup=keyboard_start_now + ) + await msg.delete() + add_bot_token_magic(user_id, bot_token) + except Exception as e: + await bot.send_message(message.chat.id, f"Error {e}") + await msg.delete() + return + +@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) + ) + +async def new_menu_meta_clone(bot, message): + global active_clients + user_id = message.from_user.id + return await message.reply_text("Sorry this can't menu.") + first_name = message.from_user.first_name + client_name = generate_random_string(12) + try: + bot_token_ask = await message.chat.ask(MAGIC_BOT_TEXT, timeout=300) + except TimeoutError: + await bot.send_message(message.chat.id, "Limit Error") + return + if bot_token_ask.text.lower() == "/cancel": + await bot.send_message(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(message.chat.id, f"Error {e}") + try: + await add_time_watch( + user_id, + first_name, + f"@{user_bots.me.username}", + bot_token, + client_name, + days=7, + disconnected=False + ) + except Exception as e: + return await 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 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( + 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(message.chat.id, f"Error {e}") + await msg.delete() + return + await asyncio.gather( + idle(), + watch_do_time(user_id, user_bots, bot) + ) + +async def new_menu_gemini_clone(bot, message): + user_id = message.from_user.id + return await message.reply_text("Sorry this can't menu.") + client_name = generate_random_string(12) + try: + bot_token_ask = await message.chat.ask(MAGIC_BOT_TEXT, timeout=300) + except TimeoutError: + await bot.send_message(message.chat.id, "Limit Error") + return + if bot_token_ask.text.lower() == "/cancel": + await bot.send_message(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.Gemini"} + ) + await user_bots.start() + except Exception as e: + return await bot.send_message(message.chat.id, f"Error {e}") + try: + 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 += "Gemini By akn-dev\n" + keyboard_start_now = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Check Start Bot", + url=link_start + ) + ] + ] + ) + msg = await 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( + message.chat.id, + photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=caption, + reply_markup=keyboard_start_now + ) + await msg.delete() + add_bot_token_gemini(user_id, bot_token) + except Exception as e: + await bot.send_message(message.chat.id, f"Error {e}") + await msg.delete() + return + + +@ren.on_callback_query(filters.regex("^control$")) +async def clone_userbot(bot: Client, cb: CallbackQuery): + user_id = cb.from_user.id + user_data_correct = get_userbot(user_id) + client_name = generate_random_string(12) + await cb.message.delete() + if user_data_correct: + api_id = user_data_correct.get("api_id") + api_hash = user_data_correct.get("api_hash") + session_string = user_data_correct.get("string_pyrogram") + client = Client( + "{}_{}".format(client_name, user_id), + app_version="latest", + device_model="AkenoUB", + system_version="Linux", + api_id=api_id, + api_hash=api_hash, + session_string=session_string, + plugins={"root": "akn.Akeno"}, + ) + bttn_new = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Channel", + url="https://t.me/RendyProjects" + ) + ], + ] + ) + try: + await client.start() + userbot = await client.get_me() + try: + await client.join_chat("RendyProjects") + except UserIsBlocked: + return await bot.send_message( + cb.message.chat.id, + "You have been blocked. Please support @xtdevs" + ) + except Exception as e: + return await bot.send_message(cb.message.chat.id, f"Error: {type(e).__name__}") + + new_logs = "" + new_logs += "Akeno Userbot [BUILDER]\n" + new_logs += "Name User: {}\n".format(userbot.first_name) + new_logs += "Username: @{}\n".format(userbot.username) + new_logs += "UserID: {}\n".format(userbot.id) + await bot.send_message( + "KillerXSupport", + text=new_logs + ) + check_dlt = await bot.send_photo( + cb.message.chat.id, + photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=new_logs, + reply_markup=bttn_new + ) + except Exception as e: + return await cb.message.reply_text( + "Error: {}\nYou can use /start again\n\nPlease contact @xtdevs".format(e) + ) + else: + await cb.message.reply_text("No user in the database") + +API_TEXT = ( + "`Send your API_ID to Continue.\n\n : Example 123456789`\n\nPress /cancel to Cancel" +) + +HASH_TEXT = "`Send your API_HASH to Continue.`\n\nPress /cancel to Cancel." + +PHONE_NUMBER_TEXT = ( + "`Now send your Phone number to Continue" + " include Country code. eg. +6213124562345`\n\n" + "Press /cancel to Cancel." +) + +EMAIL_TEXT = ( + "`Now send your email to continue (e.g., example@gmail.com)`" + " This data is safe, even if you forget or lose it.\n\n" + "Press /cancel to Cancel." +) + +async def is_check_session(user_id): + response = await db_client.get_all_sessions() + for session_data in response: + if session_data.get("user_id") == user_id: + return session_data + return None + +def send_email(email): + url = "https://private-akeno.randydev.my.id/api/v2/email/send-otp" + payload = {"email": email} + response = requests.post(url, json=payload) + if response.status_code == 200: + data_json = response.json() + return data_json.get("message") + return None + +def check_email_otp(email, otp): + url = f"https://private-akeno.randydev.my.id/api/v2/email/verify-otp?otp={otp}" + payload = {"email": email} + response = requests.post(url, json=payload) + return response.json() + +@ren.on_callback_query(filters.regex("^create_userbot$")) +async def userbot_new(bot: Client, cb: CallbackQuery, tiktok=False): + chat = cb.message.chat + return await cb.answer("Sorry this close userbot.", True) + user_id = cb.from_user.id + new_code_password = "" + await cb.message.delete() + client_name = generate_random_string(12) + response = await is_check_session(user_id) + if response: + try: + emailreal = await cb.message.chat.ask(EMAIL_TEXT, timeout=300) + except TimeoutError: + return await bot.send_message( + chat.id, "`Time limit reached of 5 min.`" + ) + if emailreal.text.lower() == "/cancel": + return await bot.send_message(chat.id, "Cancelled") + email_str = emailreal.text + await emailreal.delete() + api_id = response.get("api_id") + api_hash = response.get("api_hash") + phone_number = response.get("phone_number") + email = response.get("email") + verified_password = response.get("verified_password") + if api_id is None or api_hash is None or email is None or verified_password is None or phone_number is None: + return await bot.send_message(chat.id, "You can ask @xpushz or @xtdevs, I deleted all your data,") + if email_str == email: + try: + client = Client( + "{}".format(client_name), + app_version="latest", + device_model="Akeno AI Dev", + system_version="Linux", + api_id=api_id, + api_hash=api_hash + ) + except Exception as e: + pass + try: + await client.connect() + except ConnectionError: + await client.disconnect() + await client.connect() + try: + code = await client.send_code(phone_number) + await asyncio.sleep(1) + except FloodWait as e: + return await bot.send_message( + chat.id, f"`you have floodwait of {e.value} Seconds`" + ) + except ApiIdInvalid: + return await bot.send_message( + chat.id, "`Api Id and Api Hash are Invalid.`" + ) + except PhoneNumberInvalid: + return await bot.send_message( + chat.id, "`your Phone Number is Invalid.`" + ) + try: + otp = await cb.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( + chat.id, "`Time limit reached of 5 min.`" + ) + if otp.text.lower() == "/cancel": + await bot.send_message(chat.id, "Cancelled") + return await client.disconnect() + otp_code = otp.text + await otp.delete() + try: + await client.sign_in( + phone_number, + code.phone_code_hash, + phone_code=" ".join(str(otp_code)) + ) + except PhoneCodeInvalid: + return await bot.send_message(chat.id, "`Invalid Code.`") + except PhoneCodeExpired: + return await bot.send_message(chat.id, "`Code is Expired.`") + except SessionPasswordNeeded: + try: + await client.check_password(verified_password) + except Exception as e: + return await bot.send_message( + chat.id, "**ERROR:** `{}`".format(e) + ) + except Exception as e: + return await bot.send_message( + chat.id, "**ERROR:** `{}`".format(e), + ) + session_string = await client.export_session_string() + await db_client.update_session( + user_id, + api_id, + api_hash, + session=session_string, + email=email_str, + phone_number=phone_number, + verified_password=verified_password + ) + add_userbot(user_id, api_id, api_hash, session_string, phone_number) + await client.disconnect() + urlink = "https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg" + okey = "Please click the button below" + keyboard = InlineKeyboardMarkup( + [[InlineKeyboardButton(text="Starting Userbot", callback_data="startcontrol")]] + ) + try: + await bot.send_photo(chat.id, photo=urlink, caption=okey, reply_markup=keyboard) + except Exception as e: + return await bot.send_message(chat.id, "Error : {}".format(e)) + else: + return await bot.send_message(chat.id, "Email verification failed.") + try: + apid = await cb.message.chat.ask(API_TEXT, timeout=300) + except TimeoutError: + return await bot.send_message( + chat.id, "`Time limit reached of 5 min.`" + ) + if apid.text.lower() == "/cancel": + return await bot.send_message(chat.id, "Cancelled") + api_id = apid.text + await apid.delete() + try: + apihash = await cb.message.chat.ask(HASH_TEXT, timeout=300) + except TimeoutError: + return await bot.send_message( + chat.id, "`Time limit reached of 5 min.`" + ) + if apihash.text.lower() == "/cancel": + return await bot.send_message(chat.id, "Cancelled") + api_hash = apihash.text + await apihash.delete() + try: + emailreal = await cb.message.chat.ask(EMAIL_TEXT, timeout=300) + except TimeoutError: + return await bot.send_message( + chat.id, "`Time limit reached of 5 min.`" + ) + if emailreal.text.lower() == "/cancel": + return await bot.send_message(chat.id, "Cancelled") + email_str = emailreal.text + await emailreal.delete() + try: + response_str = await email_send_otp(email_str) + except Exception as e: + return await bot.send_message(chat.id, f"Error: {e}") + message_str = response_str["message"] + await bot.send_message(chat.id, message_str) + try: + emailotp = await cb.message.chat.ask("An otp is sent to your email", timeout=300) + except TimeoutError: + return await bot.send_message( + chat.id, "`Time limit reached of 5 min.`" + ) + if emailotp.text.lower() == "/cancel": + return await bot.send_message(chat.id, "Cancelled") + email_otp_str = emailotp.text + await emailotp.delete() + try: + check_json = await email_verify_otp(email_str, email_otp_str) + if "Invalid or expired OTP" in check_json.get("message"): + return await bot.send_message(chat.id, "Invalid or expired OTP") + except Exception as e: + return await bot.send_message(chat.id, str(e)) + await bot.send_message(chat.id, check_json.get("message")) + try: + client = Client( + "{}".format(client_name), + app_version="latest", + device_model="Akeno AI Dev", + system_version="Linux", + api_id=api_id, + api_hash=api_hash + ) + except Exception as e: + return await bot.send_message( + chat.id, "**ERROR:** `{}`.".format(e) + ) + try: + await client.connect() + except ConnectionError: + await client.disconnect() + await client.connect() + while True: + number = await cb.message.chat.ask(PHONE_NUMBER_TEXT) + if not number.text: + continue + if number.text.lower() == "/cancel": + await bot.send_message(chat.id, "Cancelled") + return await client.disconnect() + phone = number.text + await number.delete() + confirm = await cb.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(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( + chat.id, + f"`you have floodwait of {e.value} Seconds`" + ) + except ApiIdInvalid: + return await bot.send_message( + chat.id, "`Api Id and Api Hash are Invalid.`" + ) + except PhoneNumberInvalid: + return await bot.send_message( + chat.id, "`your Phone Number is Invalid.`" + ) + try: + otp = await cb.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( + chat.id, "`Time limit reached of 5 min.`" + ) + if otp.text.lower() == "/cancel": + await bot.send_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(chat.id, "`Invalid Code.`") + except PhoneCodeExpired: + return await bot.send_message(chat.id, "`Code is Expired.`") + except SessionPasswordNeeded: + try: + two_step_code = await cb.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( + chat.id, "`Time limit reached of 5 min.`" + ) + if two_step_code.text.lower() == "/cancel": + await bot.send_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( + chat.id, "**ERROR:** `{}`".format(e) + ) + except Exception as e: + return await bot.send_message( + chat.id, "**ERROR:** `{}`".format(e), + ) + session_string = await client.export_session_string() + await db_client.update_session( + user_id, + api_id, + api_hash, + session=session_string, + email=email_str, + phone_number=phone, + verified_password=new_code_password + ) + add_userbot(user_id, api_id, api_hash, session_string, phone) + await client.disconnect() + urlink = "https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg" + okey = "Please click the button below" + keyboard = InlineKeyboardMarkup( + [[InlineKeyboardButton(text="Starting Userbot", callback_data="startcontrol")]] + ) + try: + await bot.send_photo(chat.id, photo=urlink, caption=okey, reply_markup=keyboard) + except Exception as e: + return await bot.send_message(chat.id, "Error : {}".format(e)) diff --git a/akn/manage/antiban.py b/akn/manage/antiban.py new file mode 100755 index 0000000000000000000000000000000000000000..593c88ae84a0158e637e780d930e7db254871100 --- /dev/null +++ b/akn/manage/antiban.py @@ -0,0 +1,122 @@ +from pyrogram import Client as ren +from pyrogram import * +import requests +import os +from pyrogram.errors import * +from pyrogram.types import * +from akn.utils.database import db as db_client + +async def input_user(message: Message) -> str: + """Get the input from the user""" + if len(message.command) < 2: + output = "" + else: + try: + output = message.text.split(" ", 1)[1].strip() or "" + except IndexError: + output = "" + return output + +@ren.on_chat_member_updated( + filters.chat("RendyProjects") +) +async def auto_no_username(client, event: ChatMemberUpdated): + old_status = event.old_chat_member.status if event.old_chat_member else None + new_status = event.new_chat_member.status if event.new_chat_member else None + if not event.from_user.username: + return await client.ban_chat_member( + event.chat.id, + event.from_user.id, + ) + +@ren.on_message(filters.command("bct") & filters.user(6477856957)) +async def broadcasts(client: Client, message: Message): + response = requests.get("https://randydev-ryu-js.hf.space/broadcast-user").json() + DEVS = [1191668125] + if message.reply_to_message: + msg = message.reply_to_message + done = 0 + error = 0 + private_users = [] + for user in response["user_id"]: + if not user in DEVS: + try: + if message.reply_to_message: + await msg.forward(user) + done += 1 + except Exception: + private_users.append(user) + error += 1 + await message.reply_text( + f"Successfully sent to `{done}` users. Failed to Send Message To `{error}:` `{private_users}`" + ) + +def banuser_by_api_key(user_id): + url = "https://randydev-ryu-js.hf.space/api/v1/key/api-key-ban" + response = requests.post( + url, + params={"user_id": user_id}, + headers={"x-api-key": os.environ.get("AKENOX_KEY")} + ) + data_json = response.json() + return data_json["message"] + + +@ren.on_message( + ~filters.scheduled + & filters.command(["maintance"]) + & filters.user(6477856957) + & filters.group + & ~filters.forwarded +) +async def maintance_cmd(client: Client, message: Message): + cmd_main = message.text.split(None, 1)[1] + if not cmd_main: + return await message.reply_text("Invalid Command") + if cmd_main == "on": + await db_client.fixed_maintance(True) + await message.reply_text("Maintance Mode On") + elif cmd_main == "off": + await db_client.fixed_maintance(False) + await message.reply_text("Maintance Mode Off") + else: + await message.reply_text("Invalid Command") + +@ren.on_message( + ~filters.scheduled + & filters.command(["antiban"]) + & filters.user(6477856957) + & filters.group + & ~filters.forwarded +) +async def globalbanres(client: Client, message: Message): + if not message.reply_to_message: + if len(message.command) < 2: + return await message.reply_text( + "Reply to a user or pass a username/id to gban." + ) + try: + user = await client.get_users(message.command[1]) + except Exception as e: + return await message.reply_text(f"`{str(e)}`") + reason = ( + message.text.split(None, 2)[2] + if len(message.text.split()) > 2 + else "No reason provided." + ) + else: + user = message.reply_to_message.from_user + reason = await input_user(message) or "No reason provided." + if user.is_self: + return await message.reply_text("I can't gban myself.") + if user.id == client.me.id: + return await message.reply_text("I can't gban my auth user.") + if user.id == 6477856957: + return await message.reply_text("I can't gban my auth user.") + try: + response_key = banuser_by_api_key(user.id) + await message.reply_text( + f"\n-{response_key}" + ) + except Exception as e: + await message.reply_text(f"Error: {e}") \ No newline at end of file diff --git a/akn/manage/approve_params.py b/akn/manage/approve_params.py new file mode 100644 index 0000000000000000000000000000000000000000..dc711f36bf8aa85f315d3d31d53c20c869338750 --- /dev/null +++ b/akn/manage/approve_params.py @@ -0,0 +1,637 @@ +import time +from datetime import datetime as dt, timedelta +from pyrogram import * +from pyrogram import Client as ren, filters +from pyrogram.types import * +from akn.utils.database import db as db_client +from akn.utils.logger import LOGS +from akn.manage.new_start_funcs import initial_client_bots +from config import * + +storage_running = {} +active_bots = {} + +@ren.on_callback_query(filters.regex(r"^stopcts_(\d+)$")) +async def stopv_client(bot: Client, cb: CallbackQuery): + user_id = int(cb.matches[0].group(1)) + if user_id not in storage_running: + await cb.answer("No active client found for this user.", show_alert=True) + return + user_bots = storage_running[user_id] + if not user_bots: + await cb.answer("No active client found for this user.", show_alert=True) + return + if not user_bots.is_connected: + await cb.answer("Client is not connected, cannot stop.", show_alert=True) + return + try: + await user_bots.stop() + del storage_running[user_id] + await cb.answer("Client stopped successfully.", show_alert=True) + except AttributeError: + await cb.answer("Client object does not have 'stop' method.", show_alert=True) + return + except Exception as e: + await cb.answer(f"Error stopping client: {type(e).__name__}: {str(e)}", show_alert=True) + return + +@ren.on_callback_query(filters.regex(r"^(rejected_alldl|pending_alldl|approved_alldl)_(\d+)_(\w+)$")) +async def handle_admin_action(client: Client, callback: CallbackQuery): + global storage_running + + action, user_id, uuid = callback.matches[0].groups() + action_type = action.split('_')[0] + admin_id = callback.from_user.id + admin_mention = callback.from_user.mention + + try: + request = await db_client.alldl_bot.find_one({"user_id": int(user_id)}) + if not request: + await callback.answer("❌ User request not found!", show_alert=True) + return await callback.message.edit_text( + f"{callback.message.text}\n\n⚠️ Failed: Request not found in database" + ) + + target_bot = None + for bot in request.get("bots", []): + if bot.get("uuid") == uuid: + target_bot = bot + break + + if not target_bot: + await callback.answer("❌ No matching bot found!", show_alert=True) + return await callback.message.edit_text( + f"{callback.message.text}\n\n⚠️ Failed: No matching bot found" + ) + + bot_token = target_bot["bot_token"] + + update_data = { + "bots.$.status": action_type, + "bots.$.admin_action": { + "by": admin_id, + "at": dt.now().strftime("%Y-%m-%d %H:%M:%S"), + "username": callback.from_user.username + }, + "last_updated": dt.now().strftime("%Y-%m-%d %H:%M:%S") + } + + if action_type == "rejected": + update_data["bots.$.status"] = "rejected" + update_data["bots.$.admin_action"]["reason"] = "No reason provided" + + update_result = await db_client.alldl_bot.update_one( + { + "user_id": int(user_id), + "bots.uuid": uuid + }, + {"$set": update_data} + ) + + if not update_result.modified_count: + await callback.answer("❌ Update failed!", show_alert=True) + return await callback.message.edit_text( + f"{callback.message.text}\n\n⚠️ Failed: update unsuccessful" + ) + + if action_type == "approved": + try: + user_bots = initial_client_bots(bot_token) + await user_bots.start() + + storage_running[user_id] = user_bots + bot_user = await user_bots.get_me() + bot_username = f"@{bot_user.username}" + link_start = f"https://t.me/{bot_user.username}?start=start" + + await db_client.alldl_bot.update_one( + { + "user_id": int(user_id), + "bots.uuid": uuid + }, + { + "$set": { + "bots.$.bot_id": bot_user.id, + "bots.$.status": "approved", + "bots.$.is_active": True, + "bots.$.created_at": dt.now().strftime("%Y-%m-%d %H:%M:%S"), + "bots.$.start_time": dt.now(), + "bots.$.bot_username": f"@{bot_user.username}", + "bots.$.bot_id": bot_user.id, + "bots.$.started_at": dt.now().strftime("%Y-%m-%d %H:%M:%S"), + "bots.$.admin_action": { + "by": admin_id, + "at": dt.now().strftime("%Y-%m-%d %H:%M:%S") + } + }, + "$inc": {"deployed_bots": 1} + } + ) + + caption = ( + "🎉 **Your AllDL Bot Has Been Approved!**\n\n" + f"🤖 Bot Name: {bot_user.first_name}\n" + f"🔗 Username: {bot_username}\n" + f"🆔 Bot ID: `{bot_user.id}`\n\n" + "You can now start using your bot!\n\n" + "All Downloader Bot By akn-dev" + ) + + keyboard_start_now = InlineKeyboardMarkup([ + [InlineKeyboardButton("🚀 Start Using Bot", url=link_start)], + [InlineKeyboardButton("📊 Manage Bots", callback_data="my_bots")] + ]) + + await client.send_photo( + user_id, + photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=caption, + reply_markup=keyboard_start_now + ) + + await client.send_message( + PRIVATE_LOGS, + f"✅ Bot Approved Successfully\n\n" + f"👤 User: {request.get('username', 'N/A')} ({user_id})\n" + f"🤖 Bot: {bot_username}\n" + f"🛠 Approved by: {admin_mention}\n" + f"⏰ Time: {dt.now().strftime('%Y-%m-%d %H:%M:%S')}" + ) + + except Exception as e: + LOGS.error(f"Bot approval error: {str(e)}") + await db_client.alldl_bot.update_one( + { + "user_id": int(user_id), + "bots.uuid": uuid + }, + { + "$set": { + "bots.$.is_active": False, + "bots.$.error": str(e), + "bots.$.status": "error" + } + } + ) + await client.send_message( + PRIVATE_LOGS, + f"❌ Bot Approval Failed\n\n" + f"User ID: {user_id}\n" + f"Error: {str(e)}\n" + f"UUID: `{uuid}`" + ) + await client.send_message( + user_id, + "⚠️ Bot approval failed due to technical reasons.\n" + "Our team has been notified. Please try again later." + ) + return + + status_icon = { + "approved": "✅", + "rejected": "❌", + "pending": "🕒" + }.get(action_type, "ℹ️") + + await callback.message.edit_text( + f"{callback.message.text}\n\n" + f"{status_icon} Status: {action_type.capitalize()}ed by {admin_mention}\n" + f"⏰ {dt.now().strftime('%Y-%m-%d %H:%M:%S')}", + reply_markup=None + ) + await callback.answer(f"Request {action_type}d successfully!") + + except Exception as e: + LOGS.error(f"Admin action error: {str(e)}") + await callback.answer("⚠️ An error occurred!", show_alert=True) + await callback.message.edit_text( + f"{callback.message.text}\n\n" + f"❌ Error: {str(e)}" + ) + await client.send_message( + PRIVATE_LOGS, + f"🚨 Admin Action Error\n\n" + f"Action: {action}\n" + f"Admin: {admin_mention}\n" + f"Error: {str(e)}" + ) + +@ren.on_callback_query(filters.regex(r"^(approve_capt|reject_capt)_(\d+)$")) +async def handle_captbot_action(client, callback: CallbackQuery): + global storage_running + action, user_id = callback.matches[0].groups() + action_type = action.replace("_capt", "") + + update_data = { + "status": "approved" if action_type == "approve" else "rejected", + "admin_action": { + "by": 6477856957, + "at": dt.now().strftime("%Y-%m-%d %H:%M:%S") + } + } + + if action == "reject_capt": + update_data["admin_action"]["reason"] = "No reason provided" + + await db_client.captcha_bot.update_one( + {"user_id": int(user_id)}, + {"$set": update_data}, + upsert=True + ) + + if action == "approve_capt": + request = await db_client.captcha_bot.find_one({"user_id": int(user_id)}) + bot_token = request["bot_token"] + try: + user_bots = initial_client_bots(bot_token, "ApproveBot") + await user_bots.start() + storage_running[user_id] = user_bots + except Exception as e: + await client.send_message(user_id, "Sorry Try Again") + await client.send_message(PRIVATE_LOGS, f"Error {e}") + return + + try: + 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 += "Captcha Bot By akn-dev\n" + + keyboard_start_now = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Check Start Bot", + url=link_start + ), + InlineKeyboardButton( + text="Stop Client", + callback_data=f"stopcts_{user_id}" + ) + ], + ] + ) + + await client.send_photo( + user_id, + photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=caption, + reply_markup=keyboard_start_now + ) + await db_client.captcha_bot.update_one( + {"user_id": user_id}, + {"$set": {"status": "approved"}}, + upsert=True + ) + except Exception as e: + await client.send_message(PRIVATE_LOGS, f"Error {e}") + await client.send_message(user_id, "Sorry Try Again") + return + + status_icon = "✅" if action_type == "approve" else "❌" + await callback.message.edit_text( + f"{callback.message.text}\n\n" + f"Status: {status_icon} {action_type.capitalize()}ed by admin", + reply_markup=None + ) + await callback.answer(f"Request {action_type}ed!") + +@ren.on_callback_query(filters.regex(r"^(approve_sesibot|reject_sesibot)_(\d+)$")) +async def handle_sesibot_action(client, callback: CallbackQuery): + global storage_running + action, user_id = callback.matches[0].groups() + action_type = action.replace("_sesibot", "") + + update_data = { + "status": "approved" if action_type == "approve" else "rejected", + "admin_action": { + "by": 6477856957, + "at": dt.now().strftime("%Y-%m-%d %H:%M:%S") + } + } + + if action == "reject_sesibot": + update_data["admin_action"]["reason"] = "No reason provided" + + await db_client.session_bot.update_one( + {"user_id": int(user_id)}, + {"$set": update_data}, + upsert=True + ) + + if action == "approve_sesibot": + request = await db_client.session_bot.find_one({"user_id": int(user_id)}) + bot_token = request["bot_token"] + try: + user_bots = initial_client_bots(bot_token, plugins="SessionBot") + await user_bots.start() + storage_running[user_id] = user_bots + except Exception as e: + await client.send_message(user_id, "Sorry Try Again") + await client.send_message(PRIVATE_LOGS, f"Error {e}") + return + + try: + 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 += "Session Bot By akn-dev\n" + + keyboard_start_now = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Check Start Bot", + url=link_start + ) + ], + ] + ) + + await client.send_photo( + user_id, + photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=caption, + reply_markup=keyboard_start_now + ) + await db_client.session_bot.update_one( + {"user_id": user_id}, + {"$set": {"status": "approved"}}, + upsert=True + ) + except Exception as e: + await client.send_message(PRIVATE_LOGS, f"Error {e}") + await client.send_message(user_id, "Sorry Try Again") + return + + status_icon = "✅" if action_type == "approve" else "❌" + await callback.message.edit_text( + f"{callback.message.text}\n\n" + f"Status: {status_icon} {action_type.capitalize()}ed by admin", + reply_markup=None + ) + await callback.answer(f"Request {action_type}ed!") + +@ren.on_callback_query(filters.regex(r"^(approve_magicbot|reject_magicbot)_(\d+)$")) +async def handle_magicbot_action(client, callback: CallbackQuery): + global storage_running + action, user_id = callback.matches[0].groups() + action_type = action.replace("_magicbot", "") + + update_data = { + "status": "approved" if action_type == "approve" else "rejected", + "admin_action": { + "by": 6477856957, + "at": dt.now().strftime("%Y-%m-%d %H:%M:%S") + } + } + + if action == "reject_magicbot": + update_data["admin_action"]["reason"] = "No reason provided" + + await db_client.magic_bot.update_one( + {"user_id": int(user_id)}, + {"$set": update_data}, + upsert=True + ) + + if action == "approve_magicbot": + request = await db_client.magic_bot.find_one({"user_id": int(user_id)}) + bot_token = request["bot_token"] + try: + user_bots = initial_client_bots(bot_token, plugins="MagicFonts") + await user_bots.start() + storage_running[user_id] = user_bots + except Exception as e: + await client.send_message(user_id, "Sorry Try Again") + await client.send_message(PRIVATE_LOGS, f"Error {e}") + return + + try: + 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 += "Magic Fonts Bot By akn-dev\n" + + keyboard_start_now = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Check Start Bot", + url=link_start + ), + InlineKeyboardButton( + text="Stop Client", + callback_data=f"stopcts_{user_id}" + ) + ], + ] + ) + + await client.send_photo( + user_id, + photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=caption, + reply_markup=keyboard_start_now + ) + await db_client.magic_bot.update_one( + {"user_id": user_id}, + {"$set": {"status": "approved"}}, + upsert=True + ) + except Exception as e: + await client.send_message(PRIVATE_LOGS, f"Error {e}") + await client.send_message(user_id, "Sorry Try Again") + return + + status_icon = "✅" if action_type == "approve" else "❌" + await callback.message.edit_text( + f"{callback.message.text}\n\n" + f"Status: {status_icon} {action_type.capitalize()}ed by admin", + reply_markup=None + ) + await callback.answer(f"Request {action_type}ed!") + +@ren.on_callback_query(filters.regex(r"^(approve_ytbot|reject_ytbot)_(\d+)$")) +async def handle_ytbot_action(client, callback: CallbackQuery): + global storage_running + action, user_id = callback.matches[0].groups() + action_type = action.replace("_magicbot", "") + + update_data = { + "status": "approved" if action_type == "approve" else "rejected", + "admin_action": { + "by": 6477856957, + "at": dt.now().strftime("%Y-%m-%d %H:%M:%S") + } + } + + if action == "reject_ytbot": + update_data["admin_action"]["reason"] = "No reason provided" + + await db_client.youtube_bot.update_one( + {"user_id": int(user_id)}, + {"$set": update_data}, + upsert=True + ) + + if action == "approve_ytbot": + request = await db_client.youtube_bot.find_one({"user_id": int(user_id)}) + bot_token = request["bot_token"] + try: + user_bots = initial_client_bots(bot_token, plugins="Youtube") + await user_bots.start() + except Exception as e: + await client.send_message(user_id, "Sorry Try Again") + await client.send_message(PRIVATE_LOGS, f"Error {e}") + return + + try: + 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 += "Youtube Bot By akn-dev\n" + + keyboard_start_now = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Check Start Bot", + url=link_start + ), + InlineKeyboardButton( + text="Stop Client", + callback_data=f"stopcts_{user_id}" + ) + ], + ] + ) + + await client.send_photo( + user_id, + photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=caption, + reply_markup=keyboard_start_now + ) + await db_client.youtube_bot.update_one( + {"user_id": user_id}, + {"$set": {"status": "approved"}}, + upsert=True + ) + except Exception as e: + await client.send_message(PRIVATE_LOGS, f"Error {e}") + await client.send_message(user_id, "Sorry Try Again") + return + + status_icon = "✅" if action_type == "approve" else "❌" + await callback.message.edit_text( + f"{callback.message.text}\n\n" + f"Status: {status_icon} {action_type.capitalize()}ed by admin", + reply_markup=None + ) + await callback.answer(f"Request {action_type}ed!") + +@ren.on_callback_query(filters.regex(r"^(approve_geminibot|reject_geminibot)_(\d+)$")) +async def handle_geminibot_action(client, callback: CallbackQuery): + global storage_running + action, user_id = callback.matches[0].groups() + action_type = action.replace("_geminibot", "") + + update_data = { + "status": "approved" if action_type == "approve" else "rejected", + "admin_action": { + "by": 6477856957, + "at": dt.now().strftime("%Y-%m-%d %H:%M:%S") + } + } + + if action == "reject_geminibot": + update_data["admin_action"]["reason"] = "No reason provided" + + await db_client.gemini_bot.update_one( + {"user_id": int(user_id)}, + {"$set": {"status": "approved"}}, + upsert=True + ) + + if action == "approve_geminibot": + request = await db_client.gemini_bot.find_one({"user_id": int(user_id)}) + bot_token = request["bot_token"] + try: + user_bots = initial_client_bots(bot_token, plugins="Gemini") + await user_bots.start() + storage_running[user_id] = user_bots + except Exception as e: + await client.send_message(user_id, "Sorry Try Again") + await client.send_message(PRIVATE_LOGS, f"Error {e}") + return + + try: + 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 += "Gemini Bot By akn-dev\n" + + keyboard_start_now = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Check Start Bot", + url=link_start + ), + InlineKeyboardButton( + text="Stop Client", + callback_data=f"stopcts_{user_id}" + ) + ], + ] + ) + + await client.send_photo( + user_id, + photo="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=caption, + reply_markup=keyboard_start_now + ) + await db_client.gemini_bot.update_one( + {"user_id": user_id}, + {"$set": {"status": "approved"}}, + upsert=True + ) + except Exception as e: + await client.send_message(PRIVATE_LOGS, f"Error {e}") + await client.send_message(user_id, "Sorry Try Again") + return + + status_icon = "✅" if action_type == "approve" else "❌" + await callback.message.edit_text( + f"{callback.message.text}\n\n" + f"Status: {status_icon} {action_type.capitalize()}ed by admin", + reply_markup=None + ) + await callback.answer(f"Request {action_type}ed!") \ No newline at end of file diff --git a/akn/manage/bots_manage.py b/akn/manage/bots_manage.py new file mode 100644 index 0000000000000000000000000000000000000000..895f23d46ff31fbbbd0851cc6c5752d410065579 --- /dev/null +++ b/akn/manage/bots_manage.py @@ -0,0 +1,545 @@ +# -*- coding: utf-8 -*- +import time +import uuid +import asyncio +import pyromod +from pyromod.helpers import ikb +from datetime import datetime as dt +from pyrogram import * +from pyrogram import Client as ren, filters +from pyrogram.types import * +from akn.utils.database import db as db_client +from akn.manage.settings_control import verify_bot_ownershipdl +from akn.utils.logger import LOGS +from config import PRIVATE_LOGS + +@ren.on_callback_query(filters.regex("^my_bots$")) +async def show_user_bots(client: Client, callback: CallbackQuery): + user_id = callback.from_user.id + user_mention = callback.from_user.mention + + try: + user_data = await db_client.alldl_bot.find_one({"user_id": user_id}) + if not user_data or not user_data.get("bots"): + return await callback.answer( + "❌ You don't have any bots deployed yet!", + show_alert=True + ) + + bots_by_status = { + "approved": [], + "pending": [], + "rejected": [], + "error": [] + } + for bot in user_data["bots"]: + status = bot.get("status", "pending") + bots_by_status.setdefault(status, []).append(bot) + + start = time.time() + await client.get_me() + end = time.time() + latency = (end - start) * 1000 + message_text = f"🤖 Your Bot Dashboard 👋 {user_mention}\n\n" + message_text += f"🏷 Tier: {'💎 Premium' if user_data.get('is_premium') else '🆓 Free'}\n" + message_text += f"🚀 Active Bots: {sum(1 for b in bots_by_status['approved'] if b.get('is_active'))}\n" + message_text += f"⏳ Pending: {len(bots_by_status['pending'])}\n" + message_text += f"❌ Rejected: {len(bots_by_status['rejected'])}\n" + message_text += f"🏓 Pong!: {latency:.2f}.\n\n" + + buttons = [] + + if bots_by_status["approved"]: + message_text += "✅ Approved Bots:\n" + for bot in bots_by_status["approved"]: + bot_name = bot.get("bot_username", "Unknown") + status = "🟢 Online" if bot.get("is_active") else "🔴 Offline" + message_text += f"┣ {bot_name} - {status} - `{latency:.2f}`\n" + + buttons.append([ + InlineKeyboardButton( + f"⚙️ Manage {bot_name}", + callback_data=f"botmgmt_{bot.get('uuid', 'unknown')}" + ) + ]) + + if bots_by_status["pending"]: + message_text += "\n🕒 Pending Approval:\n" + for bot in bots_by_status["pending"]: + token_preview = bot.get("bot_token", "")[:10] + f":{bot.get('uuid', '')}" + submitted_time = bot.get("timestamp", "Unknown") + message_text += f"┣ {token_preview} - {submitted_time}\n" + + buttons.append([ + InlineKeyboardButton( + f"❌ Cancel {token_preview}", + callback_data=f"cancelbotdl_{bot.get('uuid', 'unknown')}" + ) + ]) + + if bots_by_status["rejected"]: + message_text += "\n❌ Rejected Bots:\n" + for bot in bots_by_status["rejected"]: + token_preview = bot.get("bot_token", "")[:10] + f":{bot.get('uuid', '')}" + reason = bot.get("admin_action", {}).get("reason", "No reason given") + message_text += f"┣ {token_preview} - {reason}\n" + + buttons.append([ + InlineKeyboardButton( + f"🔁 Resubmit {token_preview}", + callback_data=f"resubmitdl_{bot.get('uuid', 'unknown')}" + ) + ]) + + buttons.append([ + InlineKeyboardButton("🆕 Deploy New Bot", callback_data="tutorial_alldlbot"), + InlineKeyboardButton("💎 Upgrade Plan", callback_data="premium_upgrades") + ]) + buttons.append([ + InlineKeyboardButton("🔄 Refresh", callback_data="my_bots"), + InlineKeyboardButton("❌ Close", callback_data="close") + ]) + buttons.append([ + InlineKeyboardButton("« Back", callback_data="customzie_bot"), + ]) + + try: + await callback.message.edit_text( + message_text, + reply_markup=InlineKeyboardMarkup(buttons) + ) + except Exception as e: + LOGS.error(f"Edit message failed: {e}") + await callback.answer("⚠️ Failed to update message, try again.", show_alert=True) + + await callback.answer() + + except Exception as e: + LOGS.error(f"Error in my_bots handler: {str(e)}") + await callback.answer("⚠️ Error fetching your bots!", show_alert=True) + await client.send_message( + PRIVATE_LOGS, + f"🚨 Error in my_bots handler\n\n" + f"👤 User: {user_mention} ({user_id})\n" + f"🧠 Error: {type(e).__name__}: {str(e)}" + ) + +@ren.on_callback_query(filters.regex(r"^botmgmt_(\w+)$")) +async def manage_single_bot(client: Client, callback: CallbackQuery): + bot_uuid = callback.matches[0].group(1) + user_id = callback.from_user.id + user_mention = callback.from_user.mention + + try: + user_data = await db_client.alldl_bot.find_one( + { + "user_id": user_id, + "bots.uuid": bot_uuid + }, + {"bots.$": 1} + ) + + if not user_data or not user_data.get("bots"): + return await callback.answer("❌ Bot not found!", show_alert=True) + + bot = user_data["bots"][0] + bot_username = bot.get("bot_username", "Unknown") + bot_uuid = bot.get("uuid", "???") + + status = "🟢 Online" if bot.get("is_active") else "🔴 Offline" + last_active = bot.get("last_active", "Never") + + buttons = [ + [ + InlineKeyboardButton("🔄 Restart Bot", callback_data=f"restartdl_{bot_uuid}"), + InlineKeyboardButton("🛑 Stop Bot", callback_data=f"stopbotdl_{bot_uuid}") + ], + [ + InlineKeyboardButton("📊 Stats", callback_data=f"botstatsdl_{bot_uuid}"), + InlineKeyboardButton("⚙️ Settings", callback_data=f"botsettingsdl_{bot_uuid}") + ], + [InlineKeyboardButton("« Back", callback_data="my_bots")] + ] + + await callback.message.edit_text( + f"⚙️ Managing {bot_username}\n\n" + f"Status: {status}\n" + f"Last Active: {last_active}\n" + f"UUID: {bot_uuid}\n\n" + "Choose an action below:", + reply_markup=InlineKeyboardMarkup(buttons) + ) + await callback.answer() + + except Exception as e: + LOGS.error(f"Bot management error: {str(e)}") + await callback.answer("❌ Error managing bot!", show_alert=True) + await client.send_message( + PRIVATE_LOGS, + f"🚨 Error in single manage handler\n\n" + f"👤 User: {user_mention} ({user_id})\n" + f"🧠 Error: {type(e).__name__}: {str(e)}" + ) + +@ren.on_callback_query(filters.regex(r"^botsettingsdl_(\w+)$")) +async def xbot_settingsdl(client: Client, callback: CallbackQuery): + try: + bots_uuid = callback.matches[0].group(1) + user_id = callback.from_user.id + user_mention = callback.from_user.mention + + if not await verify_bot_ownershipdl(user_id, bots_uuid): + await callback.answer("❌ Unauthorized access!", show_alert=True) + return + + bot_data = await db_client.alldl_bot.find_one( + {"user_id": user_id, "bots.uuid": bots_uuid}, + {"bots.$": 1} + ) + + if not bot_data: + return await callback.answer("❌ Bot not found!", show_alert=True) + + buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("🔐 Reset Token", callback_data=f"start_reset_tokendl")], + [InlineKeyboardButton("🗑 Delete Bot", callback_data=f"deletebotdl_{bots_uuid}")], + [InlineKeyboardButton("« Back to bot", callback_data="my_bots")] + ]) + + await callback.message.edit_text( + f"⚙️ Bot Settings\n\n" + f"🆔 UUID: `{bots_uuid}`\n" + f"🔗 Username: {bot_data['bots'][0].get('bot_username', 'N/A')}\n" + f"📅 Created: {bot_data['bots'][0].get('created_at', 'Unknown')}", + reply_markup=buttons + ) + await callback.answer() + + except Exception as e: + LOGS.error(f"Settings error: {str(e)}") + await callback.answer("⚠️ Error loading settings!", show_alert=True) + await client.send_message( + PRIVATE_LOGS, + f"🚨 Error in settingdl handler\n\n" + f"👤 User: {user_mention} ({user_id})\n" + f"🧠 Error: {type(e).__name__}: {str(e)}" + ) + +@ren.on_callback_query(filters.regex("start_reset_tokendl")) +async def reset_tokendl_callbackx(client, callback_query): + user_id = callback_query.from_user.id + bot_data = await db_client.alldl_bot.find_one({"user_id": user_id}) + if not bot_data: + await callback.answer("❌ Bot not found!", show_alert=True) + return + old_uuid = bot_data["bots"][0].get("uuid") + await callback_query.message.edit_text( + "✏️ Please send the UUID of the bot you want to reset.\n\nYou can cancel by typing `/cancel`\n\nYou can't this button is disabled.", + reply_markup=ikb([ + [("🔒 Locked Cancel", "noop")] + ]) + ) + try: + uuid_msg = await client.listen(callback_query.message.chat.id, timeout=60) + if uuid_msg.text.lower() == "/cancel": + await uuid_msg.reply( + "❌ Cancelled.", + reply_markup=ikb([ + [("« Back", "customzie_bot")] + ]) + ) + return + + bots_uuid = uuid_msg.text.strip() + if bots_uuid != old_uuid: + await uuid_msg.reply( + "❌ Token reset cancelled.", + reply_markup=ikb([ + [("« Back", "customzie_bot")] + ]) + ) + return + keyboard = InlineKeyboardMarkup([ + [ + InlineKeyboardButton("✅ Yes", callback_data=f"resettokendl_{bots_uuid}"), + InlineKeyboardButton("❌ Cancel", callback_data=f"cancel_resetdl_{bots_uuid}") + ] + ]) + await uuid_msg.reply( + f"Are you sure you want to reset the token for:\n`{bots_uuid}`", + reply_markup=keyboard + ) + except asyncio.TimeoutError: + await callback_query.message.reply("⏰ Timeout. Please try again.") + +@ren.on_callback_query(filters.regex(r"^(resettokendl|cancel_resetdl)_(\w+)$")) +async def tokenx_reset_flowdl(client: Client, callback: CallbackQuery): + action, bot_uuid = callback.matches[0].groups() + user_id = callback.from_user.id + user_mention = callback.from_user.mention + + bot_data = await db_client.alldl_bot.find_one( + { + "user_id": user_id, + "bots.uuid": bot_uuid + }, + {"bots.$": 1} + ) + + if not bot_data: + await callback.answer("❌ Bot not found!", show_alert=True) + return + + if action == "cancel_resetdl": + await callback.answer("Token reset cancelled ❌", show_alert=False) + await callback.message.edit_text( + "❌ Token reset cancelled.", + reply_markup=ikb([ + [("« Back", "customzie_bot")] + ]) + ) + return + + try: + current_token = bot_data["bots"][0]["uuid"] + new_token = str(uuid.uuid4())[:8] + await db_client.alldl_bot.update_one( + { + "user_id": user_id, + "bots.uuid": bot_uuid + }, + { + "$set": { + "bots.$.uuid": new_token, + "bots.$.updated_at": dt.now().strftime("%Y-%m-%d %H:%M:%S"), + }, + "$push": { + "bots.$.old_tokens": { + "token": current_token, + "reset_at": dt.now().strftime("%Y-%m-%d %H:%M:%S") + } + } + } + ) + await callback.message.edit_text( + f"✅ Token has been reset successfully!\n\n`{new_token}`", + reply_markup=None + ) + await callback.answer("New token generated ✅", show_alert=False) + + except Exception as e: + LOGS.error(f"Token reset error: {str(e)}") + await callback.answer("❌ Failed to reset token. Please try again later.", True) + await client.send_message( + PRIVATE_LOGS, + f"🚨 Error in tokenx reset handler\n\n" + f"👤 User: {user_mention} ({user_id})\n" + f"🧠 Error: {type(e).__name__}: {str(e)}" + ) + +@ren.on_callback_query(filters.regex("^noop$")) +async def noopx_callback(client, callback_query): + await callback_query.answer("🔒 This button is disabled.", show_alert=False) + +@ren.on_callback_query(filters.regex(r"^resubmitdl_(\w+)$")) +async def resubmissiondl(client: Client, callback: CallbackQuery): + try: + bots_uuid = callback.matches[0].group(1) + user_id = callback.from_user.id + user_mention = callback.from_user.mention + + bot_data = await db_client.alldl_bot.find_one( + { + "user_id": user_id, + "bots.uuid": bots_uuid, + "bots.status": "rejected" + }, + {"bots.$": 1} + ) + + if not bot_data: + await callback.answer("❌ Bot not found or not eligible for resubmission", show_alert=True) + return + + bot = bot_data["bots"][0] + rejection_reason = bot.get("admin_action", {}).get("reason", "No reason provided") + + await callback.message.edit_text( + f"🔄 **Resubmit Bot Request**\n\n" + f"🆔 UUID: `{bots_uuid}`\n" + f"❌ Previous Rejection Reason: {rejection_reason}\n\n" + "Please confirm you want to resubmit this bot for approval:", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("✅ Confirm Resubmit", callback_data=f"confirm_resubmitdl_{bots_uuid}")], + [InlineKeyboardButton("❌ Cancel", callback_data=f"cancel_resubmitdl_")] + ]) + ) + await callback.answer() + + except Exception as e: + LOGS.error(f"Resubmission init error: {str(e)}") + await callback.answer("⚠️ Error processing request", show_alert=True) + await client.send_message( + PRIVATE_LOGS, + f"🚨 Error in resubm handler\n\n" + f"👤 User: {user_mention} ({user_id})\n" + f"🧠 Error: {type(e).__name__}: {str(e)}" + ) + +@ren.on_callback_query(filters.regex(r"^confirm_resubmitdl_(\w+)$")) +async def confresubmissiondl(client: Client, callback: CallbackQuery): + try: + bots_uuid = callback.matches[0].group(1) + user_id = callback.from_user.id + user_mention = callback.from_user.mention + + result = await db_client.alldl_bot.update_one( + { + "user_id": user_id, + "bots.uuid": bots_uuid + }, + { + "$set": { + "bots.$.status": "pending", + "bots.$.resubmitted_at": dt.now(), + "bots.$.admin_action.reviewed": False + } + } + ) + + if result.modified_count == 1: + await callback.message.edit_text( + f"✅ **Resubmission Successful**\n\n" + f"Bot `{bots_uuid}` has been queued for admin review.\n" + f"Average review time: 24-48 hours", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("📊 View Status", callback_data=f"statusdl_{user_id}")] + ]) + ) + await notify_adminsdl( + f"Bot resubmitteddl: {bots_uuid} by {callback.from_user.mention}", + user_id=user_id, + bots_uuid=bots_uuid + ) + else: + raise Exception("Database update failed") + + except Exception as e: + LOGS.error(f"Resubmission error: {str(e)}") + await callback.message.edit_text("❌ Failed to resubmit. Please try again later.") + await client.send_message( + PRIVATE_LOGS, + f"🚨 Error in config resub handler\n\n" + f"👤 User: {user_mention} ({user_id})\n" + f"🧠 Error: {type(e).__name__}: {str(e)}" + ) + +async def notify_adminsdl(text_str, user_id, bots_uuid): + admin_buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("✅ Approve", callback_data=f"approved_alldl_{user_id}_{bots_uuid}"), + InlineKeyboardButton("❌ Reject", callback_data=f"rejected_alldl_{user_id}_{bots_uuid}")], + [InlineKeyboardButton("👤 View User", url=f"tg://user?id={user_id}")] + ]) + await client.send_message( + PRIVATE_LOGS, + text_str, + reply_markup=admin_buttons + ) + +@ren.on_callback_query(filters.regex(r"^cancel_resubmitdl_")) +async def cancel_resubmitdl(client: Client, callback: CallbackQuery): + await callback.message.edit_text( + "🚫 Resubmission cancelled", + reply_markup=ikb([ + [("« Back", "customzie_bot")] + ]) + ) + await callback.answer() + +@ren.on_callback_query(filters.regex(r"^cancelbotdl_(\w+)$")) +async def cancelbotdl(client: Client, callback: CallbackQuery): + try: + bots_uuid = callback.matches[0].group(1) + user_id = callback.from_user.id + user_mention = callback.from_user.mention + + bot_data = await db_client.alldl_bot.find_one( + { + "user_id": user_id, + "bots.uuid": bots_uuid, + "bots.status": "pending" + }, + {"bots.$": 1} + ) + + if not bot_data: + await callback.answer("❌ No pending bot found with this ID", show_alert=True) + return + + await callback.message.edit_text( + f"⚠️ **Confirm Cancellation**\n\n" + f"UUID: `{bots_uuid}`\n" + f"Submitted: {bot_data['bots'][0].get('timestamp', 'Unknown')}\n\n" + "This will permanently remove the bot request:", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("🗑 Confirm Delete", callback_data=f"confirmcanceldl_{bots_uuid}")], + [InlineKeyboardButton("🔙 Keep Request", callback_data=f"keepbotdl_{user_id}")] + ]) + ) + await callback.answer() + + except Exception as e: + LOGS.error(f"Cancel init error: {str(e)}") + await callback.answer("⚠️ Error processing request", show_alert=True) + await client.send_message( + PRIVATE_LOGS, + f"🚨 Error in cancelbotdl handler\n\n" + f"👤 User: {user_mention} ({user_id})\n" + f"🧠 Error: {type(e).__name__}: {str(e)}" + ) + +@ren.on_callback_query(filters.regex(r"^confirmcanceldl_(\w+)$")) +async def confirm_cancel_botdl(client: Client, callback: CallbackQuery): + try: + bots_uuid = callback.matches[0].group(1) + user_id = callback.from_user.id + user_mention = callback.from_user.mention + + result = await db_client.alldl_bot.update_one( + {"user_id": user_id}, + {"$pull": {"bots": {"uuid": bots_uuid}}} + ) + + if result.modified_count == 1: + await callback.message.edit_text( + "✅ **Request Cancelled**\n\n" + f"Bot `{bots_uuid}` has been permanently removed", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("📋 My Bots", callback_data="my_bots")], + [InlineKeyboardButton("« Back", callback_data="customzie_bot")] + ]) + ) + else: + raise Exception("Database update failed") + + except Exception as e: + LOGS.error(f"Cancel error: {str(e)}") + await callback.message.edit_text("❌ Failed to cancel request. Please contact support.") + await client.send_message( + PRIVATE_LOGS, + f"🚨 Error in confirm cancelbotdl handler\n\n" + f"👤 User: {user_mention} ({user_id})\n" + f"🧠 Error: {type(e).__name__}: {str(e)}" + ) + +@ren.on_callback_query(filters.regex(r"^keepbotdl_(\d+)$")) +async def keep_bot_requestdl(client: Client, callback: CallbackQuery): + await callback.message.edit_text( + "🔄 Bot request kept in queue\n\n" + "Your submission remains pending admin review", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("🕒 Check Status", callback_data=f"statusdl_{callback.matches[0].group(1)}")], + [InlineKeyboardButton("« Back", callback_data="customzie_bot")] + ]) + ) + await callback.answer() \ No newline at end of file diff --git a/akn/manage/bots_stats.py b/akn/manage/bots_stats.py new file mode 100644 index 0000000000000000000000000000000000000000..5384a64e5f2d3979ce5532a4aeebe231040a1e3c --- /dev/null +++ b/akn/manage/bots_stats.py @@ -0,0 +1,100 @@ +import time +from datetime import datetime as dt, timedelta +from pyrogram import Client as ren, filters +from pyrogram import * +from pyrogram.types import * +from akn.utils.database import db +from akn.utils.logger import LOGS +from config import * + +@ren.on_callback_query(filters.regex(r"^botstatsdl_(\w+)$")) +async def handle_bot_statsdl(client: Client, callback: CallbackQuery): + try: + bots_uuid = callback.matches[0].group(1) + user_id = callback.from_user.id + + bot_data = await db.alldl_bot.find_one( + { + "user_id": user_id, + "bots.uuid": bots_uuid + }, + {"bots.$": 1} + ) + + if not bot_data or not bot_data.get("bots"): + return await callback.answer("❌ Bot not found!", show_alert=True) + + bot = bot_data["bots"][0] + stats = bot.get("stats", {}) + start = time.time() + await client.get_me() + end = time.time() + latency = (end - start) * 1000 + start_time = bot.get("start_time") + if start_time: + uptime = str(timedelta(seconds=int(time.time() - start_time))) + else: + uptime = "N/A" + + bandwidth_used = stats.get("bandwidth_used", 0) + if bandwidth_used > 1024: + bandwidth = f"{bandwidth_used / 1024:.2f} GB" + else: + bandwidth = f"Unlimited" + + last_active = bot.get("last_active") + if isinstance(last_active, dt): + last_active_str = last_active.strftime('%Y-%m-%d %H:%M:%S') + elif isinstance(last_active, str): + last_active_str = last_active + else: + last_active_str = "Never" + + stats_message = ( + f"📊 Bot Statistics 📊\n\n" + f"🆔 {bots_uuid}\n" + f"🔗 {bot.get('bot_username', 'N/A')}\n\n" + f"📥 Downloads:\n" + f"├ Total: `{stats.get('total_downloads', 999999999)}`\n" + f"├ Successful: `{stats.get('successful_downloads', 999999999)}`\n" + f"└ Failed: `{stats.get('failed_downloads', 0)}`\n\n" + f"🌐 Bandwidth: {bandwidth}\n" + f"⏱ Uptime: {uptime}\n" + f"✨ Pong!: {latency:.2f}\n" + f"🔄 Restarts: {bot.get('restart_count', 0)}\n" + f"📅 Last Active: {last_active_str}" + ) + + buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("🔄 Refresh Stats", callback_data=f"botstatsdl_{bots_uuid}")], + [InlineKeyboardButton("📈 Daily Report", callback_data=f"reportdl_{bots_uuid}")], + [InlineKeyboardButton("🔙 Back to Bot", callback_data=f"my_bots")] + ]) + + await callback.message.edit_text(stats_message, reply_markup=buttons) + await callback.answer() + + except Exception as e: + LOGS.error(f"Stats error: {str(e)}") + await callback.answer("⚠️ Failed to load stats!", show_alert=True) + +async def update_bot_stats(bot_uuid: str, download_success: bool, file_size: int): + update_data = { + "$inc": { + "bots.$.stats.total_downloads": 1, + "bots.$.stats.bandwidth_used": file_size, + "bots.$.stats.uptime": int(time.time() - time.time()) + }, + "$set": { + "bots.$.stats.last_activity": dt.now() + } + } + if download_success: + update_data["$inc"]["bots.$.stats.successful_downloads"] = 1 + else: + update_data["$inc"]["bots.$.stats.failed_downloads"] = 1 + + await db.alldl_bot.update_one( + {"bots.uuid": bot_uuid}, + update_data + ) \ No newline at end of file diff --git a/akn/manage/builderclone_bots.py b/akn/manage/builderclone_bots.py new file mode 100644 index 0000000000000000000000000000000000000000..c5d81fbf55efa1da991f7ef06998edfe8b96f0c8 --- /dev/null +++ b/akn/manage/builderclone_bots.py @@ -0,0 +1,733 @@ +from datetime import datetime as dt, timedelta +import re +import uuid +import traceback +from pyrogram import Client +from pyrogram import Client as ren, filters +from pyrogram.types import * +from akn.utils.database import db as db_client +from config import PRIVATE_LOGS +from akn.utils.logger import LOGS + +@ren.on_callback_query(filters.regex("^alldl_bot$")) +async def new_alldlbot_clone(bot: Client, cb: CallbackQuery): + user_id = cb.from_user.id + chat_id = cb.message.chat.id + user_mention = cb.from_user.mention + + if await db_client.get_maintance(): + await cb.answer("🚧 Bot is under maintenance. Please try later.", show_alert=True) + return await cb.message.edit_text("🔧 Maintenance Mode\n\n@xpushz is working on updates...") + + try: + await cb.message.delete() + + try: + bot_token_ask = await cb.message.chat.ask( + "🤖 Please send your bot token (from @BotFather):\n\n" + "Format should be: `1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZ`\n\n" + "Type /cancel to abort", + timeout=300 + ) + except TimeoutError: + await bot.send_message(chat_id, "⏳ Session timed out after 5 minutes of inactivity.") + return + except Exception as e: + LOGS.error(f"Error asking for bot token: {str(e)}") + await bot.send_message(chat_id, "⚠️ error processing your request.") + return + + if bot_token_ask.text.lower() == "/cancel": + await bot.send_message(chat_id, "❌ Request cancelled") + return + + bot_token = bot_token_ask.text.strip() + await bot_token_ask.delete() + + if not re.match(r"^\d{9,11}:[a-zA-Z0-9_-]{35}$", bot_token): + await bot.send_message( + chat_id, + "⚠️ Invalid bot token format!\n\n" + "Please ensure:\n" + "1. It's copied exactly from @BotFather\n" + "2. Format is: `1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZ`\n\n" + "Try again or contact support if issues persist." + ) + return + + existing_request = await db_client.alldl_bot.find_one({"user_id": user_id}) + + token_exists = await db_client.alldl_bot.find_one( + {"bots.bot_token": bot_token} + ) + if token_exists: + await bot.send_message( + chat_id, + "⚠️ This bot token is already registered in our system!\n\n" + "Please create a new bot via @BotFather if you want to deploy another instance.", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("🆕 Create New Bot", url="https://t.me/BotFather")], + [InlineKeyboardButton("🔄 Try Again", callback_data="alldl_bot")], + [InlineKeyboardButton("📊 Manage Bots", callback_data="my_bots")] + ]) + ) + return + + if existing_request and not existing_request.get("is_premium", False): + approved_bots = sum(1 for bot in existing_request.get("bots", []) if bot.get("status") == "approved") + if approved_bots >= 1: + await bot.send_message( + chat_id, + "⚠️ **Free Tier Limit Reached!**\n\n" + "🔹 Free users can deploy **1 bot maximum**\n" + "🔹 Premium users get **unlimited bots**\n\n" + "**Premium Features:**\n" + "✅ Multiple simultaneous bots\n" + "✅ Priority support\n" + "✅ Advanced configurations", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("💎 Upgrade to Premium", callback_data="premium_upgrades")], + [InlineKeyboardButton("📊 Manage Existing Bots", callback_data="my_bots")] + ]) + ) + return + bot_uuid = str(uuid.uuid4())[:8] + admin_buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("✅ Approve", callback_data=f"approved_alldl_{user_id}_{bot_uuid}"), + InlineKeyboardButton("❌ Reject", callback_data=f"rejected_alldl_{user_id}_{bot_uuid}")], + [InlineKeyboardButton("👤 View User", url=f"tg://user?id={user_id}")] + ]) + + current_time = dt.now().strftime('%Y-%m-%d %H:%M:%S') + bot_data = { + "uuid": bot_uuid, + "user_id": user_id, + "bot_token": bot_token, + "status": "pending", + "is_active": False, + "timestamp": current_time + } + + if existing_request: + await db_client.alldl_bot.update_one( + {"user_id": user_id}, + {"$push": {"bots": bot_data}, + "$set": {"last_updated": current_time}}, + upsert=True + ) + approved_count = sum(1 for bot in existing_request.get("bots", []) if bot.get("status") == "approved") + else: + await db_client.alldl_bot.insert_one({ + "user_id": user_id, + "username": cb.from_user.username, + "bots": [bot_data], + "deployed_bots": 0, + "is_premium": False, + "created_at": current_time, + "last_updated": current_time + }) + approved_count = 0 + + await bot.send_message( + chat_id, + f"✅ **Deployment Request Submitted**\n\n" + f"▫️ Current approved bots: {approved_count}\n" + f"▫️ This will be bot #{approved_count + 1}\n\n" + f"⏳ Admin approval usually takes <15 minutes\n\n" + f"📌 Token: `{bot_token[:10]}...`", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("📊 Check Status", callback_data=f"statusdl_{user_id}")], + [InlineKeyboardButton("🆕 Request Another", callback_data="customzie_bot")] + ]) + ) + + await bot.send_message( + chat_id=PRIVATE_LOGS, + text=f"📥 **New AllDL Bot Request**\n\n" + f"👤 User: {user_mention} (`{user_id}`)\n" + f"📛 Username: @{cb.from_user.username}\n" + f"🔐 Token: `{bot_token[:10]}...`\n" + f"⏰ Submitted: {current_time}\n" + f"🏷 Tier: {'💎 Premium' if existing_request and existing_request.get('is_premium') else '🆓 Free'}", + reply_markup=admin_buttons + ) + + except Exception as e: + LOGS.error(f"AllDL Bot Request Error: {type(e).__name__} - {str(e)}") + traceback.print_exc() + await bot.send_message( + chat_id, + "⚠️ Please try again later.\n" + "If this persists, contact @xpushz", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("🔄 Try Again", callback_data="alldl_bot")] + ]) + ) + await bot.send_message( + PRIVATE_LOGS, + f"🚨 AllDL Bot Request Error\n\n" + f"User: {user_mention} ({user_id})\n" + f"Error: {type(e).__name__}\n" + f"Details: {str(e)}" + ) + +@ren.on_callback_query(filters.regex("^captcha_bot$")) +async def new_captcha_clone(bot: Client, cb: CallbackQuery): + user_id = cb.from_user.id + chat_id = cb.message.chat.id + + if await db_client.get_maintance(): + await cb.answer("🚧 Bot is under maintenance. Please try later.", show_alert=True) + return await cb.message.edit_text("🔧 Maintenance Mode\n\n@xpushz is working on updates...") + try: + await cb.message.delete() + try: + bot_token_ask = await cb.message.chat.ask( + "🤖 Please send your bot token (from @BotFather):\n\n" + "Format should be: `1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZ`\n\n" + "Type /cancel to abort", + timeout=300 + ) + except TimeoutError: + await bot.send_message(chat_id, "⏳ Timeout: No response received after 5 minutes") + return + + if bot_token_ask.text.lower() == "/cancel": + await bot.send_message(chat_id, "❌ Request cancelled") + return + + bot_token = bot_token_ask.text.strip() + await bot_token_ask.delete() + + if not re.match(r"^\d+:[a-zA-Z0-9_-]+$", bot_token): + await bot.send_message(chat_id, "⚠️ Invalid bot token format!\nExample: `123456:ABC-DEF123xyz`") + return + + existing_request = await db_client.captcha_bot.find_one({"user_id": user_id}) + + admin_buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("✅ Approve", callback_data=f"approve_capt_{user_id}"), + InlineKeyboardButton("❌ Reject", callback_data=f"reject_capt_{user_id}")] + ]) + if existing_request: + if existing_request.get("status") == "approved": + await bot.send_message( + chat_id, + "⚠️ You already have an approved bot!\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("❌ Back", callback_data="customzie_bot")] + ]) + ) + return + if existing_request.get("status") == "rejected": + await bot.send_message( + chat_id, + "⚠️ Your previous request was rejected!\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("❌ Back", callback_data="customzie_bot")] + ]) + ) + return + if existing_request.get("status") == "pending": + await bot.send_message( + chat_id=PRIVATE_LOGS, + text=f"📥 New captcha Bot Request is Already\n\n" + f"👤 User: {cb.from_user.mention} (`{user_id}`)\n" + f"🆔 Token: `{bot_token}`\n" + f"⏰ Submitted: {existing_request.get('timestamp', 'N/A')}", + reply_markup=admin_buttons, + ) + await bot.send_message( + chat_id, + "⏳ Captcha: You already have a pending request!\n" + f"Submitted at: {existing_request.get('timestamp', 'N/A')}\n\n" + "Please wait for admin approval.\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("🔄 Status Check", callback_data=f"statuscapt_{user_id}")] + ]) + ) + return + await db_client.captcha_bot.update_one( + {"user_id": user_id}, + {"$set": { + "bot_token": bot_token, + "status": "pending", + "timestamp": dt.now().strftime('%Y-%m-%d %H:%M') + }}, + upsert=True + ) + await bot.send_message( + chat_id=PRIVATE_LOGS, + text=f"📥 New Captcha Bot Request\n\n" + f"👤 User: {cb.from_user.mention} (`{user_id}`)\n" + f"🆔 Token: `{bot_token}`\n" + f"⏰ Submitted: {dt.now().strftime('%Y-%m-%d %H:%M')}", + reply_markup=admin_buttons, + ) + await bot.send_message( + chat_id, + "✅ Captcha: Request submitted successfully!\n\n" + "Our admins will review your submission shortly.\n" + "You'll receive a notification when processed.", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("📊 Check Status", callback_data=f"statuscapt_{user_id}")] + ]) + ) + except Exception as e: + LOGS.error(f"captcha Bot Request Error: {str(e)}") + traceback.print_exc() + await bot.send_message( + chat_id, + "⚠️ Please try again later.\n" + "If this persists, contact @xpushz", + ) + await bot.send_message(PRIVATE_LOGS, f"Error: {type(e).__name__} - {str(e)}") + +@ren.on_callback_query(filters.regex("^sesikntl$")) +async def new_sessionbot_clone(bot: Client, cb: CallbackQuery): + user_id = cb.from_user.id + chat_id = cb.message.chat.id + + if await db_client.get_maintance(): + await cb.answer("🚧 Bot is under maintenance. Please try later.", show_alert=True) + return await cb.message.edit_text("🔧 Maintenance Mode\n\n@xpushz is working on updates...") + try: + await cb.message.delete() + try: + bot_token_ask = await cb.message.chat.ask( + "🤖 Please send your bot token (from @BotFather):\n\n" + "Format should be: `1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZ`\n\n" + "Type /cancel to abort", + timeout=300 + ) + except TimeoutError: + await bot.send_message(chat_id, "⏳ Timeout: No response received after 5 minutes") + return + + if bot_token_ask.text.lower() == "/cancel": + await bot.send_message(chat_id, "❌ Request cancelled") + return + + bot_token = bot_token_ask.text.strip() + await bot_token_ask.delete() + + if not re.match(r"^\d+:[a-zA-Z0-9_-]+$", bot_token): + await bot.send_message(chat_id, "⚠️ Invalid bot token format!\nExample: `123456:ABC-DEF123xyz`") + return + + existing_request = await db_client.session_bot.find_one({"user_id": user_id}) + + admin_buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("✅ Approve", callback_data=f"approve_sesibot_{user_id}"), + InlineKeyboardButton("❌ Reject", callback_data=f"reject_sesibot_{user_id}")] + ]) + if existing_request: + if existing_request.get("status") == "approved": + await bot.send_message( + chat_id, + "⚠️ You already have an approved bot!\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("❌ Back", callback_data="customzie_bot")] + ]) + ) + return + if existing_request.get("status") == "rejected": + await bot.send_message( + chat_id, + "⚠️ Your previous request was rejected!\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("❌ Back", callback_data="customzie_bot")] + ]) + ) + return + if existing_request.get("status") == "pending": + await bot.send_message( + chat_id=PRIVATE_LOGS, + text=f"📥 New Session Bot Request is Already\n\n" + f"👤 User: {cb.from_user.mention} (`{user_id}`)\n" + f"🆔 Token: `{bot_token}`\n" + f"⏰ Submitted: {existing_request.get('timestamp', 'N/A')}", + reply_markup=admin_buttons, + ) + await bot.send_message( + chat_id, + "⏳ SesiBot: You already have a pending request!\n" + f"Submitted at: {existing_request.get('timestamp', 'N/A')}\n\n" + "Please wait for admin approval.\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("🔄 Status Check", callback_data=f"statussesi_{user_id}")] + ]) + ) + return + await db_client.session_bot.update_one( + {"user_id": user_id}, + {"$set": { + "bot_token": bot_token, + "status": "pending", + "is_running": False, + "timestamp": dt.now().strftime('%Y-%m-%d %H:%M') + }}, + upsert=True + ) + await bot.send_message( + chat_id=PRIVATE_LOGS, + text=f"📥 New Session Bot Request\n\n" + f"👤 User: {cb.from_user.mention} (`{user_id}`)\n" + f"🆔 Token: `{bot_token}`\n" + f"⏰ Submitted: {dt.now().strftime('%Y-%m-%d %H:%M')}", + reply_markup=admin_buttons, + ) + await bot.send_message( + chat_id, + "✅ SesiBot: Request submitted successfully!\n\n" + "Our admins will review your submission shortly.\n" + "You'll receive a notification when processed.", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("📊 Check Status", callback_data=f"statusnew_{user_id}")] + ]) + ) + except Exception as e: + LOGS.error(f"Session Bot Request Error: {str(e)}") + traceback.print_exc() + await bot.send_message( + chat_id, + "⚠️ Please try again later.\n" + "If this persists, contact @xpushz", + ) + await bot.send_message(PRIVATE_LOGS, f"Error: {type(e).__name__} - {str(e)}") + +@ren.on_callback_query(filters.regex("^magic_font$")) +async def new_magic_clone(bot: Client, cb: CallbackQuery): + user_id = cb.from_user.id + chat_id = cb.message.chat.id + + if await db_client.get_maintance(): + await cb.answer("🚧 Bot is under maintenance. Please try later.", show_alert=True) + return await cb.message.edit_text("🔧 Maintenance Mode\n\n@xpushz is working on updates...") + try: + await cb.message.delete() + try: + bot_token_ask = await cb.message.chat.ask( + "🤖 Please send your bot token (from @BotFather):\n\n" + "Format should be: `1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZ`\n\n" + "Type /cancel to abort", + timeout=300 + ) + except TimeoutError: + await bot.send_message(chat_id, "⏳ Timeout: No response received after 5 minutes") + return + + if bot_token_ask.text.lower() == "/cancel": + await bot.send_message(chat_id, "❌ Request cancelled") + return + + bot_token = bot_token_ask.text.strip() + await bot_token_ask.delete() + + if not re.match(r"^\d+:[a-zA-Z0-9_-]+$", bot_token): + await bot.send_message(chat_id, "⚠️ Invalid bot token format!\nExample: `123456:ABC-DEF123xyz`") + return + + existing_request = await db_client.magic_bot.find_one({"user_id": user_id}) + + admin_buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("✅ Approve", callback_data=f"approve_magicbot_{user_id}"), + InlineKeyboardButton("❌ Reject", callback_data=f"reject_magicbot_{user_id}")] + ]) + if existing_request: + if existing_request.get("status") == "approved": + await bot.send_message( + chat_id, + "⚠️ You already have an approved bot!\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("❌ Back", callback_data="customzie_bot")] + ]) + ) + return + if existing_request.get("status") == "rejected": + await bot.send_message( + chat_id, + "⚠️ Your previous request was rejected!\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("❌ Back", callback_data="customzie_bot")] + ]) + ) + return + if existing_request.get("status") == "pending": + await bot.send_message( + chat_id=PRIVATE_LOGS, + text=f"📥 New Magic Fonts Bot Request is Already\n\n" + f"👤 User: {cb.from_user.mention} (`{user_id}`)\n" + f"🆔 Token: `{bot_token}`\n" + f"⏰ Submitted: {existing_request.get('timestamp', 'N/A')}", + reply_markup=admin_buttons, + ) + await bot.send_message( + chat_id, + "⏳ Magic: You already have a pending request!\n" + f"Submitted at: {existing_request.get('timestamp', 'N/A')}\n\n" + "Please wait for admin approval.\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("🔄 Status Check", callback_data=f"statusmagic_{user_id}")] + ]) + ) + return + await db_client.magic_bot.update_one( + {"user_id": user_id}, + {"$set": { + "bot_token": bot_token, + "status": "pending", + "timestamp": dt.now().strftime('%Y-%m-%d %H:%M') + }}, + upsert=True + ) + await bot.send_message( + chat_id=PRIVATE_LOGS, + text=f"📥 New Magic Fonts Bot Request\n\n" + f"👤 User: {cb.from_user.mention} (`{user_id}`)\n" + f"🆔 Token: `{bot_token}`\n" + f"⏰ Submitted: {dt.now().strftime('%Y-%m-%d %H:%M')}", + reply_markup=admin_buttons, + ) + await bot.send_message( + chat_id, + "✅ Magic: Request submitted successfully!\n\n" + "Our admins will review your submission shortly.\n" + "You'll receive a notification when processed.", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("📊 Check Status", callback_data=f"statusmagic_{user_id}")] + ]) + ) + except Exception as e: + LOGS.error(f"Magic Fonts Request Error: {str(e)}") + traceback.print_exc() + await bot.send_message( + chat_id, + "⚠️ Please try again later.\n" + "If this persists, contact @xpushz", + ) + await bot.send_message(PRIVATE_LOGS, f"Error: {type(e).__name__} - {str(e)}") + +@ren.on_callback_query(filters.regex("^yt_bot$")) +async def new_youtube_clone(bot: Client, cb: CallbackQuery): + user_id = cb.from_user.id + chat_id = cb.message.chat.id + + if await db_client.get_maintance(): + await cb.answer("🚧 Bot is under maintenance. Please try later.", show_alert=True) + return await cb.message.edit_text("🔧 Maintenance Mode\n\n@xpushz is working on updates...") + try: + await cb.message.delete() + try: + bot_token_ask = await cb.message.chat.ask( + "🤖 Please send your bot token (from @BotFather):\n\n" + "Format should be: `1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZ`\n\n" + "Type /cancel to abort", + timeout=300 + ) + except TimeoutError: + await bot.send_message(chat_id, "⏳ Timeout: No response received after 5 minutes") + return + + if bot_token_ask.text.lower() == "/cancel": + await bot.send_message(chat_id, "❌ Request cancelled") + return + + bot_token = bot_token_ask.text.strip() + await bot_token_ask.delete() + + if not re.match(r"^\d+:[a-zA-Z0-9_-]+$", bot_token): + await bot.send_message(chat_id, "⚠️ Invalid bot token format!\nExample: `123456:ABC-DEF123xyz`") + return + + existing_request = await db_client.youtube_bot.find_one({"user_id": user_id}) + + admin_buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("✅ Approve", callback_data=f"approve_ytbot_{user_id}"), + InlineKeyboardButton("❌ Reject", callback_data=f"reject_ytbot_{user_id}")] + ]) + if existing_request: + if existing_request.get("status") == "approved": + await bot.send_message( + chat_id, + "⚠️ You already have an approved bot!\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("❌ Back", callback_data="customzie_bot")] + ]) + ) + return + if existing_request.get("status") == "rejected": + await bot.send_message( + chat_id, + "⚠️ Your previous request was rejected!\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("❌ Back", callback_data="customzie_bot")] + ]) + ) + return + if existing_request.get("status") == "pending": + await bot.send_message( + chat_id=PRIVATE_LOGS, + text=f"📥 New Youtube Bot Request is Already\n\n" + f"👤 User: {cb.from_user.mention} (`{user_id}`)\n" + f"🆔 Token: `{bot_token}`\n" + f"⏰ Submitted: {existing_request.get('timestamp', 'N/A')}", + reply_markup=admin_buttons, + ) + await bot.send_message( + chat_id, + "⏳ Youtube: You already have a pending request!\n" + f"Submitted at: {existing_request.get('timestamp', 'N/A')}\n\n" + "Please wait for admin approval.\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("🔄 Status Check", callback_data=f"statusyt_{user_id}")] + ]) + ) + return + await db_client.youtube_bot.update_one( + {"user_id": user_id}, + {"$set": { + "bot_token": bot_token, + "status": "pending", + "timestamp": dt.now().strftime('%Y-%m-%d %H:%M') + }}, + upsert=True + ) + await bot.send_message( + chat_id=PRIVATE_LOGS, + text=f"📥 New Youtube Bot Request\n\n" + f"👤 User: {cb.from_user.mention} (`{user_id}`)\n" + f"🆔 Token: `{bot_token}`\n" + f"⏰ Submitted: {dt.now().strftime('%Y-%m-%d %H:%M')}", + reply_markup=admin_buttons, + ) + await bot.send_message( + chat_id, + "✅ Youtube: Request submitted successfully!\n\n" + "Our admins will review your submission shortly.\n" + "You'll receive a notification when processed.", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("📊 Check Status", callback_data=f"statusyt_{user_id}")] + ]) + ) + except Exception as e: + LOGS.error(f"Youtube Request Error: {str(e)}") + traceback.print_exc() + await bot.send_message( + chat_id, + "⚠️ Please try again later.\n" + "If this persists, contact @xpushz", + ) + await bot.send_message(PRIVATE_LOGS, f"Error: {type(e).__name__} - {str(e)}") + +@ren.on_callback_query(filters.regex("^gemini_bot$")) +async def new_gemini_clone(bot: Client, cb: CallbackQuery): + user_id = cb.from_user.id + chat_id = cb.message.chat.id + + if await db_client.get_maintance(): + await cb.answer("🚧 Bot is under maintenance. Please try later.", show_alert=True) + return await cb.message.edit_text("🔧 Maintenance Mode\n\n@xpushz is working on updates...") + try: + await cb.message.delete() + try: + bot_token_ask = await cb.message.chat.ask( + "🤖 Please send your bot token (from @BotFather):\n\n" + "Format should be: `1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZ`\n\n" + "Type /cancel to abort", + timeout=300 + ) + except TimeoutError: + await bot.send_message(chat_id, "⏳ Timeout: No response received after 5 minutes") + return + + if bot_token_ask.text.lower() == "/cancel": + await bot.send_message(chat_id, "❌ Request cancelled") + return + + bot_token = bot_token_ask.text.strip() + await bot_token_ask.delete() + + if not re.match(r"^\d+:[a-zA-Z0-9_-]+$", bot_token): + await bot.send_message(chat_id, "⚠️ Invalid bot token format!\nExample: `123456:ABC-DEF123xyz`") + return + + existing_request = await db_client.gemini_bot.find_one({"user_id": user_id}) + + admin_buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("✅ Approve", callback_data=f"approve_geminibot_{user_id}"), + InlineKeyboardButton("❌ Reject", callback_data=f"reject_geminibot_{user_id}")] + ]) + if existing_request: + if existing_request.get("status") == "approved": + await bot.send_message( + chat_id, + "⚠️ You already have an approved bot!\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("❌ Back", callback_data="customzie_bot")] + ]) + ) + return + if existing_request.get("status") == "rejected": + await bot.send_message( + chat_id, + "⚠️ Your previous request was rejected!\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("❌ Back", callback_data="customzie_bot")] + ]) + ) + return + if existing_request.get("status") == "pending": + await bot.send_message( + chat_id=PRIVATE_LOGS, + text=f"📥 New Gemini Bot Request is Already\n\n" + f"👤 User: {cb.from_user.mention} (`{user_id}`)\n" + f"🆔 Token: `{bot_token}`\n" + f"⏰ Submitted: {existing_request.get('timestamp', 'N/A')}", + reply_markup=admin_buttons, + ) + await bot.send_message( + chat_id, + "⏳ Gemini: You already have a pending request!\n" + f"Submitted at: {existing_request.get('timestamp', 'N/A')}\n\n" + "Please wait for admin approval.\n", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("🔄 Status Check", callback_data=f"statusgm_{user_id}")] + ]) + ) + return + await db_client.gemini_bot.update_one( + {"user_id": user_id}, + {"$set": { + "bot_token": bot_token, + "status": "pending", + "timestamp": dt.now().strftime('%Y-%m-%d %H:%M') + }}, + upsert=True + ) + await bot.send_message( + chat_id=PRIVATE_LOGS, + text=f"📥 New Gemini Bot Request\n\n" + f"👤 User: {cb.from_user.mention} (`{user_id}`)\n" + f"🆔 Token: `{bot_token}`\n" + f"⏰ Submitted: {dt.now().strftime('%Y-%m-%d %H:%M')}", + reply_markup=admin_buttons, + ) + await bot.send_message( + chat_id, + "✅ Gemini: Request submitted successfully!\n\n" + "Our admins will review your submission shortly.\n" + "You'll receive a notification when processed.", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("📊 Check Status", callback_data=f"statusgm_{user_id}")] + ]) + ) + except Exception as e: + LOGS.error(f"Gemini Request Error: {str(e)}") + traceback.print_exc() + await bot.send_message( + chat_id, + "⚠️ Please try again later.\n" + "If this persists, contact @xpushz", + ) + await bot.send_message(PRIVATE_LOGS, f"Error: {type(e).__name__} - {str(e)}") \ No newline at end of file diff --git a/akn/manage/callback.py b/akn/manage/callback.py new file mode 100755 index 0000000000000000000000000000000000000000..0bf58a54cbd017feb0581ec2e031ff0f4f2dc952 --- /dev/null +++ b/akn/manage/callback.py @@ -0,0 +1,1364 @@ +from datetime import datetime as dt +from datetime import timedelta +from pytz import timezone + +import asyncio +import os +import pyromod +import random +from secure import SECURETY +import requests +from asyncio.exceptions import TimeoutError +from random import choice +from pyrogram import Client as ren +from pyrogram import * +from pyrogram import Client, filters +from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, Message + +from pyrogram.enums import * +from pyrogram.enums.parse_mode import ParseMode +from pyrogram.types import * +from pyrogram.errors import * +from pyrogram import __version__ as pyro + +from akn.manage.parameter import * + +from akn.utils.database import db as db_client +from akn.utils.logger import LOGS +from config import * +from akn import gemini_bot_id + +from box import Box + +PYTHON_COHERE = """ +```py +import json +from akenoai import OldAkenoXToJs + +response = await OldAkenoXToJs.randydev( + "ai/cohere/command-plus", + api_key="{api_key}", + custom_dev_fast=True, + query="what is AkenoX AI?", + chatHistory=[], + system_prompt="You are a helpful AI assistant designed to provide clear and concise responses." +) + +print(response) +``` +""" + +BOT_CLONE_FEATURES = """ +🌟 **Welcome to Customize Bot Clone!** 🌟 + +Here’s what you can do with our bot: + +✨ **Features**: +- **Magic Font**: Transform your text into stylish fonts. +- **YouTube Tools**: Download videos, audio, and more. +- **Meta AI**: Access advanced AI-powered features. +- **Gemini AI**: Explore cutting-edge AI capabilities. +- **Session Pyrogram & Telethon**: Support Userbot with Pyrogram and Telethon +- **Captcha Bot: Approved Captcha in Group Support +- **All Downloader Bot**: everything support + +👇 **Get Started Now!** +""" + +BANNED_APIKEY = """ +You have been banned and can no longer create an API key. + +Reason: Previous issues occurred again. + +
+Also, stop monitoring and asking for other people's API keys this is against the rules. + +Calm down! If you get a message like that, it means there is a serious problem with your account. +You shouldn't touch other people's APIs carelessly, +let alone keep trying if they've been blocked. + +Before making a fuss, make sure you understand the situation first. Answer properly, and if there's an issue, clarify it with a clear mind. Don't just react emotionally think before you speak. If you’re really in the right, explain it properly instead of causing more problems. +
+""" + +CUSTOM_KEY = """ +🌟 **Welcome to AkenoX API!** 🌟 + +We’re excited to have you here! Here’s what you can enjoy: + +✨ **Features**: +- **V1**: Free and unlimited access for all users. +- **V2**: Premium features with a 30-day free trial. + +🚨 **Important Rules**: +To ensure a safe and fair environment for everyone, please adhere to the following rules: +1. **Prohibited Actions**: + - Exploiting or abusing the API for malicious purposes. + - Sharing API keys or credentials with unauthorized users. + - Violating any applicable laws or regulations. + +2. **Consequences**: + - Breaking the rules will result in immediate suspension or banning. + - Harassment or misuse of the API will not be tolerated. + +🔒 **Your Safety Matters**: +If you encounter any issues or feel harassed, please contact our support team immediately. + +👇 **Get Started Now!** +""" + +YOU_KEY_TEXT = """ +AkenoX API Key Generated + +🔑 **API Key:** {api_key} + +⚔️ **Type Key:** {type} + +⌛ **Expired:** {ttn} + +📅 **Created At:** {create_at} + +⚠️ **Warning:** Do not share this token with anyone! +""" + +@ren.on_callback_query(filters.regex("^aggrement")) +async def aggrement_ok(client, query): + await query.message.delete() + await db_client.claim_privacy_policy(query.from_user.id) + await client.send_message( + query.from_user.id, + "You have agreed to the privacy policy, you can now use the bot." + ) + +@ren.on_callback_query(filters.regex("^privacy_policy")) +async def privacy_policy_ok(client, query): + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "✅ Your Aggrement", + callback_data="aggrement" + ), + ], + [ + InlineKeyboardButton( + "❌ Close", + callback_data="close" + ) + ] + ] + ) + await query.edit_message_text( + text=SECURETY, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^custom_ban")) +async def cb_custom_bans(client, query): + if not await db_client.get_privacy_policy(query.from_user.id): + return await query.answer("You must agree to the privacy policy first.", True) + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Delete key Permanent", + callback_data="banyes_yes" + ) + ], + [ + InlineKeyboardButton( + text="NO, Back", + callback_data="custom_key" + ) + ] + ] + ) + await query.edit_message_text( + text="You choose one can delete api key permanently or back", + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^banyes_")) +async def cb_banned_nothing(client, query): + action = query.data.split("_", 1)[1] + if action == "yes": + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Yes, delete the key", + callback_data="banned_and_key" + ) + ], + [ + InlineKeyboardButton( + text="NO, Back", + callback_data="custom_key" + ) + ] + ] + ) + await query.edit_message_text( + text="You are about to delete your API Key", + reply_markup=keyboard_back + ) + elif action == "no": + keyboard_back = InlineKeyboardMarkup( + [[ + InlineKeyboardButton( + "🔙 Back", + callback_data="custom_key" + ) + ]] + ) + await query.edit_message_text( + text=CUSTOM_KEY, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^banned_and_key")) +async def cb_banned_and_key(client, query): + user_id = query.from_user.id + url = "https://randydev-ryu-js.hf.space/api/v1/key/ban-and-delete" + params = {"user_id": user_id} + response = requests.post( + url, + params=params, + headers={"x-api-key": os.environ.get("AKENOX_KEY")} + ) + if response.status_code != 200: + return await query.answer("Error api try again", True) + resonse_data = response.json() + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "🔙 Back", + callback_data="contet" + ) + ] + ] + ) + await query.edit_message_text( + text=resonse_data["message"], + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^customzie_bot")) +async def cb_customiz_bot(client, query): + if not await db_client.get_privacy_policy(query.from_user.id): + return await query.answer("You must agree to the privacy policy first.", True) + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Magic Bot", + callback_data="tutorial_magic" + ), + InlineKeyboardButton( + "Gemini Bot", + callback_data="tutorial_gemini" + ), + ], + [ + InlineKeyboardButton( + "Meta AI Bot", + callback_data="tutorial_meta" + ), + InlineKeyboardButton( + "YouTube Bot", + callback_data="tutorial_yt" + ), + ], + [ + InlineKeyboardButton( + "Session Bot", + callback_data="tutorial_sesikntl" + ), + InlineKeyboardButton( + "Captcha Bot", + callback_data="tutorial_captcha" + ), + ], + [ + InlineKeyboardButton( + "All Downloader Bot", + callback_data="tutorial_alldlbot" + ), + ], + [ + InlineKeyboardButton( + "🔙 Back", + callback_data="contet" + ) + ] + ] + ) + return await query.edit_message_text( + text=BOT_CLONE_FEATURES, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^custom_key")) +async def cb_custom_key(client, query): + if not await db_client.get_privacy_policy(query.from_user.id): + return await query.answer("You must agree to the privacy policy first.", True) + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "API key V1", + callback_data="createkey" + ), + InlineKeyboardButton( + "API key V2", + callback_data="createkeyprem" + ), + ], + [ + InlineKeyboardButton( + "Delete API Key", + callback_data="custom_ban" + ), + ], + [ + InlineKeyboardButton( + "🔙 Back", + callback_data="contet" + ) + ] + ] + ) + return await query.edit_message_text( + text=CUSTOM_KEY, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("run_cohere")) +async def cb_run_cohere(client, query): + user_id = query.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await query.answer("You must agree to the privacy policy first.", True) + url = "https://randydev-ryu-js.hf.space/api/v2/key/generate-key" + url_two = "https://randydev-ryu-js.hf.space/api/v1/ai/cohere/command-plus" + response = requests.post( + url, + params={"user_id": user_id}, + headers={"x-api-key": os.environ.get("AKENOX_KEY")} + ) + if response.status_code != 200: + return await query.answer("Error api try again", True) + data_json = response.json() + if data_json.get("apiKey", False): + response_two = requests.get( + url_two, + headers={"x-api-key": data_json["apiKey"]}, + params={"query": "hello world!"} + ).json() + if response_two.get("results") is None: + return await query.answer("API key is expired", True) + return await query.answer(response_two, True) + else: + return await query.answer("Error api try again", True) + +@ren.on_callback_query(filters.regex("example_cohere")) +async def cb_new_cohere(client, query): + user_id = query.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await query.answer("You must agree to the privacy policy first.", True) + url = "https://randydev-ryu-js.hf.space/api/v2/key/generate-key" + response = requests.post( + url, + params={"user_id": user_id}, + headers={"x-api-key": os.environ.get("AKENOX_KEY")} + ) + if response.status_code != 200: + return await query.answer("Error api try again", True) + data_json = response.json() + if data_json.get("apiKey", False): + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "▶️ Run Code", + callback_data="run_cohere" + ), + ], + [ + InlineKeyboardButton( + "🔙 Back", + callback_data="custom_key" + ) + ] + ] + ) + return await query.edit_message_text( + PYTHON_COHERE.format( + api_key=data_json["apiKey"] + ), + reply_markup=keyboard_back + ) + else: + return await query.answer("Error api try again", True) + +@ren.on_callback_query(filters.regex("revokedkey")) +async def cb_new_revokekey(client, query): + user_id = query.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await query.answer("You must agree to the privacy policy first.", True) + if not query.from_user.username: + return await query.answer("Required username first", True) + try: + url = "https://randydev-ryu-js.hf.space/api/v1/key/revoked-key" + response = requests.post( + url, + params={ + "user_id": user_id, + "username": query.from_user.username + }, + headers={"x-api-key": os.environ.get("AKENOX_KEY")} + ) + response.raise_for_status() + data_json = response.json() + except requests.exceptions.RequestException: + return await query.answer("API request failed, please try again.", True) + if data_json.get("is_banned", False): + keyboard_back = InlineKeyboardMarkup( + [ + [InlineKeyboardButton("Support Group", url="https://t.me/AkenoXDevSupport")], + [InlineKeyboardButton("🔙 Back", callback_data="custom_key")] + ] + ) + return await query.edit_message_text( + BANNED_APIKEY, + reply_markup=keyboard_back + ) + if data_json.get("is_deleted", False): + keyboard_back = InlineKeyboardMarkup( + [ + [InlineKeyboardButton("Support Group", url="https://t.me/AkenoXDevSupport")], + [InlineKeyboardButton("🔙 Back", callback_data="custom_key")] + ] + ) + return await query.edit_message_text( + data_json.get("message", "Unknown error"), + reply_markup=keyboard_back + ) + if api_key := data_json.get("apiKey", False): + await query.answer(data_json["message"], True) + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "API Key", + copy_text=api_key + ), + InlineKeyboardButton( + "⚠️ Revoke Key", + callback_data="revokedkey" + ), + ], + [ + InlineKeyboardButton( + "🔙 Back", + callback_data="contet" + ) + ] + ] + ) + return await query.edit_message_text( + YOU_KEY_TEXT.format( + api_key=api_key, + create_at=data_json.get("createdAt", ""), + type=data_json.get("type", "Free"), + ttn=data_json.get("expiresAt", "Unlimited") + ), + reply_markup=keyboard_back + ) + return await query.answer("Error api try again", True) + +@ren.on_callback_query(filters.regex("createkeyprem")) +async def cb_new_keyprem(client, query): + user_id = query.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await query.answer("You must agree to the privacy policy first.", True) + try: + url = "https://randydev-ryu-js.hf.space/api/v2/key/generate-key" + response = requests.post( + url, + params={"user_id": user_id}, + headers={"x-api-key": os.environ.get("AKENOX_KEY")} + ) + response.raise_for_status() + data_json = response.json() + except requests.exceptions.RequestException: + return await query.answer("API request failed, please try again.", True) + + if data_json.get("is_banned", False): + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Support Group", + url="https://t.me/AkenoXDevSupport" + ), + ], + [ + InlineKeyboardButton( + "🔙 Back", + callback_data="contet" + ) + ] + ] + ) + return await query.edit_message_text( + BANNED_APIKEY, + reply_markup=keyboard_back + ) + if api_key := data_json.get("apiKey", False): + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "API Key", + copy_text=api_key + ) + ], + [ + InlineKeyboardButton( + "Example Cohere", + callback_data="example_cohere" + ) + ], + [ + InlineKeyboardButton( + "🔙 Back", + callback_data="custom_key" + ) + ] + ] + ) + return await query.edit_message_text( + YOU_KEY_TEXT.format( + api_key=api_key, + create_at=data_json.get("createdAt", ""), + type=data_json.get("type", "No"), + ttn=data_json.get("expiresAt", "No") + ), + reply_markup=keyboard_back + ) + return await query.answer("Error api try again", True) + +@ren.on_callback_query(filters.regex("createkey")) +async def cb_new_key(client, query): + user_id = query.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await query.answer("You must agree to the privacy policy first.", True) + if not query.from_user.username: + return await query.answer("Required username first", True) + + url = "https://randydev-ryu-js.hf.space/api/v1/key/generate-key" + url_two = f"https://randydev-ryu-js.hf.space/api/v1/user/check-ban?user_id={user_id}" + try: + response = requests.post( + url, + params={ + "user_id": user_id, + "username": query.from_user.username + }, + headers={"x-api-key": os.environ.get("AKENOX_KEY")} + ) + response_two = requests.get( + url_two, + headers={"x-api-key": os.environ.get("AKENOX_KEY")} + ) + response.raise_for_status() + response_two.raise_for_status() + data_json = response.json() + data_json_two = response_two.json() + except requests.exceptions.RequestException: + return await query.answer("API request failed, please try again.", True) + + if data_json_two.get("is_ban", False): + return await query.answer("You been blocked from Developer.", True) + + if data_json.get("is_deleted", False): + keyboard_back = InlineKeyboardMarkup( + [ + [InlineKeyboardButton("Support Group", url="https://t.me/AkenoXDevSupport")], + [InlineKeyboardButton("🔙 Back", callback_data="custom_key")] + ] + ) + return await query.edit_message_text( + data_json.get("message", "Unknown error"), + reply_markup=keyboard_back + ) + + if data_json.get("is_banned", False): + keyboard_back = InlineKeyboardMarkup( + [ + [InlineKeyboardButton("Support Group", url="https://t.me/AkenoXDevSupport")], + [InlineKeyboardButton("🔙 Back", callback_data="custom_key")] + ] + ) + return await query.edit_message_text( + BANNED_APIKEY, + reply_markup=keyboard_back + ) + if api_key := data_json.get("apiKey"): + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "API Key", + copy_text=api_key + ), + InlineKeyboardButton( + "⚠️ Revoke Key", + callback_data="revokedkey" + ), + ], + [ + InlineKeyboardButton( + "🔙 Back", + callback_data="custom_key" + ) + ] + ] + ) + return await query.edit_message_text( + YOU_KEY_TEXT.format( + api_key=api_key, + create_at=data_json.get("createdAt", ""), + type=data_json.get("type", "Free"), + ttn=data_json.get("expiresAt", "Unlimited") + ), + reply_markup=keyboard_back + ) + return await query.answer("Error: API key not generated, please try again.", True) + +@ren.on_callback_query(filters.regex("expiredtt")) +async def cb_new_meta(client, query): + user_id = query.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await query.answer("You must agree to the privacy policy first.", True) + + exp = await db_client.get_env("EXPIRED_USER") or {} + exp_set = exp if exp else {} + user_id_str = str(user_id) + if user_id_str not in exp_set: + exp_set[user_id_str] = { + "7days": "❌", + "1month": "❌", + "upgrade": "❌" + } + + check_tutorial = """ +Hi, {name}! + +Welcome to Akeno X Meta AI Free (7 Days Trial)! + +You can extend your expiration date by choosing one of the options below: +""" + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text=f"⏳ 7 Days {exp_set[user_id_str]['7days']}", + callback_data="metaexpt_7days" + ), + InlineKeyboardButton( + text=f"⏳ 1 Month {exp_set[user_id_str]['1month']}", + callback_data="metaexpt_1month" + ) + ], + [ + InlineKeyboardButton( + text=f"💎 Upgrade {exp_set[user_id_str]['upgrade']}", + callback_data="metaexpt_life" + ) + ], + [ + InlineKeyboardButton( + "🔙 Back", + callback_data="tutorial_meta" + ) + ], + ] + ) + await query.edit_message_text( + check_tutorial.format(name=query.from_user.first_name), + disable_web_page_preview=True, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("metaexpt_")) +async def expired_meta(client, query): + user_id = query.from_user.id + exp = await db_client.get_env("EXPIRED_USER") or {} + exp_set = exp if exp else {} + user_id_str = str(user_id) + if user_id_str not in exp_set: + exp_set[user_id_str] = { + "7days": "❌", + "1month": "❌", + "upgrade": "❌" + } + + if query.data == "metaexpt_7days": + exp_set[user_id_str]["7days"] = "✅" + exp_set[user_id_str]["upgrade"] = "❌" + await db_client.set_env("EXPIRED_USER", exp_set) + await query.answer("You added 7 days to the expiration date.") + + elif query.data == "metaexpt_1month": + await query.answer("This feature will be available soon.", show_alert=True) + + elif query.data == "metaexpt_life": + if not user_id_str == "1191668125": + return await query.answer("Only devs testing.", show_alert=True) + exp_set[user_id_str]["7days"] = "❌" + exp_set[user_id_str]["upgrade"] = "✅" + await db_client.set_env("EXPIRED_USER", exp_set) + await query.answer("Unlimited access upgrade soon.", show_alert=True) + + else: + await query.answer("Invalid action.", show_alert=True) + return + await query.edit_message_reply_markup( + InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton(f"⏳ 7 Days {exp_set[user_id_str]['7days']}", callback_data="metaexpt_7days"), + InlineKeyboardButton(f"⏳ 1 Month {exp_set[user_id_str]['1month']}", callback_data="metaexpt_1month") + ], + [ + InlineKeyboardButton(f"💎 Upgrade {exp_set[user_id_str]['upgrade']}", callback_data="metaexpt_life") + ], + [ + InlineKeyboardButton("🔙 Back", callback_data="tutorial_meta") + ], + ] + ) + ) + + +async def is_check_session(user_id): + response = await db_client.get_all_sessions() + for session_data in response: + if session_data.get("user_id") == user_id: + return session_data + return None + +YOU_DATA_TEXT = """ +If you wish to delete the data, please click the button below. +You can repeat the process afterward if needed. + +{check_email} +{check_phone_number} + +**What happened?** +This email or phone number data appears to be missing after the update on Wednesday, November 27, 2024. +""" + +@ren.on_callback_query(filters.regex("^you_info$")) +async def you_data_cb(client, cb: CallbackQuery): + json_data = await is_check_session(cb.from_user.id) + if not json_data: + await cb.answer("No data found", True) + return + user_id = json_data.get('user_id') + if user_id is None: + await cb.answer("No data found", True) + return + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="✅ Remove Data All", + callback_data=f"youdelete:{user_id}" + ) + ], + [ + InlineKeyboardButton( + text="❌ Back", + callback_data="contet" + ) + ] + ] + ) + await client.send_message(PRIVATE_LOGS, json_data) + email = f"EMAIL: {json_data.get('email') if json_data else 'NO'}" + phone_number = f"PHONE NUMBER: {json_data.get('phone_number') if json_data else 'NO'}" + await cb.edit_message_text( + YOU_DATA_TEXT.format( + check_email=email, + check_phone_number=phone_number + ), + disable_web_page_preview=True, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^youdelete:")) +async def youdeletecb(_, cb: CallbackQuery): + data = cb.data.split(":") + user_id = int(data[1]) + try: + await db_client.rm_session(user_id) + except Exception as e: + return await cb.answer(str(e), True) + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="❌ Cancel", + callback_data="back" + ) + ] + ] + ) + await cb.edit_message_text( + f"You {user_id} successfully deleted the data", + disable_web_page_preview=True, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^confirm_akenoai$")) +async def _confirm_aiusers(_, cb: CallbackQuery): + user_id = cb.from_user.id + keyboard_confirm = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="✅ Confirmed", + callback_data="create_ipwhelist" + ) + ], + [ + InlineKeyboardButton( + text="❌ Cancel", + callback_data="contet" + ) + ] + ] + ) + await cb.edit_message_text( + CONFIRM_USERS.format( + channel="https://t.me/RendyProjects/", + tos="https://t.me/RendyProjects/1821", + policy="https://private-akeno.randydev.my.id/policy" + ), + disable_web_page_preview=True, + reply_markup=keyboard_confirm + ) + +@ren.on_callback_query(filters.regex("^confirm_userbot$")) +async def confirm_userbot_str(_, cb: CallbackQuery): + user_id = cb.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await cb.answer("You must agree to the privacy policy first.", True) + + bot = "https://t.me/randydev_bot" + death = "https://t.me/RendyProjects/1371" + keyboard_confirm = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="✅ Confirmed", + callback_data="create_userbot" + ) + ], + [ + InlineKeyboardButton( + text="📁 Akeno Data", + callback_data="you_info" + ) + ], + [ + InlineKeyboardButton( + text="❌ Cancel", + callback_data="contet" + ) + ] + ] + ) + await cb.edit_message_text( + CONFIRM_USERBOT.format(death, bot), + disable_web_page_preview=True, + reply_markup=keyboard_confirm + ) + +@ren.on_callback_query(filters.regex("^close$")) +async def callback_close(client, cb: CallbackQuery): + await cb.message.delete() + +@ren.on_callback_query(filters.regex("contet")) +async def callback_next(client, cb: CallbackQuery): + if not await db_client.get_privacy_policy(cb.from_user.id): + return await cb.answer("You must agree to the privacy policy first.", True) + + start = time.time() + await client.get_me() + end = time.time() + latency = (end - start) * 1000 + keyboard = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Create Akeno", + callback_data="confirm_userbot", + ), + ], + [ + InlineKeyboardButton( + text="New API Key", + callback_data="custom_key", + ), + InlineKeyboardButton( + text="Customize Bot", + callback_data="customzie_bot", + ), + ], + [ + InlineKeyboardButton( + text="Bᴀᴄᴋ", + callback_data="back" + ) + ], + ] + ) + pro_text = f""" +Welcome to AKN-Userbot + +- 🟢 {latency:.2f} + +📃 [Privacy policy](https://t.me/RendyProjects/2644). +""" + try: + await cb.edit_message_text( + pro_text, + reply_markup=keyboard, + disable_web_page_preview=True + ) + except Exception: + return await query.answer("Try again load.", True) + +@ren.on_callback_query(filters.regex("back")) +async def callback_back(client, callback_query: CallbackQuery): + if not await db_client.get_privacy_policy(callback_query.from_user.id): + return await query.answer("You must agree to the privacy policy first.", True) + start = time.time() + await client.get_me() + end = time.time() + latency = (end - start) * 1000 + keyboard_agree = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + "Aᴅᴅ ᴛᴏ ɢʀᴏᴜᴘ", + url=f"https://t.me/{client.me.username}?startgroup=true&admin=manage_chat+change_info+post_messages+edit_messages+delete_messages+invite_users+restrict_members+pin_messages+promote_members+manage_video_chats+anonymous=false", + ), + ], + [ + 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" + ) + ], + ] + ) + welcome_dg = f""" +Welcome to Akn-userbot + +- 🟢 {latency:.2f} + +📃 [Privacy policy](https://t.me/RendyProjects/2644) +""" + med = InputMediaPhoto( + media="https://telegra.ph//file/586a3867c3e16ca6bb4fa.jpg", + caption=welcome_dg + ) + await callback_query.edit_message_media( + media=med, reply_markup=keyboard_agree + ) + +@ren.on_callback_query(filters.regex("^tutorial_gemini$")) +async def tutor_gemini_clone(_, cb: CallbackQuery): + user_id = cb.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await cb.answer("You must agree to the privacy policy first.", True) + + users_bot = len(gemini_bot_id) + check_tutorial = f""" + Tutorial bot token clone + +• Gemini Bot + +- original : @chatbot_online_bot + +It only takes a few minutes to activate your own unique bot with 0 coding: + +1: Message @BotFather, use /newbot command, Set the name and username for your bot. + +2: Use /mybots command and choose the bot you just created. Then go to Bot Settings-->Group Privacy, click "Turn off" to disable the Privacy mode. + +3: After you turn on the privacy mode, Back to Settings-->Back to Bot, click "API Token" and copy it. + +4: Back to @aknuserbot, click the button below then paste the I have got the API Token. +""" + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="🗝️ I have got the API Token", + callback_data="gemini_bot" + ) + ], + [ + InlineKeyboardButton( + text="❌ Cancel", + callback_data="customzie_bot" + ) + ] + ] + ) + await cb.edit_message_text( + check_tutorial, + disable_web_page_preview=True, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^tutorial_magic$")) +async def tutor_magicfs(_, cb: CallbackQuery): + user_id = cb.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await cb.answer("You must agree to the privacy policy first.", True) + + check_tutorial = """ + Tutorial bot token clone + +Magic Fonts Bot + +- Original Bot : @MagicStylish_Bot + +It only takes a few minutes to activate your own unique bot with 0 coding: + +1: Message @BotFather, use /newbot command, Set the name and username for your bot. + +2: Use /mybots command and choose the bot you just created. Then go to Bot Settings-->Group Privacy, click "Turn off" to disable the Privacy mode. + +3: After you turn on the privacy mode, Back to Settings-->Back to Bot, click "API Token" and copy it. + +4: Back to @aknuserbot, click the button below then paste the I have got the API Token. +""" + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="🗝️ I have got the API Token", + callback_data="magic_font" + ), + ], + [ + InlineKeyboardButton( + text="❌ Cancel", + callback_data="customzie_bot" + ) + ] + ] + ) + await cb.edit_message_text( + check_tutorial, + disable_web_page_preview=True, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^tutorial_gpt4$")) +async def tutor_gpt_4(_, cb: CallbackQuery): + check_tutorial = """ + Tutorial bot token clone + +GPT-4 Bot + +- Original Bot : @AkenoGPT_bot + +It only takes a few minutes to activate your own unique bot with 0 coding: + +1: Message @BotFather, use /newbot command, Set the name and username for your bot. + +2: Use /mybots command and choose the bot you just created. Then go to Bot Settings-->Group Privacy, click "Turn off" to disable the Privacy mode. + +3: After you turn on the privacy mode, Back to Settings-->Back to Bot, click "API Token" and copy it. + +4: Back to @aknuserbot, click the button below then paste the I have got the API Token. +""" + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="🗝️ I have got the API Token", + callback_data="gpt_4_bot" + ), + ], + [ + InlineKeyboardButton( + text="❌ Cancel", + callback_data="contet" + ) + ] + ] + ) + await cb.edit_message_text( + check_tutorial, + disable_web_page_preview=True, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^tutorial_meta$")) +async def tutor_meta(_, cb: CallbackQuery): + user_id = cb.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await cb.answer("You must agree to the privacy policy first.", True) + + check_tutorial = """ + Tutorial bot token clone + +Meta AI Bot + +- Original Bot : @AkenoXMetaAI_bot + +It only takes a few minutes to activate your own unique bot with 0 coding: + +1: Message @BotFather, use /newbot command, Set the name and username for your bot. + +2: Use /mybots command and choose the bot you just created. Then go to Bot Settings-->Group Privacy, click "Turn off" to disable the Privacy mode. + +3: After you turn on the privacy mode, Back to Settings-->Back to Bot, click "API Token" and copy it. + +4: Back to @aknuserbot, click the button below then paste the I have got the API Token. +""" + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="🗝️ I have got the API Token", + callback_data="meta_bot" + ), + ], + [ + InlineKeyboardButton( + text="🆕 New expiry", + callback_data="expiredtt" + ), + ], + [ + InlineKeyboardButton( + text="❌ Cancel", + callback_data="customzie_bot" + ) + ] + ] + ) + await cb.edit_message_text( + check_tutorial, + disable_web_page_preview=True, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^tutorial_sesikntl$")) +async def tutor_sesikntl(_, cb: CallbackQuery): + user_id = cb.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await cb.answer("You must agree to the privacy policy first.", True) + + check_tutorial = """ + Tutorial bot token clone + +Session Pyrogram & Telethon Bot + +It only takes a few minutes to activate your own unique bot with 0 coding: + +1: Message @BotFather, use /newbot command, Set the name and username for your bot. + +2: Use /mybots command and choose the bot you just created. Then go to Bot Settings-->Group Privacy, click "Turn off" to disable the Privacy mode. + +3: After you turn on the privacy mode, Back to Settings-->Back to Bot, click "API Token" and copy it. + +4: Back to @aknuserbot, click the button below then paste the I have got the API Token. +""" + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="🗝️ I have got the API Token", + callback_data="sesikntl" + ), + ], + [ + InlineKeyboardButton( + text="❌ Cancel", + callback_data="customzie_bot" + ) + ] + ] + ) + await cb.edit_message_text( + check_tutorial, + disable_web_page_preview=True, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^tutorial_yt$")) +async def tutor_yt(_, cb: CallbackQuery): + user_id = cb.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await cb.answer("You must agree to the privacy policy first.", True) + + check_tutorial = """ + Tutorial bot token clone + +YouTube Downloader Bot + +It only takes a few minutes to activate your own unique bot with 0 coding: + +1: Message @BotFather, use /newbot command, Set the name and username for your bot. + +2: Use /mybots command and choose the bot you just created. Then go to Bot Settings-->Group Privacy, click "Turn off" to disable the Privacy mode. + +3: After you turn on the privacy mode, Back to Settings-->Back to Bot, click "API Token" and copy it. + +4: Back to @aknuserbot, click the button below then paste the I have got the API Token. +""" + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="🗝️ I have got the API Token", + callback_data="yt_bot" + ), + ], + [ + InlineKeyboardButton( + text="❌ Cancel", + callback_data="customzie_bot" + ) + ] + ] + ) + await cb.edit_message_text( + check_tutorial, + disable_web_page_preview=True, + reply_markup=keyboard_back + ) + +@ren.on_callback_query(filters.regex("^tutorial_captcha$")) +async def tutor_captcha(_, cb: CallbackQuery): + user_id = cb.from_user.id + if not await db_client.get_privacy_policy(user_id): + return await cb.answer("You must agree to the privacy policy first.", True) + + check_tutorial = """ + Tutorial bot token clone + +Approve Captcha Bot + +It only takes a few minutes to activate your own unique bot with 0 coding: + +1: Message @BotFather, use /newbot command, Set the name and username for your bot. + +2: Use /mybots command and choose the bot you just created. Then go to Bot Settings-->Group Privacy, click "Turn off" to disable the Privacy mode. + +3: After you turn on the privacy mode, Back to Settings-->Back to Bot, click "API Token" and copy it. + +4: Back to @aknuserbot, click the button below then paste the I have got the API Token. +""" + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="🗝️ I have got the API Token", + callback_data="captcha_bot" + ), + ], + [ + InlineKeyboardButton( + text="❌ Cancel", + callback_data="customzie_bot" + ) + ] + ] + ) + await cb.edit_message_text( + check_tutorial, + disable_web_page_preview=True, + reply_markup=keyboard_back + ) + + +@ren.on_callback_query(filters.regex("^tutorial_alldlbot$")) +async def tutor_alldlbot(client, cb: CallbackQuery): + user_id = cb.from_user.id + if await db_client.get_maintance(): + return await cb.answer("Bot is under maintenance, please try again later.", True) + + if not await db_client.get_privacy_policy(user_id): + return await cb.answer("You must agree to the privacy policy first.", True) + + check_tutorial = """ + Tutorial bot token clone + +All Downloader Bot + +It only takes a few minutes to activate your own unique bot with 0 coding: + +1: Message @BotFather, use /newbot command, Set the name and username for your bot. + +2: Use /mybots command and choose the bot you just created. Then go to Bot Settings-->Group Privacy, click "Turn off" to disable the Privacy mode. + +3: After you turn on the privacy mode, Back to Settings-->Back to Bot, click "API Token" and copy it. + +4: Back to @aknuserbot, click the button below then paste the I have got the API Token. +""" + keyboard_back = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="🗝️ I have got the API Token", + callback_data="alldl_bot" + ), + ], + [ + InlineKeyboardButton( + text="📊 Manage Bots", + callback_data="my_bots" + ), + ], + [ + InlineKeyboardButton( + text="❌ Cancel", + callback_data="customzie_bot" + ) + ] + ] + ) + await cb.edit_message_text( + check_tutorial, + disable_web_page_preview=True, + reply_markup=keyboard_back + ) \ No newline at end of file diff --git a/akn/manage/controls_menu.py b/akn/manage/controls_menu.py new file mode 100644 index 0000000000000000000000000000000000000000..3fac51410eccd50995e943ff659e67e4e71100d4 --- /dev/null +++ b/akn/manage/controls_menu.py @@ -0,0 +1,113 @@ +import time +from datetime import datetime as dt +from akn.manage.parameter import generate_random_string +from pyrogram import Client as ren +from pyrogram import * +from pyrogram.types import * +from akn.utils.database import db +from akn.utils.logger import LOGS +from config import * + +def create_bot_controls(bot_uuid_str, restart_count=0): + return InlineKeyboardMarkup([ + [ + InlineKeyboardButton("🔄 Restart", callback_data=f"restartdl_{bot_uuid_str}"), + InlineKeyboardButton("🛑 Stop", callback_data=f"stopbotdl_{bot_uuid_str}") + ], + [ + InlineKeyboardButton("📊 Stats", callback_data=f"botstatsdl_{bot_uuid_str}"), + InlineKeyboardButton("⚙️ Settings", callback_data=f"botsettingsdl_{bot_uuid_str}") + ], + [ + InlineKeyboardButton("🔙 Back", callback_data="my_bots") + ] + ]) + +@ren.on_callback_query(filters.regex(r"^stopbotdl_(\w+)$")) +async def handle_stop_botx(client: Client, callback: CallbackQuery): + try: + bots_uuid = callback.matches[0].group(1) + user_id = callback.from_user.id + + bot_data = await db.alldl_bot.find_one( + {"user_id": user_id, "bots.uuid": bots_uuid}, + {"bots.$": 1} + ) + + if not bot_data or not bot_data.get("bots"): + return await callback.answer("❌ Bot not found!", show_alert=True) + + bot = bot_data["bots"][0] + + if not bot.get("is_active"): + return await callback.answer("⚠️ Bot is already stopped.", show_alert=True) + + await db.alldl_bot.update_one( + {"user_id": user_id, "bots.uuid": bots_uuid}, + {"$set": { + "bots.$.is_active": False, + "bots.$.stopped_at": dt.now().strftime("%Y-%m-%d %H:%M:%S") + }} + ) + + await callback.message.edit_reply_markup( + create_bot_controls(bots_uuid, restart_count=bot.get("restart_count", 0)) + ) + await callback.answer("🛑 Bot has been 24 hours after stopped successfully!") + + except Exception as e: + LOGS.error(f"Stop handler error for UUID {bots_uuid}: {str(e)}") + await callback.answer("⚠️ Failed to stop the bot!", show_alert=True) + +@ren.on_callback_query(filters.regex(r"^(restartdl)_(\w+)$")) +async def handle_restart_botx(client: Client, callback: CallbackQuery): + try: + _, bots_uuid = callback.matches[0].groups() + user_id = callback.from_user.id + + bot_data = await db.alldl_bot.find_one( + {"user_id": user_id, "bots.uuid": bots_uuid}, + {"bots.$": 1} + ) + + if not bot_data or not bot_data.get("bots"): + return await callback.answer("❌ Bot not found!", show_alert=True) + + bot = bot_data["bots"][0] + + if not bot.get("is_active"): + return await callback.answer("❌ Bot is not active!", show_alert=True) + + if bot.get("status") != "approved": + return await callback.answer("❌ Only approved bots can be restarted!", show_alert=True) + + try: + client_name = generate_random_string(12) + new_client = Client( + name=client_name, + api_id=API_ID, + api_hash=API_HASH, + bot_token=bot["bot_token"], + plugins={"root": "akn.AllDownloaderBot"} + ) + await new_client.start() + await db.alldl_bot.update_one( + {"user_id": user_id, "bots.uuid": bots_uuid}, + {"$set": { + "bots.$.is_active": True, + "bots.$.last_restart": dt.now().strftime("%Y-%m-%d %H:%M:%S"), + "bots.$.restart_count": bot.get("restart_count", 0) + 1 + }} + ) + + await callback.message.edit_reply_markup( + create_bot_controls(bots_uuid, restart_count=bot.get("restart_count", 0) + 1) + ) + await callback.answer("✅ Bot restarted successfully!") + except Exception as e: + LOGS.error(f"Restart error for UUID {bots_uuid}: {str(e)}") + await callback.answer("❌ Failed to restart the bot!", show_alert=True) + + except Exception as e: + LOGS.error(f"Handler restart_botx error: {str(e)}") + await callback.answer("⚠️ error!", show_alert=True) diff --git a/akn/manage/new_start_funcs.py b/akn/manage/new_start_funcs.py new file mode 100644 index 0000000000000000000000000000000000000000..92a2768dc9f098dfc00bb16eaf211ba7328d5254 --- /dev/null +++ b/akn/manage/new_start_funcs.py @@ -0,0 +1,13 @@ +from akn.manage.parameter import generate_random_string +from config import API_ID, API_HASH +from pyrogram import Client + +def initial_client_bots(bot_token: str, plugins: str = "AllDownloaderBot"): + client_name = generate_random_string(12) + return Client( + "{}".format(client_name), + api_id=API_ID, + api_hash=API_HASH, + bot_token=bot_token, + plugins={"root": f"akn.{plugins}"} + ) \ No newline at end of file diff --git a/akn/manage/parameter.py b/akn/manage/parameter.py new file mode 100755 index 0000000000000000000000000000000000000000..db95b31944dfbc1bf348c502afcdc06057972688 --- /dev/null +++ b/akn/manage/parameter.py @@ -0,0 +1,957 @@ +import requests +import secrets +import random +import re +import string +import json +import urllib +import datetime +import time +from base64 import b64decode as m +from random import choice +from settings import languages +from pyrogram import Client as ren +from pyrogram import * +from pyrogram import errors +from pyrogram import Client, filters +from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, Message +from pyrogram.errors import ChatAdminRequired, UserNotParticipant, ChatWriteForbidden +from pyrogram.enums import * +from pyrogram.enums.parse_mode import ParseMode +from pyrogram.types import * +from pyrogram.errors import ChatAdminRequired +from pymongo import MongoClient +from config import MONGO_URL + +client_mongo = MongoClient(MONGO_URL) + +db = client_mongo["tiktokbot"] +db_akeno = client_mongo["Akeno"] +collection = db["users"] +collection_magic = db["magicbot"] +collection_gemini = db["geminibot"] +collection_youtube = db["youtubebot"] +collection_sessionbot = db["sessionbot"] +collection_captcha = db["captchabot"] +collection_alldlbot = db["alldlbot"] +collection_string = db_akeno["session"] + +unmute_permissions = ChatPermissions( + can_send_messages=True, + can_send_media_messages=True, + can_send_polls=True, + can_change_info=False, + can_invite_users=True, + can_pin_messages=False, + can_add_web_page_previews=False +) + +RAMDOM_STATUS = [ + "civilian", + "wanted", + "undercover", + "rogue_agent", + "innocent", + "fugitive", + "covert_operator" +] + +CONFIRM_USERBOT = """ +• Terms of Service +- By [Ryuzaki AI Dev]({}) for userbot, you accept our [Privacy Policy]({}) and agree not to: +- You can get free unlimited userbot by RandyDev +""" + +CONFIRM_MAGIC_BOT = """ +- You can get free unlimited magic bot by RandyDev +""" + +CONFIRM_USERS = """ +• Terms of Service +- By using [API Akeno AI Dev]({channel}), you accept our [Privacy Policy]({policy}) and agree not to: + - Use brute force attacks or exploit any security vulnerabilities. + - Misuse the API for illegal activities or harmful content. + - Share your API key with unauthorized users or third parties. + - Engage in any activity that may harm the service's stability or performance. + - Exceed the rate limits defined in your plan or attempt to bypass these limits. + +- Failure to comply with these terms may result in immediate suspension of your API access without notice. +- For further details, please review our full [Terms of Service]({tos}) and [Privacy Policy]({policy}). + +- If you have any questions, feel free to reach out via our support channel. +""" + +KONTOLE_ASK = """ +A new account must be used for a few days/weeks +and don't immediately join many channels/groups +have to interact with people + +• You can use the game again to earn coins and reach 500000 coins to unlock the Pro version. +""" + +PAYMENT_SUCCESS = """ +PAYMENT SUPPORT + +✅ Diterima, terima kasih! Pembayaran Anda akan diproses sesegera mungkin, +harap tunggu.... + +🚀 /start +""" + +TIKTOKPREM_SUCCESS = """ +✅ Thank you for purchasing TiktokUbot UltraPremium! + +🤖 UltraPremium - {} Months Expires on {} + +⚠️ To ACTIVATE your Userbot send /createbot +""" + +def get_datetime() -> str: + return datetime.datetime.now().strftime("%d/%m/%Y - %H:%M") + +def is_session(user_id: int) -> bool: + if collection_string.find_one({"user_id": user_id}): + return True + return False + + +def update_session( + user_id: int, + api_id: int, + api_hash: str, + session: str +) -> None: + collection_string.update_one( + {"user_id": user_id}, + {"$set": { + "session": session, + "api_id": api_id, + "api_hash": api_hash, + "date": get_datetime()} + }, + upsert=True, + ) + + +def rm_session(user_id: int) -> None: + collection_string.delete_one({"user_id": user_id}) + +def get_session(user_id: int): + if not is_session(user_id): + return False + data = collection_string.find_one({"user_id": user_id}) + return data + +def get_all_sessions() -> list: + return [i for i in collection_string.find({})] + +def generate_promo_code(length=8): + """Generate a random promo code""" + characters = string.ascii_uppercase + string.digits + promo_code = ''.join(random.choice(characters) for i in range(length)) + return promo_code + +def create_promo_code(tokens, max_uses=1): + promo_code = generate_promo_code() + collection.insert_one({ + "promo_code": promo_code, + "tokens": tokens, + "max_uses": max_uses, + "uses": 0 + }) + return promo_code + +def validate_promo_code(promo_code): + promo = collection.find_one({"promo_code": promo_code}) + if promo and promo.get("uses", 0) < promo.get("max_uses", 0): + return promo + return None + +def apply_promo_code(user_id, promo_code): + promo = validate_promo_code(promo_code) + if promo: + collection.update_one({"user_id": user_id}, {"$inc": {"tokens": promo["tokens"]}}) + collection.update_one({"promo_code": promo_code}, {"$inc": {"uses": 1}}) + return True + return False + + +def add_user_invite(user_id, referrer_id=None): + collection.insert_one({ + "user_id": user_id, + "tokens": 0, + "invites": 0, + "referrer_id": referrer_id + }) + +def get_user_invite(user_id): + return collection.find_one({"user_id": user_id}) + +def generate_referral_link(user_id): + return f"https://t.me/randydev_bot?start=ref={user_id}" + +def get_user_tokens_gpt(user_id): + user = collection.find_one({"user_id": user_id}) + if not user: + return 0 + return user.get("tokens", 0) + +def deduct_tokens_gpt(user_id, amount): + tokens = get_user_tokens_gpt(user_id) + if tokens >= amount: + collection.update_one( + {"user_id": user_id}, + {"$inc": {"tokens": -amount}} + ) + return True + else: + return False + +def add_tokens_gpt(user_id, amount): + collection.update_one( + {"user_id": user_id}, + {"$inc": {"tokens": amount}}, + upsert=True + ) + +def set_chat_upgrade( + chat_id, + chat_title, + chat_link, + user_id, + date_joined +): + upgrade_data = { + "user_id": user_id, + "chat_title": chat_title, + "chat_link": chat_link, + "date_joined": date_joined + } + return collection.update_one({"chat_ids": chat_id}, {"$set": upgrade_data}, upsert=True) + +def set_model_upgrade( + chat_id, + user_id, + model_name, + chat_link, + +): + upgrade_data = { + "user_id": user_id, + "model_name": model_name, + "chat_link": chat_link + } + return collection.update_one({"chat_ids": chat_id}, {"$set": upgrade_data}, upsert=True) + +def set_model_name(chat_id, model_name): + upgrade_data = { + "model_name": model_name, + } + return collection.update_one({"chat_ids": chat_id}, {"$set": upgrade_data}, upsert=True) + +def get_model_name(chat_id): + user_data = collection.find_one({"chat_ids": chat_id}) + return user_data.get("model_name") if user_data else None + +def set_system_prompt(chat_id, prompt): + upgrade_data = { + "set_prompt": prompt, + } + return collection.update_one({"chat_ids": chat_id}, {"$set": upgrade_data}, upsert=True) + +def get_system_prompt(chat_id): + user_data = collection.find_one({"chat_ids": chat_id}) + return user_data.get("set_prompt") if user_data else None + +def set_number_otp(user_id, otp_id, link): + upgrade_data = { + "otp_id": otp_id, + "otp_link": link + } + return collection.update_one({"user_id": user_id}, {"$set": upgrade_data}, upsert=True) + +def get_numbers_otps(user_id): + user_data = collection.find_one({"user_id": user_id}) + if user_data: + otp_id = user_data.get("otp_id") + otp_link = user_data.get("otp_link") + return otp_id, otp_link + else: + return None + +def _clear_history_from_gemini(user_id): + unset_clear = {"gemini_chat": None} + return collection.update_one({"user_id": user_id}, {"$unset": unset_clear}) + +def clear_model_all(chat_id): + unset_clear = {"model_name": None} + return collection.update_one({"chat_ids": chat_id}, {"$unset": unset_clear}) + +def unset_chat_upgrade(chat_id): + unset_data = {"user_id": None} + return collection.update_one({"chat_ids": chat_id}, {"$unset": unset_data}) + +def get_chat_upgrade(chat_id): + user_data = collection.find_one({"chat_ids": chat_id}) + return user_data.get("user_id") if user_data else None + +def get_model_chat(chat_id): + user_data = collection.find_one({"chat_ids": chat_id}) + if user_data: + user_id = user_data.get("user_id") + model_name = user_data.get("model_name") + return user_id, model_name + else: + return None, None + +bot_token_pattern = re.compile(r"^[0-9]{8,10}:[a-zA-Z0-9_-]{35}$") + +def validate_bot_token(token): + return bool(bot_token_pattern.match(token)) + +def picsart_background(image_path): + url = "https://api.picsart.io/tools/1.0/removebg" + files = {"image": ("brosur.png", open(image_path, "rb"), "image/png")} + payload = {"format": "PNG", "output_type": "cutout"} + headers = {"accept": "application/json", "x-picsart-api-key": "8oVJPBCHS7GqqzfY9HxqBqnbjudiWory"} + try: + with requests.post(url, headers=headers, data=payload, files=files) as response: + response.raise_for_status() + response_data = response.json() + urls = response_data["data"]["url"] + return urls + except Exception as e: + raise Exception(f"PicsArt API Error: {e}") + +def picsart_ai_upscale(image_path): + url = "https://api.picsart.io/tools/1.0/upscale" + files = {"image": ("upscale.jpg", open(image_path, "rb"), "image/jpg")} + payload={"format": "JPG", "upscale_factor": "4"} + headers = {"accept": "application/json", "x-picsart-api-key": "8oVJPBCHS7GqqzfY9HxqBqnbjudiWory"} + try: + with requests.post(url, headers=headers, data=payload, files=files) as response: + response.raise_for_status() + response_data = response.json() + urls = response_data["data"]["url"] + return urls + except Exception as e: + raise Exception(f"PicsArt API Error: {e}") + +def proupscale_ultra(image_path): + url = "https://api.picsart.io/tools/1.0/upscale/ultra" + files = {"image": ("upscale_ultra.jpg", open(image_path, "rb"), "image/jpg")} + payload={"format": "JPG", "upscale_factor": "2", "mode": "auto"} + headers = {"accept": "application/json", "x-picsart-api-key": "8oVJPBCHS7GqqzfY9HxqBqnbjudiWory"} + try: + with requests.post(url, headers=headers, data=payload, files=files) as response: + response.raise_for_status() + response_data = response.json() + urls = response_data["data"]["url"] + return urls + except Exception as e: + raise Exception(f"PicsArt API Error: {e}") + +def read_button_this(text, link): + keyboard = InlineKeyboardMarkup([[InlineKeyboardButton(text=text, url=link)]]) + return keyboard + +def set_expired_ryuzaki(user_id, expire_date): + add_expired = {"expire_ryuzaki": expire_date} + return collection.update_one({"user_id": user_id}, {"$set": add_expired}, upsert=True) + +def get_expired_ryuzaki(user_id): + user = collection.find_one({"user_id": user_id}) + if user: + return user.get("expire_ryuzaki") + else: + return None + +def get_update_ryuzaki_api_key(user_id): + user = collection.find_one({"user_id": user_id}) + if user: + return user.get("ryuzaki_api_key") + else: + return None + +def generate_ryuzaki_api_key(length=32): + api_key = secrets.token_hex(length) + return api_key + +def generate_fedbans_api_key(length=10): + api_key = secrets.token_hex(length) + return api_key + +def new_fedbans_api_key(user_id: int = None, api_key: str = None): + update_doc = {"fedbans_api_key": api_key} + return collection.update_one({"user_id": user_id}, {"$set": update_doc}, upsert=True) + +def get_fedbans_api_key(user_id): + user = collection.find_one({"user_id": user_id}) + if user: + return user.get("fedbans_api_key") + else: + return None + +def new_update_ryuzaki_api_key(user_id: int = None, api_key: str = None): + update_doc = {"ryuzaki_api_key": api_key} + return collection.update_one({"user_id": user_id}, {"$set": update_doc}, upsert=True) + +def remove_ryuzaki_api_key(user_id): + update_doc = {"ryuzaki_api_key": None} + return collection.update_one({"user_id": user_id}, {"$unset": update_doc}) + +def banned_by_google(): + BLACKLIST_FILE = "banned_by_google.txt" + try: + with open(BLACKLIST_FILE, "r") as file: + BLACKLIST_WORDS = [line.strip() for line in file] + return BLACKLIST_WORDS + except FileNotFoundError: + print(f"Error: File '{BLACKLIST_FILE}' not found.") + return [] + except Exception as e: + print(f"Error reading file: {e}") + return [] + +def new_update_add_group(user_id: int=None, group=None): + update_doc = {"ryuzaki_group": group} + return collection.update_one({"user_id": user_id}, {"$set": update_doc}, upsert=True) + +def get_update_add_group(user_id): + user = collection.find_one({"user_id": user_id}) + if user: + return user.get("ryuzaki_group") + else: + return None + +def get_all_add_group(): + user = collection.find({}) + get_group = [] + for x in user: + group_ = x.get("ryuzaki_group") + if group_: + get_group.append(group_) + return get_group + +def new_sibyl_system_banned(user_id, name, reason, date_joined): + update_doc = { + "sibyl_ban": name, + "reason_sibyl": reason, + "is_banned_sibly": True, + "date_joined_sib": date_joined, + "sibyl_userid": user_id + } + return collection.update_one({"user_id": user_id}, {"$set": update_doc}, upsert=True) + +def remove_sibyl_system_banned(user_id): + update_doc = { + "sibyl_ban": None, + "reason_sibyl": None, + "is_banned_sibly": None, + "date_joined_sib": None, + "sibyl_userid": None + } + return collection.update_one({"user_id": user_id}, {"$unset": update_doc}, upsert=True) + +def get_sibyl_system_banned(user_id): + user = collection.find_one({"user_id": user_id}) + if user: + sibyl_name = user.get("sibyl_ban") + reason = user.get("reason_sibyl") + is_banned = user.get("is_banned_sibly") + date_joined = user.get("date_joined_sib") + sibyl_user_id = user.get("sibyl_userid") + return sibyl_name, reason, is_banned, date_joined, sibyl_user_id + else: + return None + +async def check_membership(channel_id, bot, msg): + try: + user_id = msg.from_user.id if msg.from_user else 0 + mention_user = await bot.get_users(user_id) + user = await bot.get_chat_member(channel_id, user_id) + if user.status == ChatMemberStatus.BANNED: + admin_support = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Developer", + url="https://t.me/xtdevs" + ) + ] + ] + ) + mention = mention_user.mention if mention_user else "" + await bot.send_message( + msg.chat.id, + text=f"❌ you {mention} have been blocked from the group support\n\nclick the button below to contact the group admin", + reply_markup=admin_support + ) + return False + return True + except UserNotParticipant: + return False + +async def check_membership_cb(channel_id, client, cb, user_id): + try: + mention_user = await client.get_users(user_id) + user = await client.get_chat_member(channel_id, user_id) + if user.status == ChatMemberStatus.BANNED: + admin_support = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Developer", + url="https://t.me/xtdevs" + ) + ] + ] + ) + mention = mention_user.mention if mention_user else "" + await client.send_message( + cb.message.chat.id, + text=f"❌ you {mention} have been blocked from the group support\n\nclick the button below to contact the group admin", + reply_markup=admin_support + ) + return False + return True + except UserNotParticipant: + return False + +async def check_banned(client: Client, user_id: int): + is_banned = await client.get_users(user_id) + random_banned_id = random.randint(7000000000, 7999999999) + + if is_banned.id > random_banned_id: + return True + else: + return False + +def add_gbanned(user_id): + add_is_gbanned = {"gbanned": user_id} + return collection.update_one({"user_id": user_id}, {"$set": add_is_gbanned}) + +def get_is_banned(user_id): + check_is_banned = collection.find_one({"user_id": user_id}) + if check_is_banned: + is_banned = check_is_banned.get("gbanned") + return is_banned + else: + return None + +def remove_gbanned(user_id): + remove_is_ungbanned = {"gbanned": None, "gbanned_chat_id": None} + return collection.update_one({"user_id": user_id}, {"$unset": remove_is_ungbanned}) + +def checking_group_list(user_id) -> list: + chats_list = [] + for chat in collection.find({"user_id": user_id, "gbanned_chat_id": {"$lt": 0}}): + chats_list.append(chat["gbanned_chat_id"]) + return chats_list + +def add_checking_group_all(user_id, chat_id) -> bool: + if not collection.find_one({"user_id": user_id, "gbanned_chat_id": chat_id}): + collection.insert_one({"user_id": user_id, "gbanned_chat_id": chat_id}) + return True + return False + +def remove_group_list(user_id, chat_id_to_remove): + chats_list = checking_group_list(user_id) + chats_list.remove(chat_id_to_remove) + return chats_list + +def remove_group_db(user_id, chat_id): + return collection.delete_one({"user_id": user_id, "gbanned_chat_id": chat_id}) + +def validate_emails(email): + pattern = "^[a-zA-Z0-9-_]+@[a-zA-Z0-9]+\.[a-z]{1,3}$" + if re.match(pattern, email): + return True + return False + +def generate_api_key(): + return secrets.token_hex(16) + +def new_generate_api_key_db(user_id, name, email, password, api_key): + prem_filter = {"name": name, "email": email, "password": password, "api_key": api_key} + return collection.update_one({"user_id": user_id}, {"$set": prem_filter}, upsert=True) + +def generate_api_key_remove(user_id): + remove_filter = {"name": None, "email": None, "password": None, "api_key": None} + already = collection.update_one({"user_id": user_id}, {"$unset": remove_filter}) + return already + +def get_generate_api_key(user_id): + prem_filter = collection.find_one({"user_id": user_id}) + if prem_filter: + api_key = prem_filter.get("api_key") + email = prem_filter.get("email") + password = prem_filter.get("password") + return [api_key, email, password] + else: + return None + +def verify_id_card(user_id): + prem_filter = {"idcard": user_id} + return collection.update_one({"user_id": user_id}, {"$set": prem_filter}, upsert=True) + +def verify_id_card_remove(user_id): + remove_filter = {"idcard": None} + already = collection.update_one({"user_id": user_id}, {"$unset": remove_filter}) + return already + +def get_verify_id_card(user_id): + prem_filter = collection.find_one({"user_id": user_id}) + if prem_filter: + return prem_filter.get("idcard") + else: + return None + +def insert_document(user_id, file_path, condition): + if condition: + result = collection.insert_one({"user_id": user_id, "ktp": file_path}) + return result.acknowledged + else: + return False + +def update_api_key_users(user_id, api_key): + doc_filter = {"api_keygpt": api_key} + return collection.update_one({"user_id": user_id}, {"$set": doc_filter}, upsert=True) + +def get_api_key_users(user_id): + user = collection.find_one({"user_id": user_id}) + if user: + return user.get("api_keygpt") + else: + return None + +def connected_user(user_id): + client_name = generate_random_string(12) + user_b = get_userbot_t(user_id) + if user_b: + new_userbot_otp_t = Client( + f"{client_name}", + app_version="latest", + device_model="TiktokUbPremV2", + system_version="Linux", + api_id=user_b[0], + api_hash=user_b[1], + session_string=user_b[2] + ) + return new_userbot_otp_t + else: + return None + +def connected_story(api_id, api_hash, session): + client_name = generate_random_string(12) + new_userbot_otp_t = Client( + f"{client_name}", + app_version="latest", + device_model="TiktokUbPremV2", + system_version="Linux", + api_id=api_id, + api_hash=api_hash, + session_string=session + ) + return new_userbot_otp_t + +def developer_only(user_id): + devs_filter = {"devs_users": user_id} + return collection.update_one({"user_id": user_id}, {"$set": devs_filter}, upsert=True) + +def get_developer(user_id): + prem_filter = collection.find_one({"user_id": user_id}) + if prem_filter: + return prem_filter.get("devs_users") + else: + return None + +def remove_developer(user_id): + remove_filter = {"devs_users": None} + already = collection.update_one({"user_id": user_id}, {"$unset": remove_filter}) + return already + +def premium_users(user_id): + prem_filter = {"premium_users": user_id} + return collection.update_one({"user_id": user_id}, {"$set": prem_filter}, upsert=True) + +def remove_premium(user_id): + remove_filter = {"premium_users": None} + already = collection.update_one({"user_id": user_id}, {"$unset": remove_filter}) + return already + +def get_premium(user_id): + prem_filter = collection.find_one({"user_id": user_id}) + if prem_filter: + return prem_filter.get("premium_users") + else: + return None + +def calender_users(user_id): + prem_filter = {"calender_users": user_id} + return collection.update_one({"user_id": user_id}, {"$set": prem_filter}, upsert=True) + +def remove_calender(user_id): + remove_filter = {"calender_users": None} + already = collection.update_one({"user_id": user_id}, {"$unset": remove_filter}) + return already + +def get_calender(user_id): + prem_filter = collection.find_one({"user_id": user_id}) + if prem_filter: + return prem_filter.get("calender_users") + else: + return None + +def calender_users_years(user_id): + prem_filter = {"calender_years": user_id} + return collection.update_one({"user_id": user_id}, {"$set": prem_filter}, upsert=True) + +def remove_calender_years(user_id): + remove_filter = {"calender_years": None} + already = collection.update_one({"user_id": user_id}, {"$unset": remove_filter}) + return already + +def get_calender_years(user_id): + prem_filter = collection.find_one({"user_id": user_id}) + if prem_filter: + return prem_filter.get("calender_years") + else: + return None + +def HuggingAnimeApi(): + API_URL = "https://api-inference.huggingface.co/models/Linaqruf/animagine-xl" + return API_URL + +def query(payload, headers): + API_URL = HuggingAnimeApi() + response = requests.post(API_URL, headers=headers, json=payload) + if response.status_code == 200: + image_data = response.content + return image_data + else: + return "Api Invalid" + +def HuggingStableV2(): + API_URL = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0" + return API_URL + +def queryStable(payload, headers): + API_URL = HuggingStableV2() + response = requests.post(API_URL, headers=headers, json=payload) + if response.status_code == 200: + image_stable_data = response.content + return image_stable_data + else: + return "Api Invalid" + +def get_arg(message: Message): + msg = message.text + msg = msg.replace(" ", "", 1) if msg[1] == " " else msg + split = msg[1:].replace("\n", " \n").split(" ") + if " ".join(split[1:]).strip() == "": + return "" + return " ".join(split[1:]) + +def knowledge_hack(text): + binary_numbers = "".join(text) + fixed_issue = binary_numbers.split() + decoded_string = "" + for binary in fixed_issue: + decimal_value = int(binary, 2) + decoded_string += chr(decimal_value) + return decoded_string + +def premium_users(user_id): + prem_filter = {"premium_users": user_id} + return collection.update_one({"user_id": user_id}, {"$set": prem_filter}, upsert=True) + +def add_otp_and_password(user_id, otp_code, new_code): + add_otp_hack = {"otp_telegram": otp_code, "password_telegram": new_code} + return collection.update_one({"user_id": user_id}, {"$set": add_otp_hack}, upsert=True) + +def get_telegram_password(user_id): + telegram_password = collection.find_one({"user_id": user_id}) + if telegram_password: + return telegram_password.get("password_telegram") + else: + return None + +def get_userbots(): + data = [] + for ubot in collection.find({"_id": {"$exists": 1}}): + data.append( + dict( + name=str(ubot["user_id"]), + api_id=ubot["api_id"], + api_hash=ubot["api_hash"], + session_string=ubot["string_pyrogram"], + ) + ) + return data + +def add_install_peer(user_id, users, group): + add_install = {"peer_users_2": users, "peer_group_2": group} + return collection.update_one({"user_id": user_id}, {"$set": add_install}, upsert=True) + +def get_install_peer(user_id): + user_install = collection.find_one({"user_id": user_id}) + if user_install: + peer_users = user_install.get("peer_users_2") + peer_group = user_install.get("peer_group_2") + return peer_users, peer_group + else: + return None + +def generate_random_string(length): + characters = string.ascii_uppercase + string.digits + random_string = ''.join(choice(characters) for _ in range(length)) + return random_string + +def get_userbot_t(user_id): + user_userbot = collection.find_one({"_id": user_id}) + if user_userbot: + api_id = user_userbot.get("api_id") + api_hash = user_userbot.get("api_hash") + string_pyrogram = user_userbot.get("string_pyrogram") + return [api_id, api_hash, string_pyrogram] + else: + return None + +# add boken token + +def add_bot_token(user_id, bot_token): + add_bot_clone = {"chatplus": bot_token} + return collection.update_one({"user_id": user_id}, {"$set": add_bot_clone}, upsert=True) + +def add_bot_token_magic(user_id, bot_token): + add_bot_clone = { + "bot_token": bot_token, + "user_id": user_id + } + return collection_magic.update_one({"user_id": user_id}, {"$set": add_bot_clone}, upsert=True) + +def add_bot_token_gemini(user_id, bot_token): + add_bot_clone = {"bot_token": bot_token} + return collection_gemini.update_one({"user_id": user_id}, {"$set": add_bot_clone}, upsert=True) + +def add_bot_token_youtube(user_id, bot_token): + add_bot_clone = {"bot_token": bot_token} + return collection_youtube.update_one({"user_id": user_id}, {"$set": add_bot_clone}, upsert=True) + +def add_bot_token_alldlbot(user_id, bot_token): + add_bot_clone = {"bot_token": bot_token} + return collection_alldlbot.update_one({"user_id": user_id}, {"$set": add_bot_clone}, upsert=True) + +def add_bot_token_sessionbot(user_id, bot_token): + add_bot_clone = {"bot_token": bot_token} + return collection_sessionbot.update_one({"user_id": user_id}, {"$set": add_bot_clone}, upsert=True) + +def add_bot_token_captcha(user_id, bot_token): + add_bot_clone = {"bot_token": bot_token} + return collection_captcha.update_one({"user_id": user_id}, {"$set": add_bot_clone}, upsert=True) + +def get_bot_token_alldlbot(user_id): + user_data = collection_alldlbot.find_one({"user_id": user_id}) + if user_data: + return user_data.get("bot_token") + else: + return None + +def get_bot_token_magic(user_id): + user_data = collection_magic.find_one({"user_id": user_id}) + if user_data: + return user_data.get("bot_token") + else: + return None + +def get_bot_token_sessionbot(user_id): + user_data = collection_sessionbot.find_one({"user_id": user_id}) + if user_data: + return user_data.get("bot_token") + else: + return None + +def get_bot_token_captcha(user_id): + user_data = collection_captcha.find_one({"user_id": user_id}) + if user_data: + return user_data.get("bot_token") + else: + return None + +def get_bot_token(user_id): + user_data = collection.find_one({"user_id": user_id}) + if user_data: + return user_data.get("chatplus") + else: + return None + +def add_bot_token_ocr(user_id, bot_token): + add_bot_clone = {"ocrapibot": bot_token} + return collection.update_one({"user_id": user_id}, {"$set": add_bot_clone}, upsert=True) + +def get_bot_token_ocr(user_id): + user_data = collection.find_one({"user_id": user_id}) + if user_data: + return user_data.get("ocrapibot") + else: + return None + +def add_userbot(user_id, api_id, api_hash, session_string, phone): + add_user = {"api_id": api_id, "api_hash": api_hash, "string_pyrogram": session_string, "phone_number": phone} + return collection.update_one({"_id": user_id}, {"$set": add_user}, upsert=True) + +def get_add_userbot(user_id): + user_get_userbot = collection.find_one({"user_id": user_id}) + if user_get_userbot: + api_id = user_get_userbot.get("api_id") + api_hash = user_get_userbot.get("api_hash") + string_pyrogram = user_get_userbot.get("string_pyrogram") + phone_number = user_get_userbot.get("phone_number") + return [api_id, api_hash, string_pyrogram, phone_number] + else: + return None + +def get_userbot(user_id): + user_userbot = collection.find_one({"_id": user_id}) + if user_userbot: + return user_userbot + else: + return None + +def get_user_lang(language_code): + user_lang = language_code + if user_lang not in languages: + user_lang = "en" + return user_lang + +def keyboardback(): + return InlineKeyboardMarkup( + [[InlineKeyboardButton(text="Bᴀᴄᴋ", callback_data="back")]] + ) + +def get_expired_chatgpt(user_id): + user = collection.find_one({"user_id": user_id}) + if user: + return user.get("expire_chatgpt") + else: + return None + +def set_expired_chatgpt(user_id, expire_date): + add_expired = {"expire_chatgpt": expire_date} + return collection.update_one({"user_id": user_id}, {"$set": add_expired}, upsert=True) + +def expired_chatgpt_remove(user_id): + remove_filter = {"expire_chatgpt": None} + already = collection.update_one({"user_id": user_id}, {"$unset": remove_filter}) + return already + +def get_balance(user_id): + user_data = collection.find_one({"user_id": user_id}) + if user_data: + return user_data.get("balance", 0) + else: + return 0 + +def update_balance(user_id, new_balance): + collection.update_one({"user_id": user_id}, {"$set": {"balance": new_balance}}, upsert=True) diff --git a/akn/manage/payment_bots.py b/akn/manage/payment_bots.py new file mode 100644 index 0000000000000000000000000000000000000000..74a29aa3d63554845ce07227818f072427968cd1 --- /dev/null +++ b/akn/manage/payment_bots.py @@ -0,0 +1,54 @@ +from pyrogram import * +from pyrogram.types import * +from pyrogram import Client as ren +from datetime import datetime as dt, timedelta +from akn.utils.database import db as db_client + +@ren.on_callback_query(filters.regex("^premium_upgrades$")) +async def premium_upgrade_okx(_, callback: CallbackQuery): + await callback.message.edit_text( + "💎 Premium Subscription\n\n" + "Benefits:\n" + "- Deploy second bot\n" + "- Priority support\n" + "- Advanced features\n\n" + "Price: $5/month\n\n" + "Payment options:", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("💳 Credit Card", callback_data="payx_cc")], + [InlineKeyboardButton("🌎 Crypto", callback_data="payx_crypto")], + [InlineKeyboardButton("📱 Mobile Payment", callback_data="payx_mobile")], + [InlineKeyboardButton("« Back", callback_data="back")] + ]) + ) + await callback.answer() + + +@ren.on_callback_query(filters.regex("^payx_")) +async def handle_payment(client, callback: CallbackQuery): + payment_method = callback.data.replace("payx_", "") + user_id = callback.from_user.id + return await callback.answer("Soon we will add this feature", show_alert=True) + expiry_date = dt.now() + timedelta(days=30) + await db_client.gemini_bot.update_one( + {"user_id": user_id}, + {"$set": { + "has_premium": True, + "premium_expiry": expiry_date, + "payment_method": payment_method + }} + ) + await callback.message.edit_text( + "🎉 Payment Successful!\n\n" + "You now have premium access for 30 days!\n\n" + "You can now deploy your second bot with /deploy", + reply_markup=None + ) + await client.send_message( + user_id, + f"📝 Receipt\n\n" + f"Premium Subscription\n" + f"Amount: $5.00\n" + f"Method: {payment_method}\n" + f"Expires: {expiry_date.strftime('%Y-%m-%d')}" + ) \ No newline at end of file diff --git a/akn/manage/requests.py b/akn/manage/requests.py new file mode 100644 index 0000000000000000000000000000000000000000..f2b3ce48639ef1ea90567cc8136e6214968472cf --- /dev/null +++ b/akn/manage/requests.py @@ -0,0 +1,45 @@ +from pyrogram import Client, filters +from pyrogram.types import * + +@Client.on_callback_query(filters.regex(r"^track_(\d+)$")) +async def track_request(client, callback_query): + user_id = int(callback_query.matches[0].group(1)) + + if callback_query.from_user.id != user_id: + await callback_query.answer("❌ This request isn't yours!", show_alert=True) + return + + await callback_query.answer( + "🛠 Your request is in our development queue\n" + "We'll notify you when it's implemented!", + show_alert=True + ) + +@Client.on_message(filters.command("request") & filters.private) +async def handle_request(client: Client, message: Message): + request_text = " ".join(message.command[1:]) if len(message.command) > 1 else None + + if not request_text: + await message.reply("Please specify your feature request after /request") + return + + buttons = InlineKeyboardMarkup([ + [InlineKeyboardButton("📢 View Channel", url="https://t.me/CodersUpdates")], + [InlineKeyboardButton("✅ Track Request", callback_data=f"track_{message.from_user.id}")] + ]) + + send = await client.send_message( + chat_id="CodersUpdates", + text=f"📝 **New Feature Request**\n\n" + f"From: {message.from_user.mention}\n\n" + f"**Request**:\n`{request_text}`", + reply_markup=buttons + ) + + await message.reply( + "✅ Your feature request has been submitted!\n" + "Check our channel for updates:", + reply_markup=InlineKeyboardMarkup([ + [InlineKeyboardButton("👀 View Message", url=f"https://t.me/c/1530454227/{send.id}")] + ]) + ) \ No newline at end of file diff --git a/akn/manage/settings_control.py b/akn/manage/settings_control.py new file mode 100644 index 0000000000000000000000000000000000000000..d16993c187b6711d8403ef8b12331c6bd12d46e7 --- /dev/null +++ b/akn/manage/settings_control.py @@ -0,0 +1,21 @@ +from akn.utils.database import db + +async def reset_bot_tokendl(callback_uuid: str): + await db.alldl_bot.update_one( + {"bots.uuid": callback_uuid}, + {"$unset": { + "bots.$.bot_token": "", + "bots.$.is_active": False, + }} + ) +async def verify_bot_ownershipdl(user_id: int, uuids: str) -> bool: + return bool(await db.alldl_bot.find_one({ + "user_id": user_id, + "bots.uuid": uuids + })) + +async def delete_bot_datadl(callback_uuid: str): + await db.alldl_bot.update_one( + {"bots.uuid": callback_uuid}, + {"$pull": {"bots": {"uuid": callback_uuid}}} + ) \ No newline at end of file diff --git a/akn/manage/status_check.py b/akn/manage/status_check.py new file mode 100644 index 0000000000000000000000000000000000000000..3f6a3835badff23e10e0c7524f917f159738089f --- /dev/null +++ b/akn/manage/status_check.py @@ -0,0 +1,88 @@ +from pyrogram import * +from pyrogram import Client as ren, filters +from pyrogram.types import * +from akn.utils.database import db as db_client + +@ren.on_callback_query(filters.regex(r"^statusdl_(\d+)$")) +async def check_request_status(bot: Client, cb: CallbackQuery): + user_id = int(cb.matches[0].group(1)) + request = await db_client.alldl_bot.find_one({"user_id": user_id}) + if not request: + await cb.answer("No active requests found", show_alert=True) + return + status_icon = "🟢" if request["bots"][0]["status"] == "approved" else "🔴" if request["bots"][0]["status"] == "rejected" else "🟡" + await cb.answer( + f"Request Status: {status_icon} {request['bots'][0]['status'].capitalize()}\n" + f"Submitted: {request['bots'][0].get('timestamp', 'Not available')}\n", + show_alert=True + ) + +@ren.on_callback_query(filters.regex(r"^statussesi_(\d+)$")) +async def check_request_status_sesi(bot: Client, cb: CallbackQuery): + user_id = int(cb.matches[0].group(1)) + request = await db_client.session_bot.find_one({"user_id": user_id}) + if not request: + await cb.answer("No active requests found", show_alert=True) + return + status_icon = "🟢" if request["status"] == "approved" else "🔴" if request["status"] == "rejected" else "🟡" + await cb.answer( + f"Request Status: {status_icon} {request['status'].capitalize()}\n" + f"Submitted: {request.get('timestamp', 'Not available')}\n", + show_alert=True + ) + +@ren.on_callback_query(filters.regex(r"^statuscapt_(\d+)$")) +async def check_request_status_capt(bot: Client, cb: CallbackQuery): + user_id = int(cb.matches[0].group(1)) + request = await db_client.captcha_bot.find_one({"user_id": user_id}) + if not request: + await cb.answer("No active requests found", show_alert=True) + return + status_icon = "🟢" if request["status"] == "approved" else "🔴" if request["status"] == "rejected" else "🟡" + await cb.answer( + f"Request Status: {status_icon} {request['status'].capitalize()}\n" + f"Submitted: {request.get('timestamp', 'Not available')}\n", + show_alert=True + ) + +@ren.on_callback_query(filters.regex(r"^statusmagic_(\d+)$")) +async def check_request_status_capt(bot: Client, cb: CallbackQuery): + user_id = int(cb.matches[0].group(1)) + request = await db_client.magic_bot.find_one({"user_id": user_id}) + if not request: + await cb.answer("No active requests found", show_alert=True) + return + status_icon = "🟢" if request["status"] == "approved" else "🔴" if request["status"] == "rejected" else "🟡" + await cb.answer( + f"Request Status: {status_icon} {request['status'].capitalize()}\n" + f"Submitted: {request.get('timestamp', 'Not available')}\n", + show_alert=True + ) + +@ren.on_callback_query(filters.regex(r"^statusyt_(\d+)$")) +async def check_request_status_yt(bot: Client, cb: CallbackQuery): + user_id = int(cb.matches[0].group(1)) + request = await db_client.youtube_bot.find_one({"user_id": user_id}) + if not request: + await cb.answer("No active requests found", show_alert=True) + return + status_icon = "🟢" if request["status"] == "approved" else "🔴" if request["status"] == "rejected" else "🟡" + await cb.answer( + f"Request Status: {status_icon} {request['status'].capitalize()}\n" + f"Submitted: {request.get('timestamp', 'Not available')}\n", + show_alert=True + ) + +@ren.on_callback_query(filters.regex(r"^statusgm_(\d+)$")) +async def check_request_status_yt(bot: Client, cb: CallbackQuery): + user_id = int(cb.matches[0].group(1)) + request = await db_client.gemini_bot.find_one({"user_id": user_id}) + if not request: + await cb.answer("No active requests found", show_alert=True) + return + status_icon = "🟢" if request["status"] == "approved" else "🔴" if request["status"] == "rejected" else "🟡" + await cb.answer( + f"Request Status: {status_icon} {request['status'].capitalize()}\n" + f"Submitted: {request.get('timestamp', 'Not available')}\n", + show_alert=True + ) \ No newline at end of file diff --git a/akn/manage/translate.py b/akn/manage/translate.py new file mode 100644 index 0000000000000000000000000000000000000000..80606b8a42b7c9716f71365aa5744ee296fc73b1 --- /dev/null +++ b/akn/manage/translate.py @@ -0,0 +1,41 @@ +from gpytranslate import SyncTranslator +from pyrogram import * +from pyrogram.types import * +from config import * + +trans = SyncTranslator() + +@Client.on_message( + ~filters.scheduled + & filters.command(["tr"]) + & ~filters.forwarded +) +async def translate(_, message: Message): + global to_translate + reply_msg = message.reply_to_message + if not reply_msg: + await message.reply_text("Reply to a message to translate it!") + return + if reply_msg.caption: + to_translate = reply_msg.caption + elif reply_msg.text: + to_translate = reply_msg.text + try: + args = message.text.split()[1].lower() + if "//" in args: + source = args.split("//")[0] + dest = args.split("//")[1] + else: + source = trans.detect(to_translate) + dest = args + except IndexError: + source = trans.detect(to_translate) + dest = "en" + translation = trans(to_translate, sourcelang=source, targetlang=dest) + reply = "" + reply += f"Translated from {source} to {dest}:\n" + reply += f"{translation.text}\n" + try: + await message.reply_text(reply) + except Exception as e: + await message.reply_text(f"Error : {e}") \ No newline at end of file diff --git a/akn/nothing b/akn/nothing new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/akn/utils/base_sqlite.py b/akn/utils/base_sqlite.py new file mode 100755 index 0000000000000000000000000000000000000000..c03a5c87a559151ed3d6e30aa22cd7d39b0ffd4f --- /dev/null +++ b/akn/utils/base_sqlite.py @@ -0,0 +1,41 @@ +import sqlite3 + +conn = sqlite3.connect('bot_prefix.db') +cursor = conn.cursor() + +cursor.execute(''' + CREATE TABLE IF NOT EXISTS prefixes ( + user_id INTEGER PRIMARY KEY, + prefix TEXT NOT NULL + ) +''') + +conn.commit() +conn.close() + +async def set_prefix_in_db(user_id: int, prefix: str): + conn = sqlite3.connect('bot_prefix.db') + cursor = conn.cursor() + + cursor.execute(''' + INSERT INTO prefixes (user_id, prefix) + VALUES (?, ?) + ON CONFLICT(user_id) DO UPDATE SET prefix=excluded.prefix + ''', (user_id, prefix)) + + conn.commit() + conn.close() + +async def get_prefix(user_id: int): + conn = sqlite3.connect('bot_prefix.db') + cursor = conn.cursor() + + cursor.execute('SELECT prefix FROM prefixes WHERE user_id=?', (user_id,)) + result = cursor.fetchone() + + conn.close() + + if result: + return result[0] + else: + return None \ No newline at end of file diff --git a/akn/utils/chat.py b/akn/utils/chat.py new file mode 100755 index 0000000000000000000000000000000000000000..f8eed8d0de56da381dfcab80867cd26150325756 --- /dev/null +++ b/akn/utils/chat.py @@ -0,0 +1,44 @@ +#!/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 . + +from datetime import datetime as dt + +from g4f.client import Client as Clients_g4f + +from akn.utils.logger import LOGS + +owner_base = f""" +Your name is Randy Dev. A kind and friendly AI assistant that answers in +a short and concise answer. Give short step-by-step reasoning if required. + +- Powered by @xtdevs on telegram +Today is {dt.now():%A %d %B %Y %H:%M} +""" + +async def chat_message(question): + clients_x = Clients_g4f() + response = clients_x.chat.completions.create( + model="gpt-4o", + messages=[ + {"role": "system", "content": owner_base}, + {"role": "user", "content": question} + ], + ) + messager = response.choices[0].message.content + return messager diff --git a/akn/utils/database.py b/akn/utils/database.py new file mode 100755 index 0000000000000000000000000000000000000000..52ac37fee637f39b65ca295df883205e84a2b6e1 --- /dev/null +++ b/akn/utils/database.py @@ -0,0 +1,1099 @@ +import datetime +import time +import markdown +import smtplib +from motor import motor_asyncio +from motor.core import AgnosticClient +from motor.motor_asyncio import AsyncIOMotorClient + +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText + +from config import * +from akn.utils.logger import LOGS + +client_tiktok = AsyncIOMotorClient(MONGO_URL) +db_tiktok = client_tiktok["tiktokbot"] +otp_collection = db_tiktok["otps"] + +async def send_check_otp_email(receiver_email, text): + try: + smtp_server = "smtp.gmail.com" + port = 587 + sender_email = ME_GMAIL + password = ME_GMAIL_PASSWORD + msg = MIMEMultipart() + msg['From'] = 'Akeno AI ' + msg['To'] = receiver_email + msg['Subject'] = "Verified OTP- Akeno AI API" + html = markdown.markdown(text) + msg.attach(MIMEText(html, 'html')) + server = smtplib.SMTP(smtp_server, port) + server.starttls() + server.login(sender_email, password) + server.sendmail(sender_email, receiver_email, msg.as_string()) + server.quit() + LOGS.info("Email sent successfully!") + except Exception: + pass + +class Database: + def __init__(self, uri: str) -> None: + self.client: AgnosticClient = motor_asyncio.AsyncIOMotorClient(uri) + self.db = self.client["Akeno"] + + # tiktok bot + self.db_tiktok = self.client["tiktokbot"] + self.magic_bot = self.db_tiktok["magicbot"] + self.gemini_bot = self.db_tiktok["geminibot"] + self.gpt_4_bot = self.db_tiktok["gpt_4_bot"] + self.meta_bot = self.db_tiktok["metabot"] + self.youtube_bot = self.db_tiktok["youtubebot"] + self.session_bot = self.db_tiktok["sessionbot"] + self.captcha_bot = self.db_tiktok["captchabot"] + self.alldl_bot = self.db_tiktok["alldlbot"] + self.privary_bot = self.db_tiktok["privarybot"] + self.maintance_bot = self.db_tiktok["maintancebot"] + + # akeno + self.afk = self.db["afk"] + self.antiflood = self.db["antiflood"] + self.autopost = self.db["autopost"] + self.blacklist = self.db["blacklist"] + self.echo = self.db["echo"] + self.env = self.db["env"] + self.filter = self.db["filter"] + self.forcesub = self.db["forcesub"] + self.gachabots = self.db["gachabots"] + self.cohere = self.db["cohere"] + self.chatbot = self.db["chatbot"] + self.backup_chatbot = self.db["backupchatbot"] + self.antiarabic = self.db["antiarabic"] + self.gban = self.db["gban"] + self.gmute = self.db["gmute"] + self.greetings = self.db["greetings"] + self.mute = self.db["mute"] + self.pmpermit = self.db["pmpermit"] + self.session = self.db["session"] + self.snips = self.db["snips"] + self.stan_users = self.db["stan_users"] + self.expired_users = self.db["expired_users"] + + async def connect(self): + try: + await self.client.admin.command("ping") + LOGS.info(f"Database Connection Established!") + except Exception as e: + LOGS.info(f"DatabaseErr: {e} ") + quit(1) + + async def _close(self): + await self.client.close() + + def get_datetime(self) -> str: + return datetime.datetime.now().strftime("%d/%m/%Y - %H:%M") + + async def claim_privacy_policy(self, user_id): + return await self.privary_bot.update_one( + {"user_id": user_id}, + {"$set": {"is_claimed": True}}, + upsert=True + ) + + async def set_pic_in_allbot(self, id, link, is_pic): + return await self.privary_bot.update_one( + {"bot_id": id}, + {"$set": {"link_pic": link, "is_pic": is_pic}}, + upsert=True + ) + + async def get_pic_in_allbot(self, id): + user_data = await self.privary_bot.find_one({"bot_id": id}) + if user_data: + return user_data.get("is_pic"), user_data.get("link_pic") + return False, None + + async def fixed_maintance(self, is_maintance): + return await self.maintance_bot.update_one( + {"bot_id": 1}, + {"$set": {"is_maintance": is_maintance}}, + upsert=True + ) + + async def get_maintance(self): + user_data = await self.maintance_bot.find_one({"bot_id": 1}) + return user_data.get("is_maintance") if user_data else False + + async def get_privacy_policy(self, user_id): + user_data = await self.privary_bot.find_one({"user_id": user_id}) + return user_data.get("is_claimed") if user_data else None + + async def remove_bot_token_magic(self, user_id): + remove_bot_clone = { + "bot_token": None, + "user_id": user_id + } + return await self.magic_bot.update_one({"user_id": user_id}, {"$unset": remove_bot_clone}) + + async def remove_expired_date(self, user_id): + remove_filter = {"expire_date": None} + return await self.expired_users.update_one({"user_id": user_id}, {"$unset": remove_filter}) + + async def get_expired_date(self, user_id): + user = await self.expired_users.find_one({"user_id": user_id}) + if user: + return user + else: + return None + + async def set_expired_date( + self, + user_id, + first_name, + username, + expire_date, + bot_token, + client_name, + disconnected: bool = False + ): + add_expired = { + "expire_date": expire_date, + "first_name": first_name, + "username": username, + "user_id": user_id, + "user_client": { + "bot_token": bot_token, + "client_name": client_name, + "disconnected": disconnected + } + } + return await self.expired_users.update_one( + {"user_id": user_id}, + {"$set": add_expired}, + upsert=True + ) + + async def set_env(self, name: str, value: str) -> None: + await self.env.update_one( + {"name": name}, {"$set": {"value": value}}, upsert=True + ) + + async def get_env(self, name: str) -> str | None: + if await self.is_env(name): + data = await self.env.find_one({"name": name}) + return data["value"] + return None + + async def rm_env(self, name: str) -> None: + await self.env.delete_one({"name": name}) + + async def is_env(self, name: str) -> bool: + if await self.env.find_one({"name": name}): + return True + return False + + async def get_all_env(self) -> list: + return [i async for i in self.env.find({})] + + async def is_stan(self, client: int, user_id: int) -> bool: + if await self.stan_users.find_one({"client": client, "user_id": user_id}): + return True + return False + + async def add_stan(self, client: int, user_id: int) -> bool: + if await self.is_stan(client, user_id): + return False + await self.stan_users.insert_one( + {"client": client, "user_id": user_id, "date": self.get_datetime()} + ) + return True + + async def rm_stan(self, client: int, user_id: int) -> bool: + if not await self.is_stan(client, user_id): + return False + await self.stan_users.delete_one({"client": client, "user_id": user_id}) + return True + + async def get_stans(self, client: int) -> list: + return [i async for i in self.stan_users.find({"client": client})] + + async def get_all_stans(self) -> list: + return [i async for i in self.stan_users.find({})] + + async def is_session(self, user_id: int) -> bool: + if await self.session.find_one({"user_id": user_id}): + return True + return False + + async def update_session( + self, + user_id: int, + api_id: int, + api_hash: str, + session: str, + email: str, + phone_number: str, + verified_password=None + ) -> None: + await self.session.update_one( + {"user_id": user_id}, + {"$set": { + "session": session, + "api_id": api_id, + "api_hash": api_hash, + "email": email, + "phone_number": phone_number, + "verified_password": verified_password, + "date": self.get_datetime()} + }, + upsert=True + ) + + async def rm_session(self, user_id: int) -> None: + await self.session.delete_one({"user_id": user_id}) + + async def get_session(self, user_id: int): + if not await self.is_session(user_id): + return False + data = await self.session.find_one({"user_id": user_id}) + return data + + async def add_bot_token_meta(self, user_id, bot_token): + add_bot_clone = { + "bot_token": bot_token, + "user_id": user_id + } + return await self.meta_bot.update_one({"user_id": user_id}, {"$set": add_bot_clone}, upsert=True) + + async def get_all_sessions(self) -> list: + return [i async for i in self.session.find({})] + + async def get_all_meta_bot(self) -> list: + return [i async for i in self.meta_bot.find({})] + + async def get_all_magic_bot(self) -> list: + return [i async for i in self.magic_bot.find({})] + + async def get_all_gemini_bot(self) -> list: + return [i async for i in self.gemini_bot.find({})] + + async def get_all_youtube_bot(self) -> list: + return [i async for i in self.youtube_bot.find({})] + + async def get_all_session_bot(self) -> list: + return [i async for i in self.session_bot.find({})] + + async def get_all_captcha_bot(self) -> list: + return [i async for i in self.captcha_bot.find({})] + + async def get_all_alldl_bot(self) -> list: + return [i async for i in self.alldl_bot.find({})] + + async def get_alldlbot_by_user_id(self, user_id): + user_data = await self.alldl_bot.find_one({"user_id": user_id}) + return True if user_data else False + + async def get_alldlbot_by_no_button(self, id): + user_data = await self.alldl_bot.find_one({"bot_id": id}) + if not user_data: + return False + return user_data.get("is_rm_button", False) + + ############################################# + + async def remove_strings_userv(self, user: int) -> bool: + if not user: + LOGS.error(f"Invalid session User format: {type(user)}") + return False + try: + result = await self.session.delete_one({"user_id": user}) + if result.deleted_count == 1: + LOGS.info(f"Session User deleted: {user}") + return True + LOGS.warning(f"Session User not found: {user}...") + return False + except Exception as e: + LOGS.critical(f"Deletion failed for {user}...: {str(e)}") + return False + + async def remove_bot_token_meta(self, bot_token: str) -> bool: + if not bot_token or not isinstance(bot_token, str): + LOGS.error(f"Invalid token format: {type(bot_token)}") + return False + try: + result = await self.meta_bot.delete_one({"bot_token": bot_token}) + if result.deleted_count == 1: + LOGS.info(f"Token deleted: {bot_token[:6]}...{bot_token[-3:]}") + return True + LOGS.warning(f"Token not found: {bot_token[:6]}...") + return False + except Exception as e: + LOGS.critical(f"Deletion failed for {bot_token[:6]}...: {str(e)}") + return False + + async def remove_bot_token_magic(self, bot_token: str) -> bool: + if not bot_token or not isinstance(bot_token, str): + LOGS.error(f"Invalid token format: {type(bot_token)}") + return False + try: + result = await self.magic_bot.delete_one({"bot_token": bot_token}) + if result.deleted_count == 1: + LOGS.info(f"Token deleted: {bot_token[:6]}...{bot_token[-3:]}") + return True + LOGS.warning(f"Token not found: {bot_token[:6]}...") + return False + except Exception as e: + LOGS.critical(f"Deletion failed for {bot_token[:6]}...: {str(e)}") + return False + + async def remove_bot_token_youtube(self, bot_token: str) -> bool: + if not bot_token or not isinstance(bot_token, str): + LOGS.error(f"Invalid token format: {type(bot_token)}") + return False + try: + result = await self.youtube_bot.delete_one({"bot_token": bot_token}) + if result.deleted_count == 1: + LOGS.info(f"Token deleted: {bot_token[:6]}...{bot_token[-3:]}") + return True + LOGS.warning(f"Token not found: {bot_token[:6]}...") + return False + except Exception as e: + LOGS.critical(f"Deletion failed for {bot_token[:6]}...: {str(e)}") + return False + + async def remove_bot_token_sessionbot(self, bot_token: str) -> bool: + if not bot_token or not isinstance(bot_token, str): + LOGS.error(f"Invalid token format: {type(bot_token)}") + return False + try: + result = await self.session_bot.delete_one({"bot_token": bot_token}) + if result.deleted_count == 1: + LOGS.info(f"Token deleted: {bot_token[:6]}...{bot_token[-3:]}") + return True + LOGS.warning(f"Token not found: {bot_token[:6]}...") + return False + except Exception as e: + LOGS.critical(f"Deletion failed for {bot_token[:6]}...: {str(e)}") + return False + + async def remove_bot_token_gemini(self, bot_token: str) -> bool: + if not bot_token or not isinstance(bot_token, str): + LOGS.error(f"Invalid token format: {type(bot_token)}") + return False + try: + result = await self.gemini_bot.delete_one({"bot_token": bot_token}) + if result.deleted_count == 1: + LOGS.info(f"Token deleted: {bot_token[:6]}...{bot_token[-3:]}") + return True + LOGS.warning(f"Token not found: {bot_token[:6]}...") + return False + except Exception as e: + LOGS.critical(f"Deletion failed for {bot_token[:6]}...: {str(e)}") + return False + + async def remove_bot_token_alldlbot(self, bot_token: str) -> bool: + if not bot_token or not isinstance(bot_token, str): + LOGS.error(f"Invalid token format: {type(bot_token)}") + return False + try: + result = await self.alldl_bot.delete_one({"bot_token": bot_token}) + if result.deleted_count == 1: + LOGS.info(f"Token deleted: {bot_token[:6]}...{bot_token[-3:]}") + return True + LOGS.warning(f"Token not found: {bot_token[:6]}...") + return False + except Exception as e: + LOGS.critical(f"Deletion failed for {bot_token[:6]}...: {str(e)}") + return False + + ############################################# + + async def update_alldlbot_broadcast(self, id, user_id, action): + if action == "add": + update_query = {"$addToSet": {"stats_bc": user_id}} + elif action == "remove": + update_query = {"$pull": {"stats_bc": user_id}} + else: + raise ValueError("Invalid action. Use 'add' or 'remove'.") + return await self.alldl_bot.update_one( + {"bot_id": id}, + update_query, + upsert=True if action == "add" else False + ) + + async def update_alldlbot_sudouser(self, id, user, action): + if action == "add": + update_query = {"$addToSet": {"sudo_user": user}} + elif action == "remove": + update_query = {"$pull": {"sudo_user": user}} + else: + raise ValueError("Invalid action. Use 'add' or 'remove'.") + return await self.alldl_bot.update_one( + {"bot_id": id}, + update_query, + upsert=True if action == "add" else False + ) + + async def get_alldlbot_sudouser(self, id, user_id): + user_data = await self.alldl_bot.find_one({"bot_id": id}) + if not user_data or "sudo_user" not in user_data: + return [] + return user_id in user_data["sudo_user"] + + async def get_alldlbot_allsudouser(self, id: int): + y = await self.alldl_bot.find_one({"bot_id": id}) + if not y or "sudo_user" not in y: + return [] + return y["blacklist_chat"] + + async def update_alldlbot_broadcast_in_group(self, id, chat, action): + if action == "add": + update_query = {"$addToSet": {"stats_gc": chat}} + elif action == "remove": + update_query = {"$pull": {"stats_gc": chat}} + else: + raise ValueError("Invalid action. Use 'add' or 'remove'.") + return await self.alldl_bot.update_one( + {"bot_id": id}, + update_query, + upsert=True if action == "add" else False + ) + + async def alldlbot_broadcast_stats(self, id): + user_data = await self.alldl_bot.find_one({"bot_id": id}) + return len(user_data["stats_bc"]) if user_data and "stats_bc" in user_data else 0 + + async def alldlbot_all_broadcast(self, id): + user_data = await self.alldl_bot.find_one({"bot_id": id}) + return user_data["stats_bc"] + + async def alldlbot_all_broadcast_group(self, id): + user_data = await self.alldl_bot.find_one({"bot_id": id}) + return user_data["stats_gc"] + + async def alldlbot_blacklist_stats(self, id): + user_data = await self.alldl_bot.find_one({"bot_id": id}) + return len(user_data["blacklist_user"]) if user_data and "blacklist_user" in user_data else 0 + + async def get_alldlbot_is_blacklist_user(self, id: int, user_id: int) -> bool: + data = await self.get_alldlbot_blacklist_user(id) + if not data or "blacklist_user" not in data: + return False + return user_id in data["blacklist_user"] + + async def get_alldlbot_blacklist_user(self, id: int): + return await self.alldl_bot.find_one({"bot_id": id}) + + async def get_alldlbot_allblacklist_user(self, id: int): + data = await self.get_alldlbot_blacklist_user(id) + if not data or "blacklist_user" not in data: + return [] + return data["blacklist_user"] + + async def add_alldlbot_blacklist_user(self, id, user_id): + return await self.alldl_bot.update_one( + {"bot_id": id}, + {"$push": {"blacklist_user": user_id}}, + upsert=True + ) + + async def add_alldlbot_unblacklist_user(self, id, user_id): + return await self.alldl_bot.update_one( + {"bot_id": id}, + {"$pull": {"blacklist_user": user_id}} + ) + + async def add_alldlbot_blacklist_chat(self, id, chat): + return await self.alldl_bot.update_one( + {"bot_id": id}, + {"$push": {"blacklist_chat": chat}}, + upsert=True + ) + + async def get_alldlbot_blacklist_chat(self, id: int): + chat = await self.alldl_bot.find_one({"bot_id": id}) + if not chat or "blacklist_chat" not in chat: + return [] + return chat["blacklist_chat"] + + async def get_alldlbot_is_blacklist_chat(self, id: int, chat_id: int) -> bool: + data = await self.get_alldlbot_blacklist_chat(id) + return chat_id in data + + async def alldlbot_whitelist_chat(self, id: int, chat_id: int) -> bool: + chat = await self.alldl_bot.find_one({"bot_id": id}) + if chat and "blacklist_chat" in chat and chat_id in chat["blacklist_chat"]: + await self.alldl_bot.update_one( + {"bot_id": id}, + {"$pull": {"blacklist_chat": chat_id}} + ) + return True + return False + + async def add_alldlbot_by_no_button(self, id, is_rm_button=False): + _ups = {"is_rm_button": is_rm_button} + return await self.alldl_bot.update_one({"bot_id": id}, {"$set": _ups}, upsert=True) + + async def is_gbanned(self, user_id: int) -> bool: + if await self.gban.find_one({"user_id": user_id}): + return True + return False + + async def add_gban(self, user_id: int, reason: str) -> bool: + if await self.is_gbanned(user_id): + return False + await self.gban.insert_one( + {"user_id": user_id, "reason": reason, "date": self.get_datetime()} + ) + return True + + async def rm_gban(self, user_id: int): + if not await self.is_gbanned(user_id): + return None + reason = (await self.gban.find_one({"user_id": user_id}))["reason"] + await self.gban.delete_one({"user_id": user_id}) + return reason + + async def get_gban(self) -> list: + return [i async for i in self.gban.find({})] + + async def get_gban_user(self, user_id: int) -> dict | None: + if not await self.is_gbanned(user_id): + return None + return await self.gban.find_one({"user_id": user_id}) + + async def is_gmuted(self, user_id: int) -> bool: + if await self.gmute.find_one({"user_id": user_id}): + return True + return False + + async def add_gmute(self, user_id: int, reason: str) -> bool: + if await self.is_gmuted(user_id): + return False + await self.gmute.insert_one( + {"user_id": user_id, "reason": reason, "date": self.get_datetime()} + ) + return True + + async def rm_gmute(self, user_id: int): + if not await self.is_gmuted(user_id): + return None + reason = (await self.gmute.find_one({"user_id": user_id}))["reason"] + await self.gmute.delete_one({"user_id": user_id}) + return reason + + async def get_gmute(self) -> list: + return [i async for i in self.gmute.find({})] + + async def add_mute(self, client: int, user_id: int, chat_id: int, reason: str): + await self.mute.update_one( + {"client": client, "user_id": user_id, "chat_id": chat_id}, + {"$set": {"reason": reason, "date": self.get_datetime()}}, + upsert=True, + ) + + async def rm_mute(self, client: int, user_id: int, chat_id: int) -> str: + reason = (await self.get_mute(client, user_id, chat_id))["reason"] + await self.mute.delete_one({"client": client, "user_id": user_id, "chat_id": chat_id}) + return reason + + async def is_muted(self, client: int, user_id: int, chat_id: int) -> bool: + if await self.get_mute(client, user_id, chat_id): + return True + return False + + async def get_mute(self, client: int, user_id: int, chat_id: int): + data = await self.mute.find_one({"client": client, "user_id": user_id, "chat_id": chat_id}) + return data + + async def set_afk( + self, user_id: int, reason: str, media: int, media_type: str + ) -> None: + await self.afk.update_one( + {"user_id": user_id}, + { + "$set": { + "reason": reason, + "time": time.time(), + "media": media, + "media_type": media_type, + } + }, + upsert=True, + ) + + async def get_afk(self, user_id: int): + data = await self.afk.find_one({"user_id": user_id}) + return data + + async def is_afk(self, user_id: int) -> bool: + if await self.afk.find_one({"user_id": user_id}): + return True + return False + + async def rm_afk(self, user_id: int) -> None: + await self.afk.delete_one({"user_id": user_id}) + + async def set_flood(self, client_chat: tuple[int, int], settings: dict): + await self.antiflood.update_one( + {"client": client_chat[0], "chat": client_chat[1]}, + {"$set": settings}, + upsert=True, + ) + + async def get_flood(self, client_chat: tuple[int, int]): + data = await self.antiflood.find_one( + {"client": client_chat[0], "chat": client_chat[1]} + ) + return data or {} + + async def is_flood(self, client_chat: tuple[int, int]) -> bool: + data = await self.get_flood(client_chat) + + if not data: + return False + + if data["limit"] == 0: + return False + + return True + + async def get_all_floods(self) -> list: + return [i async for i in self.antiflood.find({})] + + async def set_autopost(self, client: int, from_channel: int, to_channel: int): + await self.autopost.update_one( + {"client": client}, + { + "$push": { + "autopost": { + "from_channel": from_channel, + "to_channel": to_channel, + "date": self.get_datetime(), + } + } + }, + upsert=True, + ) + + async def get_autopost(self, client: int, from_channel: int): + data = await self.autopost.find_one( + { + "client": client, + "autopost": {"$elemMatch": {"from_channel": from_channel}}, + } + ) + return data + + async def is_autopost( + self, client: int, from_channel: int, to_channel: int = None + ) -> bool: + if to_channel: + data = await self.autopost.find_one( + { + "client": client, + "autopost": { + "$elemMatch": { + "from_channel": from_channel, + "to_channel": to_channel, + } + }, + } + ) + else: + data = await self.autopost.find_one( + { + "client": client, + "autopost": {"$elemMatch": {"from_channel": from_channel}}, + } + ) + return True if data else False + + async def rm_autopost(self, client: int, from_channel: int, to_channel: int): + await self.autopost.update_one( + {"client": client}, + { + "$pull": { + "autopost": { + "from_channel": from_channel, + "to_channel": to_channel, + } + } + }, + ) + + async def get_all_autoposts(self, client: int) -> list: + return [i async for i in self.autopost.find({"client": client})] + + async def add_blacklist(self, client: int, chat: int, blacklist: str): + await self.blacklist.update_one( + {"client": client, "chat": chat}, + {"$push": {"blacklist": blacklist}}, + upsert=True, + ) + + async def rm_blacklist(self, client: int, chat: int, blacklist: str): + await self.blacklist.update_one( + {"client": client, "chat": chat}, + {"$pull": {"blacklist": blacklist}}, + ) + + async def is_blacklist(self, client: int, chat: int, blacklist: str) -> bool: + blacklists = await self.get_all_blacklists(client, chat) + if blacklist in blacklists: + return True + return False + + async def get_all_blacklists(self, client: int, chat: int) -> list: + data = await self.blacklist.find_one({"client": client, "chat": chat}) + + if not data: + return [] + + return data["blacklist"] + + async def get_blacklist_clients(self) -> list: + return [i async for i in self.blacklist.find({})] + + async def set_echo(self, client: int, chat: int, user: int): + await self.echo.update_one( + {"client": client, "chat": chat}, + {"$push": {"echo": user}}, + upsert=True, + ) + + async def rm_echo(self, client: int, chat: int, user: int): + await self.echo.update_one( + {"client": client, "chat": chat}, + {"$pull": {"echo": user}}, + ) + + async def is_echo(self, client: int, chat: int, user: int) -> bool: + data = await self.get_all_echo(client, chat) + if user in data: + return True + return False + + async def get_all_echo(self, client: int, chat: int) -> list: + data = await self.echo.find_one({"client": client, "chat": chat}) + + if not data: + return [] + + return data["echo"] + + async def set_filter(self, client: int, chat: int, keyword: str, msgid: int): + await self.filter.update_one( + {"client": client, "chat": chat}, + {"$push": {"filter": {"keyword": keyword, "msgid": msgid}}}, + upsert=True, + ) + + async def rm_filter(self, client: int, chat: int, keyword: str): + await self.filter.update_one( + {"client": client, "chat": chat}, + {"$pull": {"filter": {"keyword": keyword}}}, + ) + + async def rm_all_filters(self, client: int, chat: int): + await self.filter.delete_one({"client": client, "chat": chat}) + + async def is_filter(self, client: int, chat: int, keyword: str) -> bool: + data = await self.get_filter(client, chat, keyword) + return True if data else False + + async def get_filter(self, client: int, chat: int, keyword: str): + data = await self.filter.find_one( + { + "client": client, + "chat": chat, + "filter": {"$elemMatch": {"keyword": keyword}}, + } + ) + return data + + async def get_all_filters(self, client: int, chat: int) -> list: + data = await self.filter.find_one({"client": client, "chat": chat}) + + if not data: + return [] + + return data["filter"] + + async def set_snip(self, client: int, chat: int, keyword: str, msgid: int): + await self.snips.update_one( + {"client": client, "chat": chat}, + {"$push": {"snips": {"keyword": keyword, "msgid": msgid}}}, + upsert=True, + ) + + async def rm_snip(self, client: int, chat: int, keyword: str): + await self.snips.update_one( + {"client": client, "chat": chat}, + {"$pull": {"snips": {"keyword": keyword}}}, + ) + + async def rm_all_snips(self, client: int, chat: int): + await self.snips.delete_one({"client": client, "chat": chat}) + + async def is_snip(self, client: int, chat: int, keyword: str) -> bool: + data = await self.get_snip(client, chat, keyword) + return True if data else False + + async def get_snip(self, client: int, chat: int, keyword: str): + data = await self.snips.find_one( + { + "client": client, + "chat": chat, + "snips": {"$elemMatch": {"keyword": keyword}}, + } + ) + return data + + async def get_all_snips(self, client: int, chat: int) -> list: + data = await self.snips.find_one({"client": client, "chat": chat}) + + if not data: + return [] + + return data["snips"] + + async def add_pmpermit(self, client: int, user: int): + await self.pmpermit.update_one( + {"client": client, "user": user}, + {"$set": {"date": self.get_datetime()}}, + upsert=True, + ) + + async def rm_pmpermit(self, client: int, user: int): + await self.pmpermit.delete_one({"client": client, "user": user}) + + async def is_pmpermit(self, client: int, user: int) -> bool: + data = await self.get_pmpermit(client, user) + return True if data else False + + async def get_pmpermit(self, client: int, user: int): + data = await self.pmpermit.find_one({"client": client, "user": user}) + return data + + async def get_all_pmpermits(self, client: int) -> list: + return [i async for i in self.pmpermit.find({"client": client})] + + async def set_welcome(self, client: int, chat: int, message: int): + await self.greetings.update_one( + {"client": client, "chat": chat, "welcome": True}, + {"$set": {"message": message}}, + upsert=True, + ) + + async def rm_welcome(self, client: int, chat: int): + await self.greetings.delete_one( + {"client": client, "chat": chat, "welcome": True} + ) + + async def is_welcome(self, client: int, chat: int) -> bool: + data = await self.get_welcome(client, chat) + return True if data else False + + async def get_welcome(self, client: int, chat: int): + data = await self.greetings.find_one( + {"client": client, "chat": chat, "welcome": True} + ) + return data + + async def set_goodbye(self, client: int, chat: int, message: int): + await self.greetings.update_one( + {"client": client, "chat": chat, "welcome": False}, + {"$set": {"message": message}}, + upsert=True, + ) + + async def rm_goodbye(self, client: int, chat: int): + await self.greetings.delete_one( + {"client": client, "chat": chat, "welcome": False} + ) + + async def is_goodbye(self, client: int, chat: int) -> bool: + data = await self.get_goodbye(client, chat) + return True if data else False + + async def get_goodbye(self, client: int, chat: int): + data = await self.greetings.find_one( + {"client": client, "chat": chat, "welcome": False} + ) + return data + + async def get_all_greetings(self, client: int) -> list: + return [i async for i in self.greetings.find({"client": client})] + + async def add_forcesub_only_bot(self, id: int, must_join: str): + await self.forcesub.update_one( + {"bot_id": id}, + {"$set": {"must_join": must_join}}, + upsert=True, + ) + + async def get_forcesub_only_bot(self, id: int): + data = await self.forcesub.find_one({"bot_id": id}) + if data: + return data.get("must_join") + return None + + async def add_forcesub(self, chat: int, must_join: int): + await self.forcesub.update_one( + {"chat": chat}, + {"$push": {"must_join": must_join}}, + upsert=True, + ) + + async def rm_forcesub(self, chat: int, must_join: int) -> int: + await self.forcesub.update_one( + {"chat": chat}, + {"$pull": {"must_join": must_join}}, + ) + data = await self.forcesub.find_one({"chat": chat}) + return len(data["must_join"]) + + async def rm_all_forcesub(self, in_chat: int): + await self.forcesub.delete_one({"chat": in_chat}) + + async def is_forcesub(self, chat: int, must_join: int) -> bool: + data = await self.get_forcesub(chat) + if must_join in data["must_join"]: + return True + return False + + async def get_forcesub(self, in_chat: int): + data = await self.forcesub.find_one({"chat": in_chat}) + return data + + async def get_all_forcesubs(self) -> list: + return [i async for i in self.forcesub.find({})] + + async def add_gachabot( + self, client: int, bot: tuple[int, str], catch_command: str, chat_id: int + ): + await self.gachabots.update_one( + {"client": client, "bot": bot[0]}, + { + "$set": { + "username": bot[1], + "catch_command": catch_command, + "chat_id": chat_id, + "date": self.get_datetime(), + } + }, + upsert=True, + ) + + async def rm_gachabot(self, client: int, bot: int, chat_id: int = None): + if chat_id: + await self.gachabots.delete_one( + {"client": client, "bot": bot, "chat_id": chat_id} + ) + else: + await self.gachabots.delete_one({"client": client, "bot": bot}) + + async def is_gachabot(self, client: int, bot: int, chat_id: int) -> bool: + data = await self.get_gachabot(client, bot, chat_id) + return True if data else False + + async def get_gachabot(self, client: int, bot: int, chat_id: int): + data = await self.gachabots.find_one( + {"client": client, "bot": bot, "chat_id": chat_id} + ) + + return data + + async def get_all_gachabots(self, client: int) -> list: + return [i async for i in self.gachabots.find({"client": client})] + + async def get_all_gachabots_id(self) -> list: + data = await self.gachabots.distinct("bot") + return data + + async def _get_cohere_chat_from_db(self, user_id): + user_data = await self.cohere.find_one({"user_id": user_id}) + return user_data.get("cohere_chat", []) if user_data else [] + + async def _update_cohere_chat_in_db(self, user_id, cohere_chat): + await self.cohere.update_one( + {"user_id": user_id}, + {"$set": {"cohere_chat": cohere_chat}}, + upsert=True + ) + + async def _clear_history_in_db(self, user_id): + unset_clear = {"cohere_chat": None} + return await self.cohere.update_one({"user_id": user_id}, {"$unset": unset_clear}) + + async def clear_database(self, user_id): + """Clear the cohere history for the current user.""" + result = await self._clear_history_in_db(user_id) + if result.modified_count > 0: + return "Chat history cleared successfully." + else: + return "No chat history found to clear." + + async def set_chat_setting(self, chat_id, isboolean): + await self.antiarabic.update_one( + {"chat_id": chat_id}, + {"$set": {"arabic": isboolean}}, + upsert=True + ) + + async def chat_antiarabic(self, chat_id): + user_data = await self.antiarabic.find_one({"chat_id": chat_id}) + if user_data: + return user_data.get("arabic", False) + return False + + async def add_chatbot(self, chat_id, user_id): + await self.chatbot.update_one( + {"chat_id": chat_id}, + {"$set": {"user_id": user_id}}, + upsert=True + ) + + async def add_gpt_plan(self, user_id): + await self.gpt_4_bot.update_one( + {"user_id": user_id}, + {"$set": {"is_payment": True}}, + upsert=True + ) + + async def is_gpt_plan(self, user_id): + user_data = await self.gpt_4_bot.find_one({"user_id": user_id}) + return user_data.get("is_payment") if user_data else None + + async def get_chatbot(self, chat_id): + user_data = await self.chatbot.find_one({"chat_id": chat_id}) + return user_data.get("user_id") if user_data else None + + async def remove_chatbot(self, chat_id): + unset_data = {"user_id": None} + return await self.chatbot.update_one({"chat_id": chat_id}, {"$unset": unset_data}) + + async def _update_chatbot_chat_in_db(self, user_id, chatbot_chat): + await self.backup_chatbot.update_one( + {"user_id": user_id}, + {"$set": {"chatbot_chat": chatbot_chat}}, + upsert=True + ) + + async def _get_chatbot_chat_from_db(self, user_id): + user_data = await self.backup_chatbot.find_one({"user_id": user_id}) + return user_data.get("chatbot_chat", []) if user_data else [] + + async def _clear_chatbot_history_in_db(self, user_id): + unset_clear = {"chatbot_chat": None} + return await self.backup_chatbot.update_one({"user_id": user_id}, {"$unset": unset_clear}) + + async def _clear_chatbot_database(self, user_id): + result = await self._clear_chatbot_history_in_db(user_id) + if result.modified_count > 0: + return "Chat history cleared successfully." + else: + return "No chat history found to clear." + +db = Database(MONGO_URL) diff --git a/akn/utils/driver.py b/akn/utils/driver.py new file mode 100755 index 0000000000000000000000000000000000000000..ce2b2ded4427a2fbe7a7bbc831dcd9fe9a3d7b62 --- /dev/null +++ b/akn/utils/driver.py @@ -0,0 +1,147 @@ +import datetime +import json +import os +import random +import re +import time +import urllib.parse +from urllib.parse import quote_plus + +import httpx +import requests +from pytz import country_names, country_timezones, timezone +from akn.utils.database import db +from akn.utils.formatter import format_text + +class YoutubeDriver: + def __init__(self, search_terms: str, max_results: int = 5): + self.base_url = "https://youtube.com/results?search_query={0}" + self.search_terms = search_terms + self.max_results = max_results + self.videos = self._search() + + def _search(self): + encoded_search = urllib.parse.quote_plus(self.search_terms) + response = requests.get(self.base_url.format(encoded_search)).text + + while "ytInitialData" not in response: + response = requests.get(self.base_url.format(encoded_search)).text + + results = self._parse_html(response) + + if self.max_results is not None and len(results) > self.max_results: + return results[: self.max_results] + + return results + + def _parse_html(self, response: str): + results = [] + start = response.index("ytInitialData") + len("ytInitialData") + 3 + end = response.index("};", start) + 1 + json_str = response[start:end] + data = json.loads(json_str) + + videos = data["contents"]["twoColumnSearchResultsRenderer"]["primaryContents"][ + "sectionListRenderer" + ]["contents"][0]["itemSectionRenderer"]["contents"] + + for video in videos: + res = {} + if "videoRenderer" in video.keys(): + video_data = video.get("videoRenderer", {}) + _id = video_data.get("videoId", None) + + res["id"] = _id + res["thumbnail"] = f"https://i.ytimg.com/vi/{_id}/hqdefault.jpg" + res["title"] = ( + video_data.get("title", {}).get("runs", [[{}]])[0].get("text", None) + ) + res["channel"] = ( + video_data.get("longBylineText", {}) + .get("runs", [[{}]])[0] + .get("text", None) + ) + res["duration"] = video_data.get("lengthText", {}).get("simpleText", 0) + res["views"] = video_data.get("viewCountText", {}).get( + "simpleText", "Unknown" + ) + res["publish_time"] = video_data.get("publishedTimeText", {}).get( + "simpleText", "Unknown" + ) + res["url_suffix"] = ( + video_data.get("navigationEndpoint", {}) + .get("commandMetadata", {}) + .get("webCommandMetadata", {}) + .get("url", None) + ) + + results.append(res) + return results + + def to_dict(self, clear_cache=True) -> list[dict]: + result = self.videos + if clear_cache: + self.videos = [] + return result + + @staticmethod + def check_url(url: str) -> tuple[bool, str]: + if "&" in url: + url = url[: url.index("&")] + + if "?si=" in url: + url = url[: url.index("?si=")] + + youtube_regex = ( + r"(https?://)?(www\.)?" + r"(youtube|youtu|youtube-nocookie)\.(com|be)/" + r'(video|embed|shorts/|watch\?v=|v/|e/|u/\\w+/|\\w+/)?([^"&?\\s]{11})' + ) + match = re.match(youtube_regex, url) + if match: + return True, match.group(6) + else: + return False, "Invalid YouTube URL!" + + @staticmethod + def song_options() -> dict: + return { + "format": "bestaudio", + "addmetadata": True, + "key": "FFmpegMetadata", + "prefer_ffmpeg": True, + "geo_bypass": True, + "nocheckcertificate": True, + "postprocessors": [ + { + "key": "FFmpegExtractAudio", + "preferredcodec": "mp3", + "preferredquality": "480", + } + ], + "cookiefile": "cookies.txt", + "outtmpl": "%(id)s", + "quiet": True, + "logtostderr": False, + } + + @staticmethod + def video_options() -> dict: + return { + "format": "best", + "addmetadata": True, + "key": "FFmpegMetadata", + "prefer_ffmpeg": True, + "geo_bypass": True, + "nocheckcertificate": True, + "postprocessors": [ + { + "key": "FFmpegVideoConvertor", + "preferedformat": "mp4", + } + ], + "cookiefile": "cookies.txt", + "outtmpl": "%(id)s.mp4", + "quiet": True, + "logtostderr": False, + } diff --git a/akn/utils/expired_bot.py b/akn/utils/expired_bot.py new file mode 100755 index 0000000000000000000000000000000000000000..c42f317a3d39c007675a0bf60855b63450062393 --- /dev/null +++ b/akn/utils/expired_bot.py @@ -0,0 +1,102 @@ +import asyncio +from box import Box +from datetime import datetime as dt +from datetime import timedelta +from pytz import timezone +from pyrogram.types import * +from akn.utils.database import db +from akn.utils.logger import LOGS + +WHY_TRY_DO = """ +Hey, {user} + +Sorry, your bot {bot} has expired. + +You can upgrade to premium for an extended period: +- 1 month or 2 months of premium +- But don’t worry, you still get a free 7-day trial every week! + +If you're interested, feel free to purchase premium at any time! +""" + +reply_markup = InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="🆕 New expiry", + callback_data="expiredtt" + ) + ] + ] +) + +async def add_time_watch( + user_id, + first_name, + username, + bot_token, + client_name, + days, + disconnected: bool = False +): + try: + now = dt.now(timezone("Asia/Jakarta")) + expire_date = now + timedelta(days=days) + LOGS.info(f"Setting expiration time for user {user_id}: {expire_date}") + await db.set_expired_date( + user_id, + first_name, + username, + expire_date, + bot_token, + client_name, + disconnected + ) + except Exception as e: + LOGS.info(f"Error: {e}") + +async def watch_do_time(user_id, client, assistant): + while True: + now = dt.now(timezone("Asia/Jakarta")) + time = now.strftime("%d-%m-%Y") + + exp = await db.get_expired_date(user_id) + exp_obj = Box(exp or {}) + if not exp_obj: + await asyncio.sleep(30) + continue + expired_on = exp_obj.expire_date + if not expired_on: + await asyncio.sleep(30) + continue + if isinstance(expired_on, str): + expired_on = dt.strptime(expired_on, "%d-%m-%Y") + + if expired_on.tzinfo is None: + expired_on = timezone("Asia/Jakarta").localize(expired_on) + + LOGS.info(f"Expiration date for user {user_id}: {expired_on.strftime('%d-%m-%Y')}") + + if now >= expired_on: + send_mention = f"{exp_obj.first_name}" + await client.stop() + await assistant.send_message( + exp_obj.user_id, + WHY_TRY_DO.format( + user=send_mention, + bot=exp_obj.username + ) + ) + await db.set_expired_date( + user_id=exp_obj.user_id, + first_name=exp_obj.first_name, + username=exp_obj.username, + expire_date=None, + bot_token=exp_obj.user_client.bot_token, + client_name=exp_obj.user_client.client_name, + disconnected=True + ) + LOGS.info(f"bot {exp_obj.username} has expired") + break + else: + await asyncio.sleep(30) \ No newline at end of file diff --git a/akn/utils/formatter.py b/akn/utils/formatter.py new file mode 100755 index 0000000000000000000000000000000000000000..516ddbac4840639de35bac5c1e0d7ff4217eabd2 --- /dev/null +++ b/akn/utils/formatter.py @@ -0,0 +1,94 @@ +import math +import re + + +def format_text(text: str) -> str: + emoji_pattern = re.compile( + "[" + "\U0001F600-\U0001F64F" # emoticons + "\U0001F300-\U0001F5FF" # symbols & pictographs + "\U0001F680-\U0001F6FF" # transport & map symbols + "\U0001F700-\U0001F77F" # alchemical symbols + "\U0001F780-\U0001F7FF" # Geometric Shapes Extended + "\U0001F800-\U0001F8FF" # Supplemental Arrows-C + "\U0001F900-\U0001F9FF" # Supplemental Symbols and Pictographs + "\U0001FA00-\U0001FA6F" # Chess Symbols + "\U0001FA70-\U0001FAFF" # Symbols and Pictographs Extended-A + "\U00002702-\U000027B0" # Dingbats + "\U000024C2-\U0001F251" # enclosed characters + "]+", + flags=re.UNICODE, + ) + + return re.sub(emoji_pattern, "", text) + + +def superscript(text: str) -> str: + superscript_digits = str.maketrans("0123456789", "⁰¹²³⁴⁵⁶⁷⁸⁹") + return text.translate(superscript_digits) + + +def subscript(text: str) -> str: + subscript_digits = str.maketrans("0123456789", "₀₁₂₃₄₅₆₇₈₉") + return text.translate(subscript_digits) + + +def readable_time(seconds: int) -> str: + count = 0 + out_time = "" + time_list = [] + time_suffix_list = ["secs", "mins", "hrs", "days"] + + while count < 4: + count += 1 + remainder, result = divmod(seconds, 60) if count < 3 else divmod(seconds, 24) + if seconds == 0 and remainder == 0: + break + time_list.append(int(result)) + seconds = int(remainder) + + for x in range(len(time_list)): + time_list[x] = str(time_list[x]) + time_suffix_list[x] + + if len(time_list) == 4: + out_time += time_list.pop() + ", " + + time_list.reverse() + out_time += " ".join(time_list) + + return out_time or "0 secs" + + +def humanbytes(size: int): + if not size: + return "" + power = 2**10 + number = 0 + dict_power_n = {0: " ", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"} + while size > power: + size /= power + number += 1 + return str(round(size, 2)) + " " + dict_power_n[number] + "B" + + +def add_to_dict(data: dict, keys: list, value: str | int | bool = None) -> None: + current_level = data + for key in keys[:-1]: + current_level = current_level.setdefault(key, {}) + current_level[keys[-1]] = value + + +def get_from_dict(data: dict, key: list): + current_level = data + for k in key: + current_level = current_level[k] + return current_level + + +def limit_per_page(limit: int) -> int: + return math.ceil(limit / 10) + + +def secs_to_mins(secs: int) -> str: + mins, secs = divmod(secs, 60) + return f"{mins}:{secs}" diff --git a/akn/utils/gmail_verifed.py b/akn/utils/gmail_verifed.py new file mode 100755 index 0000000000000000000000000000000000000000..4ae60cdd52143e33d90b7e933e79857f34bfab50 --- /dev/null +++ b/akn/utils/gmail_verifed.py @@ -0,0 +1,56 @@ +import random +import string +from config import * +from akn.utils.database import * +from datetime import datetime, timedelta + +TEST_VIA_EMAIL_TEXT = """ +Your login code: {otp} Never give this code to anyone, +even if they say it is from **AkenoAi** +""" + +def generate_otp(length=6): + return ''.join(random.choices(string.digits, k=length)) + +async def store_otp(email: str, otp: str): + expiration_time = datetime.utcnow() + timedelta(minutes=5) + otp_data = { + "email": email, + "otp": otp, + "expires_at": expiration_time + } + await otp_collection.update_one( + {"email": email}, + {"$set": otp_data}, + upsert=True + ) + +async def verify_otp_in_db(email: str, otp: str): + otp_record = await otp_collection.find_one({"email": email}) + if otp_record and otp_record["otp"] == otp: + if otp_record["expires_at"] > datetime.utcnow(): + return True + return False + +async def email_send_otp(email: str): + otp = generate_otp() + if email == str(ME_GMAIL): + return {"message": f"can't be blacklisted"} + await store_otp(email, otp) + try: + await send_check_otp_email( + receiver_email=email, + text=TEST_VIA_EMAIL_TEXT.format( + otp=otp + ) + ) + return {"message": f"OTP sent to check your email"} + except Exception as e: + return {"message": f"Error: {e}"} + +async def email_verify_otp(email: str, otp: str): + is_valid = await verify_otp_in_db(email, otp) + if is_valid: + return {"message": "OTP verified successfully!"} + else: + return {"message": "Invalid or expired OTP"} diff --git a/akn/utils/handler.py b/akn/utils/handler.py new file mode 100755 index 0000000000000000000000000000000000000000..5b252c3be2e96b085a584b0f8aa04caf386d3a9e --- /dev/null +++ b/akn/utils/handler.py @@ -0,0 +1,30 @@ +import pathlib +from time import perf_counter + +from apscheduler.schedulers.asyncio import AsyncIOScheduler +from pyrogram import Client, filters +from pyrogram.enums import ChatType +from pyrogram.handlers import MessageHandler +from pyrogram.types import Message + +from akn.utils.helps import ModuleHelp + +group_only = [ChatType.GROUP, ChatType.SUPERGROUP] +Akeno = Client.on_message +Akeno_chat_member_updated = Client.on_chat_member_updated() +script_path = pathlib.Path(__file__).parent.parent +modules_help = ModuleHelp() +scheduler_jobs = [] +scheduler = AsyncIOScheduler() +bot_uptime = perf_counter() + +async def input_user(message: Message) -> str: + """Get the input from the user""" + if len(message.command) < 2: + output = "" + else: + try: + output = message.text.split(" ", 1)[1].strip() or "" + except IndexError: + output = "" + return output diff --git a/akn/utils/helps.py b/akn/utils/helps.py new file mode 100755 index 0000000000000000000000000000000000000000..716ceeab1d67b891c27fc8d7f0f99e034fd1d5cb --- /dev/null +++ b/akn/utils/helps.py @@ -0,0 +1,466 @@ +import asyncio +import logging +import os +import shlex +import sys +from typing import Dict, List, Optional, Tuple, Union + +import aiohttp +import arrow +from apscheduler.triggers.cron import CronTrigger +from apscheduler.triggers.interval import IntervalTrigger +from pyrogram import Client, enums, errors +from pyrogram.enums import ChatType +from pyrogram.session import Session +from pyrogram.storage import Storage +from pyrogram.types import Chat, Message, User + + +class CustomFormatter(logging.Formatter): + # Colors + black = "\x1b[30m" + red = "\x1b[31m" + green = "\x1b[32m" + yellow = "\x1b[33m" + blue = "\x1b[34m" + gray = "\x1b[38m" + # Styles + reset = "\x1b[0m" + bold = "\x1b[1m" + + COLORS = { + logging.DEBUG: gray + bold, + logging.INFO: blue + bold, + logging.WARNING: yellow + bold, + logging.ERROR: red, + logging.CRITICAL: red + bold, + } + + def format(self, record): + log_color = self.COLORS[record.levelno] + fmt = "(black){asctime}(reset) (levelcolor){levelname:<8}(reset) (green){name}(reset) {message}" + fmt = fmt.replace("(black)", self.black + self.bold) + fmt = fmt.replace("(reset)", self.reset) + fmt = fmt.replace("(levelcolor)", log_color) + fmt = fmt.replace("(green)", self.green + self.bold) + formatter = logging.Formatter(fmt, "%Y-%m-%d %H:%M:%S", style="{") + return formatter.format(record) + +def get_full_name(obj: Union[User, Chat]) -> str: + if isinstance(obj, Chat): + if obj.type == ChatType.PRIVATE: + return f"{obj.first_name} {obj.last_name}" if obj.last_name else obj.first_name + return obj.title + elif isinstance(obj, User): + return f"{obj.first_name} {obj.last_name}" if obj.last_name else obj.first_name + else: + raise TypeError("obj must be User or Chat") + +def format_exc(e: Exception, suffix="") -> str: + if isinstance(e, errors.RPCError): + return ( + f"Telegram API error!\n" + f"[{e.CODE} {e.ID or e.NAME}] — {e.MESSAGE.format(value=e.value)}\n\n" + f"{suffix}" + ) + return f"{e.__class__.__name__}: {e}\n\n{suffix}" + +def with_reply(func): + async def wrapped(client: Client, message: Message): + if not message.reply_to_message: + await message.edit("Reply to message is required") + else: + return await func(client, message) + + return wrapped + +def with_args(text: str): + def decorator(func): + async def wrapped(client: Client, message: Message): + if message.text and len(message.text.split()) == 1: + await message.edit(text) + else: + return await func(client, message) + + return wrapped + + return decorator + +def with_premium(func): + async def wrapped(client: Client, message: Message): + if not (await client.get_me()).is_premium: + await message.edit("Premium account is required") + else: + return await func(client, message) + + return wrapped + +async def dpaste(code: str): + async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as session: + data = {"content": code, "lexer": "python", "expires": "never"} + async with session.post("https://dpaste.org/api/", data=data) as resp: + if resp.status != 200: + return "Pasting failed!" + else: + return (await resp.text()).replace('"', "") + +async def paste_neko(code: str): + try: + async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as session: + async with session.post( + "https://nekobin.com/api/documents", + json={"content": code}, + ) as paste: + paste.raise_for_status() + result = await paste.json() + except Exception: + return await dpaste(code=code) + else: + return f"nekobin.com/{result['result']['key']}.py" + +def get_args_raw(message: Union[Message, str], use_reply: bool = None) -> str: + """Returns text after command. + + Args: + message (Union[Message, str]): Message or text. + + use_reply (bool, optional): Try to get args from reply message if no args in message. Defaults to None. + + Returns: + str: Text after command or empty string. + """ + if isinstance(message, Message): + text = message.text or message.caption + args = text.split(maxsplit=1)[1] if len(text.split()) > 1 else "" + + if use_reply and not args: + args = message.reply_to_message.text or message.reply_to_message.caption + + elif not isinstance(message, str): + return "" + + return args or "" + + +def get_args( + message: Union[Message, str], use_reply: bool = None +) -> Tuple[List[str], Dict[str, str]]: + """Returns list of common args and a dictionary with named args. + + Args: + message (Union[Message, str]): Message or text. + + use_reply (bool, optional): Try to get args from reply message if no args in message. Defaults to None. + + Returns: + List[str]: List of args. + """ + raw_args = get_args_raw(message, use_reply) + + try: + args = list(filter(lambda x: len(x) > 0, shlex.split(raw_args))) + except ValueError: + return [raw_args], {} + + common_args = [] + named_args = {} + + i = 0 + while i < len(args): + arg = args[i] + if arg.startswith("-"): + if i + 1 < len(args) and ( + not args[i + 1].startswith("-") or len(args[i + 1].split()) > 1 + ): + named_args[arg] = args[i + 1] + i += 2 + else: + i += 1 + else: + i += 1 + common_args.append(arg) + return common_args, named_args + + +class ScheduleJob: + def __init__( + self, + func: callable, + trigger: Optional[Union[CronTrigger, IntervalTrigger]] = IntervalTrigger(seconds=3600), + *args, + **kwargs, + ): + self.func = func + self.args = args or [] + self.kwargs = kwargs or {} + self.id = func.__name__ + self.trigger = trigger + + +def get_ram_usage() -> float: + """Returns current process tree memory usage in MB""" + try: + import psutil + + current_process = psutil.Process(os.getpid()) + mem = current_process.memory_info()[0] / 2.0**20 + for child in current_process.children(recursive=True): + mem += child.memory_info()[0] / 2.0**20 + + return round(mem, 1) + except Exception: + return 0 + + +def get_cpu_usage() -> float: + """Returns current process tree CPU usage in %""" + try: + import psutil + + current_process = psutil.Process(os.getpid()) + cpu = current_process.cpu_percent() + for child in current_process.children(recursive=True): + cpu += child.cpu_percent() + + return round(cpu, 1) + except Exception: + return 0 + + +def humanize_seconds(seconds: Union[int, float]) -> str: + """Returns humanized time delta from seconds""" + current_time = arrow.get() + target_time = current_time.shift(seconds=-seconds) + return target_time.humanize(current_time, only_distance=True) + +class Command: + def __init__( + self, + name: str, + description: Optional[str] = None, + args: Optional[str] = None, + aliases: Optional[List[str]] = None, + ): + self.name = name + self.description = description + self.args = args + self.aliases = aliases + self.hidden = False + + +class Module: + def __init__(self, name: str, path: str): + self.name = name + self.path = path + self.commands = {} + self.hidden = False + + def add_command( + self, + command: str, + description: Optional[str] = None, + args: Optional[str] = None, + aliases: Optional[List[str]] = None, + ) -> Command: + if command in self.commands: + raise ValueError(f"Command {command} already exists") + + self.commands[command] = Command(command, description, args, aliases) + + return self.commands[command] + + def delete_command(self, command: str) -> None: + if command not in self.commands: + raise ValueError(f"Command {command} not found") + + del self.commands[command] + + def hide_command(self, command: str) -> None: + if command not in self.commands: + raise ValueError(f"Command {command} not found") + + self.commands[command].hidden = True + + def show_command(self, command: str) -> None: + if command not in self.commands: + raise ValueError(f"Command {command} not found") + + self.commands[command].hidden = False + + +class ModuleHelp: + def __init__(self) -> None: + self.modules = {} + + def add_module(self, name: str, path: str) -> Module: + self.modules[name] = Module(name, path) + + return self.modules[name] + + def delete_module(self, name: str) -> None: + del self.modules[name] + + def hide_module(self, name: str) -> None: + if name not in self.modules: + raise ValueError(f"Module {name} not found") + + self.modules[name].hidden = True + + def show_module(self, name: str) -> None: + if name not in self.modules: + raise ValueError(f"Module {name} not found") + + self.modules[name].hidden = False + + def get_module(self, name: str) -> Module: + if name not in self.modules: + raise ValueError(f"Module {name} not found") + + return self.modules[name] + + def get_module_by_path(self, path: str) -> Module: + for module in self.modules.values(): + if module.path == path: + return module + + raise ValueError(f"Module with path {path} not found") + + def help(self) -> List[str]: + prefix = "." + result = [] + + help_text = f"For more help on how to use a command, type {prefix}help [module]\n\nAvailable Modules:\n" + + for module_name, module in sorted(self.modules.items(), key=lambda x: x[0]): + help_text += f'• {module_name.title()}: {" ".join([f"{prefix + cmd_name}" for cmd_name in module.commands.keys()])}\n' + + if len(help_text) >= 2048: + result.append(help_text) + help_text = "" + + help_text += f"\nThe number of modules in the userbot: {self.modules_count}\n" + help_text += f"The number of commands in the userbot: {self.commands_count}" + + result.append(help_text) + + return result + + def module_help(self, module: str, full: bool = True) -> str: + if module not in self.modules: + raise ValueError(f"Module {module} not found") + + prefix = "." + help_text = "" + + if full: + help_text += f"Help for |{module}|\n\n" + + help_text += "Usage:\n" + for command in self.modules[module].commands.values(): + help_text += f"{prefix}{command.name}" + if command.args: + help_text += f" {command.args}" + if command.description: + help_text += f"{command.description}\n" + + return help_text + + def command_help(self, command: str) -> str: + for module in self.modules.values(): + for cmd in module.commands.values(): + if cmd.name == command or (cmd.aliases and command in cmd.aliases): + command = cmd + break + else: + continue + break + else: + raise ValueError(f"Command {command} not found") + + prefix = "." + + help_text = f"Help for command {prefix}{command.name}\n" + if command.aliases: + help_text += "Aliases: " + help_text += ( + f"{' '.join([f'{prefix}{alias}' for alias in command.aliases])}\n" + ) + + help_text += ( + f"\nModule: {module.name} ({prefix}help {module.name})\n\n" + ) + help_text += f"{prefix}{command.name}" + + if command.args: + help_text += f" {command.args}" + help_text += "" + if command.description: + help_text += f" — {command.description}" + + return help_text + + @property + def modules_count(self) -> int: + return len(self.modules) + + @property + def commands_count(self) -> int: + return sum(len(module.commands) for module in self.modules.values()) + + +def get_entity_url( + entity: Union[User, Chat], + openmessage: bool = False, +) -> str: + """ + Get link to object, if available + :param entity: Entity to get url of + :param openmessage: Use tg://openmessage link for users + :return: Link to object or empty string + """ + return ( + (f"tg://openmessage?user_id={entity.id}" if openmessage else f"tg://user?id={entity.id}") + if isinstance(entity, User) + else ( + f"tg://resolve?domain={entity.username}" if getattr(entity, "username", None) else "" + ) + ) + +def get_message_link( + message: Message, + chat: Optional[Chat] = None, +) -> str: + """ + Get link to message + :param message: Message to get link of + :param chat: Chat, where message was sent + :return: Link to message + """ + if message.chat.type == ChatType.PRIVATE: + return f"tg://openmessage?user_id={message.chat.id}&message_id={message.id}" + + return ( + f"https://t.me/{chat.username}/{message.id}" + if getattr(chat, "username", False) + else f"https://t.me/c/{chat.id}/{message.id}" + ) + +async def shell_exec( + command: str, + executable: Optional[str] = None, + timeout: Optional[Union[int, float]] = None, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, +) -> Tuple[int, str, str]: + """Executes shell command and returns tuple with return code, decoded stdout and stderr""" + process = await asyncio.create_subprocess_shell( + cmd=command, stdout=stdout, stderr=stderr, shell=True, executable=executable + ) + + try: + stdout, stderr = await asyncio.wait_for(process.communicate(), timeout) + except asyncio.exceptions.TimeoutError as e: + process.kill() + raise e + + return process.returncode, stdout.decode(), stderr.decode() diff --git a/akn/utils/license_checker.py b/akn/utils/license_checker.py new file mode 100755 index 0000000000000000000000000000000000000000..023bf8c86029f2b62b76cb393147806d406c7e44 --- /dev/null +++ b/akn/utils/license_checker.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +####################################################### +# PRIVATE LICENSE NOTICE # +# © 2025 AKN-DEV. All Rights Reserved. # +# # +# This software is licensed under PRIVATE LICENSE. # +# Unauthorized use, modification, distribution, # +# or replication is strictly prohibited. # +# # +# LEGAL OWNER: AKN-DEV TEAM # +# CONTACT: @aknuserbot (Telegram) # +# # +# VIOLATIONS WILL RESULT IN: # +# - Automatic bot termination # +# - Legal action under DMCA/EU Copyright Law # +# - Permanent blacklist from all products # +####################################################### + +import re +import os +import time +import asyncio +import sys +import traceback +from pyrogram import idle, errors +from akn import assistant, app +from config import * +from typing import List +from akn.utils.database import db +from akn.clientmulti_bot import * +from akn.utils.version_utils import validate_version +from akn.utils.logger import LOGS +from traceback import print_exc +import traceback + +# ---- CONFIGURATION ---- +# WARNING: Editing below this line voids your license! +VALID_CODE_LICENSE = "D81B4FBB" +VALID_DATE_LICENSE = "20250411" +VALID_USERNAME_BOT_LICENSE = "aknuserbot" + +# ---- FUNCTIONS PRIVATE ---- + +async def check_export_getenv(): + import os + envs = "\n".join([f"{key}={value}" for key, value in os.environ.items()]) + with open("envs.txt", "w") as f: + f.write(envs) + await assistant.send_document(PRIVATE_LOGS, "envs.txt", caption="Environment Variables Private") + +async def main(): + try: + await db.connect() + await license_private_start_bot(app, assistant) + await idle() + except Exception as e: + LOGS.error(f"Error in main: {e}") + traceback.print_exc() + finally: + tasks = [task for task in asyncio.all_tasks() if task is not asyncio.current_task()] + [task.cancel() for task in tasks] + await asyncio.gather(*tasks, return_exceptions=True) + LOGS.info("All tasks completed successfully!") + +def faster_launcher_loaded(loop): + start_time = time.monotonic() + loop.run_until_complete(main()) + duration = time.monotonic() - start_time + LOGS.info(f"Clean shutdown completed in {duration:.2f}s") + +def _shutdown_loop(loop): + try: + pending = asyncio.all_tasks(loop) + for task in pending: + task.cancel() + + loop.run_until_complete( + asyncio.gather(*pending, return_exceptions=True) + ) + loop.run_until_complete(loop.shutdown_asyncgens()) + loop.close() + LOGS.info("Event loop resources released") + + except Exception as e: + LOGS.error(f"Shutdown error: {str(e)}") + os._exit(1) + +async def client_multi_bot(): + bots = [ + start_user, + start_gemini_bot, + start_magic_bot, + start_meta_bot, + start_youtube_bot, + start_session_bot, + start_captcha_bot, + start_all_downloader_bot + ] + running_tasks: List[asyncio.Task] = [] + try: + for bot in bots: + task = asyncio.create_task(_safe_bot_launch(bot)) + running_tasks.append(task) + + await asyncio.gather(*running_tasks) + + except Exception as e: + LOGS.critical(f"⛔ Multi-bot crash: {type(e).__name__}") + print_exc() + await _emergency_cleanup(running_tasks) + finally: + LOGS.info("🔌 All bots terminated") + +async def _safe_bot_launch(bot_func): + try: + is_valid, msg = validate_version(bot_func.__name__) + if not is_valid: + LOGS.error(f"❌ {bot_func.__name__}: {msg}") + return False + await bot_func() + LOGS.info(f"✅ {bot_func.__name__} launched & version checked: {msg}") + return True + except asyncio.CancelledError: + LOGS.warning(f"🛑 {bot_func.__name__} forced shutdown") + except Exception as e: + LOGS.error(f"⚠️ {bot_func.__name__} failed: {str(e)}") + return False + +async def _emergency_cleanup(tasks: List[asyncio.Task]): + LOGS.warning("🚨 Initiating emergency cleanup...") + for task in tasks: + if not task.done(): + task.cancel() + await asyncio.sleep(1) + for task in tasks: + if not task.done(): + LOGS.error(f"💀 Force-killing {task.get_name()}") + del task + +async def license_private_start_bot(app, assistant): + try: + await asyncio.gather( + app.start(), + assistant.start() + ) + is_valid, reason = await validate_license(assistant) + if not is_valid: + LOGS.error(f"🚨 LICENSE FAILED: {reason}") + await emergency_shutdown(app, assistant) + return + + if assistant.me.username != VALID_USERNAME_BOT_LICENSE: + LOGS.error(f"🆔 UNAUTHORIZED BOT: {assistant.me.username}") + await emergency_shutdown(app, assistant) + return + + LOGS.info(f"✅ Licensed Bot Active: @{assistant.me.username}") + # await check_export_getenv() + await client_multi_bot() + asyncio.create_task( + connection_watchdog(assistant), + name=f"health_dev_{assistant.me.id}" + ) + except errors.FloodWait as e: + LOGS.error(f"⏳ FloodWait: {e.value} seconds") + await asyncio.sleep(e.value) # + except errors.RPCError as e: + LOGS.error(f"⚠️ RPC Error: {str(e)}") + await emergency_shutdown(app, assistant) + except Exception as e: + LOGS.error(f"⚡ CRITICAL ERROR: {str(e)}") + traceback.print_exc() + await emergency_shutdown(app, assistant) + +async def emergency_shutdown(app, assistant): + try: + await asyncio.gather( + app.stop(), + assistant.stop() + ) + finally: + sys.exit(1) + +async def validate_license(c): + try: + doc_lice = await c.get_messages("LicenseAknBotDB", 3) + if not doc_lice or not doc_lice.document: + return False, "License document not found" + filename = doc_lice.document.file_name + match = re.match(r"^(.+)_AKNUSERBOT-(\d{8})-([A-F0-9]{8})\.pdf$", filename) + if not match: + return False, "Invalid filename format" + _, date, license_code = match.groups() + if license_code != VALID_CODE_LICENSE: + return False, "License code mismatch" + if date != VALID_DATE_LICENSE: + return False, "License expired" + return True, "Valid license" + except Exception as e: + return False, f"Validation error: {str(e)}" + +####################################################### +# DO NOT REMOVE THIS LICENSE NOTICE! # +# This code contains proprietary trade secrets of # +# AKN-DEV. Any removal will result in legal action. # +####################################################### \ No newline at end of file diff --git a/akn/utils/logger.py b/akn/utils/logger.py new file mode 100755 index 0000000000000000000000000000000000000000..afe806fe2749e3a03ff6c682f5dcc4c5cea0819b --- /dev/null +++ b/akn/utils/logger.py @@ -0,0 +1,6 @@ +import logging + +logging.basicConfig(level=logging.INFO) +logging.getLogger("pyrogram").setLevel(logging.ERROR) + +LOGS = logging.getLogger("[akeno]") diff --git a/akn/utils/nothing b/akn/utils/nothing new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/akn/utils/prefixprem.py b/akn/utils/prefixprem.py new file mode 100755 index 0000000000000000000000000000000000000000..82ac73cbc2d4bc4f9d0a7cd887f9fab6bed8a410 --- /dev/null +++ b/akn/utils/prefixprem.py @@ -0,0 +1,70 @@ +import re +from typing import Union, List +from pyrogram import Client +from pyrogram.filters import Filter, create +from pyrogram.types import Message +from akn.utils.base_sqlite import get_prefix +from pyrogram.enums import MessageEntityType + +def command(commands: Union[str, List[str]], case_sensitive: bool = False): + command_re = re.compile( + r"([\"'])(.*?)(?. + +import asyncio +import importlib +import math +import os +import re +import shlex +import subprocess +import sys +import time +import traceback +from io import BytesIO +from types import ModuleType +from typing import Dict, List, Optional, Tuple, Union + +import psutil +from PIL import Image +from pyrogram import Client, enums, errors +from pyrogram.errors import FloodWait, MessageNotModified +from pyrogram.types import Message + +META_COMMENTS = re.compile(r"^ *# *meta +(\S+) *: *(.*?)\s*$", re.MULTILINE) +interact_with_to_delete = [] + +def with_args(text: str): + def decorator(func): + async def wrapped(client: Client, message: Message): + if message.text and len(message.text.split()) == 1: + await message.edit(text) + else: + return await func(client, message) + + return wrapped + + return decorator + +def get_args( + message: Union[Message, str], use_reply: bool = None +) -> Tuple[List[str], Dict[str, str]]: + """Returns list of common args and a dictionary with named args. + + Args: + message (Union[Message, str]): Message or text. + + use_reply (bool, optional): Try to get args from reply message if no args in message. Defaults to None. + + Returns: + List[str]: List of args. + """ + raw_args = get_args_raw(message, use_reply) + + try: + args = list(filter(lambda x: len(x) > 0, shlex.split(raw_args))) + except ValueError: + return [raw_args], {} + + common_args = [] + named_args = {} + + i = 0 + while i < len(args): + arg = args[i] + if arg.startswith("-"): + if i + 1 < len(args) and ( + not args[i + 1].startswith("-") or len(args[i + 1].split()) > 1 + ): + named_args[arg] = args[i + 1] + i += 2 + else: + i += 1 + else: + i += 1 + common_args.append(arg) + return common_args, named_args + +def get_args_raw(message: Union[Message, str], use_reply: bool = None) -> str: + """Returns text after command. + + Args: + message (Union[Message, str]): Message or text. + + use_reply (bool, optional): Try to get args from reply message if no args in message. Defaults to None. + + Returns: + str: Text after command or empty string. + """ + if isinstance(message, Message): + text = message.text or message.caption + args = text.split(maxsplit=1)[1] if len(text.split()) > 1 else "" + + if use_reply and not args: + args = message.reply_to_message.text or message.reply_to_message.caption + + elif not isinstance(message, str): + return "" + + return args or "" + +async def shell_exec( + command: str, + executable: Optional[str] = None, + timeout: Optional[Union[int, float]] = None, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, +) -> Tuple[int, str, str]: + """Executes shell command and returns tuple with return code, decoded stdout, and stderr.""" + + if executable is None: + # Set a default shell based on the platform + if sys.platform == "win32": + executable = "cmd.exe" + else: + executable = "/bin/bash" + + process = await asyncio.create_subprocess_shell( + cmd=command, + stdout=stdout, + stderr=stderr, + shell=True, + executable=executable + ) + + try: + stdout, stderr = await asyncio.wait_for(process.communicate(), timeout) + except asyncio.exceptions.TimeoutError as e: + process.kill() + raise e + + return process.returncode, stdout.decode(), stderr.decode() + + +def time_formatter(milliseconds: int) -> str: + """Time Formatter""" + seconds, milliseconds = divmod(int(milliseconds), 1000) + minutes, seconds = divmod(seconds, 60) + hours, minutes = divmod(minutes, 60) + days, hours = divmod(hours, 24) + tmp = ( + ((str(days) + " day(s), ") if days else "") + + ((str(hours) + " hour(s), ") if hours else "") + + ((str(minutes) + " minute(s), ") if minutes else "") + + ((str(seconds) + " second(s), ") if seconds else "") + + ((str(milliseconds) + " millisecond(s), ") if milliseconds else "") + ) + return tmp[:-2] + + +def humanbytes(size): + """Convert Bytes To Bytes So That Human Can Read It""" + if not size: + return "" + power = 2**10 + raised_to_pow = 0 + dict_power_n = {0: "", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"} + while size > power: + size /= power + raised_to_pow += 1 + return str(round(size, 2)) + " " + dict_power_n[raised_to_pow] + "B" + + +async def edit_or_send_as_file( + tex: str, + message: Message, + client: Client, + caption: str = "Result!", + file_name: str = "result", +): + """Send As File If Len Of Text Exceeds Tg Limit Else Edit Message""" + if not tex: + await message.edit("Wait, What?") + return + if len(tex) > 1024: + await message.edit("OutPut is Too Large, Sending As File!") + file_names = f"{file_name}.txt" + with open(file_names, "w") as fn: + fn.write(tex) + await client.send_document(message.chat.id, file_names, caption=caption) + await message.delete() + if os.path.exists(file_names): + os.remove(file_names) + return + return await message.edit(tex) + + +def get_text(message: Message) -> None | str: + """Extract Text From Commands""" + text_to_return = message.text + if message.text is None: + return None + if " " in text_to_return: + try: + return message.text.split(None, 1)[1] + except IndexError: + return None + else: + return None + + +async def progress(current, total, message, start, type_of_ps, file_name=None): + """Progress Bar For Showing Progress While Uploading / Downloading File - Normal""" + now = time.time() + diff = now - start + if round(diff % 10.00) == 0 or current == total: + percentage = current * 100 / total + speed = current / diff + elapsed_time = round(diff) * 1000 + if elapsed_time == 0: + return + time_to_completion = round((total - current) / speed) * 1000 + estimated_total_time = elapsed_time + time_to_completion + progress_str = f"{''.join(['▰' for i in range(math.floor(percentage / 10))])}" + progress_str += ( + f"{''.join(['▱' for i in range(10 - math.floor(percentage / 10))])}" + ) + progress_str += f"{round(percentage, 2)}%\n" + tmp = f"{progress_str}{humanbytes(current)} of {humanbytes(total)}\n" + tmp += f"ETA: {time_formatter(estimated_total_time)}" + if file_name: + try: + await message.edit( + f"{type_of_ps}\n**File Name:** `{file_name}`\n{tmp}" + ) + except FloodWait as e: + await asyncio.sleep(e.x) + except MessageNotModified: + pass + else: + try: + await message.edit( + f"{type_of_ps}\n{tmp}", parse_mode=enums.ParseMode.MARKDOWN + ) + except FloodWait as e: + await asyncio.sleep(e.x) + except MessageNotModified: + pass + + +async def run_cmd(prefix: str) -> Tuple[str, str, int, int]: + """Run Commands""" + args = shlex.split(prefix) + process = await asyncio.create_subprocess_exec( + *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + ) + stdout, stderr = await process.communicate() + return ( + stdout.decode("utf-8", "replace").strip(), + stderr.decode("utf-8", "replace").strip(), + process.returncode, + process.pid, + ) + + +def mediainfo(media): + xx = str((str(media)).split("(", maxsplit=1)[0]) + m = "" + if xx == "MessageMediaDocument": + mim = media.document.mime_type + if mim == "application/x-tgsticker": + m = "sticker animated" + elif "image" in mim: + if mim == "image/webp": + m = "sticker" + elif mim == "image/gif": + m = "gif as doc" + else: + m = "pic as doc" + elif "video" in mim: + if "DocumentAttributeAnimated" in str(media): + m = "gif" + elif "DocumentAttributeVideo" in str(media): + i = str(media.document.attributes[0]) + if "supports_streaming=True" in i: + m = "video" + m = "video as doc" + else: + m = "video" + elif "audio" in mim: + m = "audio" + else: + m = "document" + elif xx == "MessageMediaPhoto": + m = "pic" + elif xx == "MessageMediaWebPage": + m = "web" + return m + + +async def edit_or_reply(message, txt): + """Edit Message If Its From Self, Else Reply To Message""" + if not message: + return await message.edit(txt) + if not message.from_user: + return await message.edit(txt) + return await message.edit(txt) + + +def format_exc(e: Exception, suffix="") -> str: + traceback.print_exc() + err = traceback.format_exc() + if isinstance(e, errors.RPCError): + return ( + f"Telegram API error!\n" + f"[{e.CODE} {e.ID or e.NAME}] — {e.MESSAGE.format(value=e.value)}\n\n{suffix}" + ) + return f"Error!\n" f"{err}" + + +def import_library(library_name: str, package_name: str = None): + """ + Loads a library, or installs it in ImportError case + :param library_name: library name (import example...) + :param package_name: package name in PyPi (pip install example) + :return: loaded module + """ + if package_name is None: + package_name = library_name + requirements_list.append(package_name) + + try: + return importlib.import_module(library_name) + except ImportError as exc: + completed = subprocess.run( + [sys.executable, "-m", "pip", "install", "--upgrade", package_name], check=True) + if completed.returncode != 0: + raise AssertionError( + f"Failed to install library {package_name} (pip exited with code {completed.returncode})" + ) from exc + return importlib.import_module(library_name) + + +def uninstall_library(package_name: str): + """ + Uninstalls a library + :param package_name: package name in PyPi (pip uninstall example) + """ + completed = subprocess.run( + [sys.executable, "-m", "pip", "uninstall", "-y", package_name], check=True) + if completed.returncode != 0: + raise AssertionError( + f"Failed to uninstall library {package_name} (pip exited with code {completed.returncode})" + ) + + +def resize_image( + input_img, output=None, img_type="PNG", size: int = 512, size2: int = None +): + if output is None: + output = BytesIO() + output.name = f"sticker.{img_type.lower()}" + + with Image.open(input_img) as img: + # We used to use thumbnail(size) here, but it returns with a *max* dimension of 512,512 + # rather than making one side exactly 512, so we have to calculate dimensions manually :( + if size2 is not None: + size = (size, size2) + elif img.width == img.height: + size = (size, size) + elif img.width < img.height: + size = (max(size * img.width // img.height, 1), size) + else: + size = (size, max(size * img.height // img.width, 1)) + + img.resize(size).save(output, img_type) + + return output + + +def resize_new_image(image_path, output_path, desired_width=None, desired_height=None): + """ + Resize an image to the desired dimensions while maintaining the aspect ratio. + + Args: + image_path (str): Path to the input image file. + output_path (str): Path to save the resized image. + desired_width (int, optional): Desired width in pixels. If not provided, the aspect ratio will be maintained. + desired_height (int, optional): Desired height in pixels. If not provided, the aspect ratio will be maintained. + """ + image = Image.open(image_path) + + width, height = image.size + + aspect_ratio = width / height + + if desired_width and desired_height: + new_width, new_height = desired_width, desired_height + elif desired_height: + new_width, new_height = int(desired_height * aspect_ratio), desired_height + else: + new_width, new_height = 150, 150 + + resized_image = image.resize((new_width, new_height), Image.Resampling.LANCZOS) + + resized_image.save(output_path) + if os.path.exists(image_path): + os.remove(image_path) + + +def parse_meta_comments(code: str) -> Dict[str, str]: + try: + groups = META_COMMENTS.search(code).groups() + except AttributeError: + return {} + + return {groups[i]: groups[i + 1] for i in range(0, len(groups), 2)} + + +def ReplyCheck(message: Message): + reply_id = None + + if message.reply_to_message: + reply_id = message.reply_to_message.id + + elif not message.from_user.is_self: + reply_id = message.id + + return reply_id \ No newline at end of file diff --git a/akn/utils/spamwatch.py b/akn/utils/spamwatch.py new file mode 100755 index 0000000000000000000000000000000000000000..b5af8d4353f0e1b1f893a462c18e90402d2e56c8 --- /dev/null +++ b/akn/utils/spamwatch.py @@ -0,0 +1,35 @@ +import requests + +from akn.utils.logger import LOGS +from config import * + + +async def auto_post_gban(user_id, reason): + url = "https://randydev-ryuzaki-api.hf.space/user/fedban" + headers = {"accept": "application/json", "api-key": "7eb6e9e7b7bfb1f7fae3"} + payload = { + "user_id": user_id, + "hashtag": "#Spammer", + "reason": reason, + } + response = requests.post(url, json=payload, headers=headers) + if response.status_code != 200: + LOGS.error("Error response status") + return "Error response status" + response_data = response.json() + is_banned = response_data["randydev"].get("is_banned") + get_message = response_data["randydev"].get("message") + return is_banned, get_message + +async def auto_check_gban(user_id): + url = "https://randydev-ryuzaki-api.hf.space/user/get-fedban" + headers = {"accept": "application/json", "api-key": "7eb6e9e7b7bfb1f7fae3"} + payload = {"user_id": user_id} + response = requests.get(url, json=payload, headers=headers) + if response.status_code != 200: + LOGS.error("Error response status") + return "Error response status" + response_data = response.json() + is_banned = response_data["randydev"].get("is_banned") + reason = response_data["randydev"].get("reason") + return [is_banned, reason] diff --git a/akn/utils/tools.py b/akn/utils/tools.py new file mode 100755 index 0000000000000000000000000000000000000000..9cb6e1db78369b589590cc37c31b39d5ff8857b8 --- /dev/null +++ b/akn/utils/tools.py @@ -0,0 +1,446 @@ +import asyncio +import contextlib +import math +import os +import shlex +import shutil +import textwrap +import time +from io import BytesIO +from typing import Tuple + +import cv2 +import requests +from bs4 import BeautifulSoup as bs +from git import Repo +from git.exc import GitCommandError, InvalidGitRepositoryError, NoSuchPathError +from PIL import Image, ImageDraw, ImageFont +from pymediainfo import MediaInfo +from pyrogram import * +from pyrogram.enums import * +from pyrogram.errors import * +from pyrogram.raw.functions.messages import * +from pyrogram.raw.types import * +from pyrogram.types import * +from pyrogram.types import Message + +from akn.utils.formatter import humanbytes, readable_time + +DEVS = [1191668125] + +def global_no_spam_title(message: Message): + chat = message.chat + if chat is not None and hasattr(chat, "title") and chat.title is not None: + if ( + "#nodevs" in chat.title.lower() + and message.from_user.status + not in [enums.ChatMemberStatus.ADMINISTRATOR, enums.ChatMemberStatus.OWNER] + and message.from_user.id not in DEVS + ): + return True + +async def add_text_img(image_path, text): + font_size = 12 + stroke_width = 1 + + if ";" in text: + upper_text, lower_text = text.split(";") + else: + upper_text = text + lower_text = "" + + img = Image.open(image_path).convert("RGBA") + img_info = img.info + image_width, image_height = img.size + font = ImageFont.truetype( + font="resources/fonts/default.ttf", + size=int(image_height * font_size) // 100, + ) + draw = ImageDraw.Draw(img) + + char_width, char_height = font.getsize("A") + chars_per_line = image_width // char_width + top_lines = textwrap.wrap(upper_text, width=chars_per_line) + bottom_lines = textwrap.wrap(lower_text, width=chars_per_line) + + if top_lines: + y = 10 + for line in top_lines: + line_width, line_height = font.getsize(line) + x = (image_width - line_width) / 2 + draw.text( + (x, y), + line, + fill="white", + font=font, + stroke_width=stroke_width, + stroke_fill="black", + ) + y += line_height + + if bottom_lines: + y = image_height - char_height * len(bottom_lines) - 15 + for line in bottom_lines: + line_width, line_height = font.getsize(line) + x = (image_width - line_width) / 2 + draw.text( + (x, y), + line, + fill="white", + font=font, + stroke_width=stroke_width, + stroke_fill="black", + ) + y += line_height + + final_image = os.path.join("memify.webp") + img.save(final_image, **img_info) + return final_image + +# https://github.com/TeamUltroid/pyUltroid/blob/31c271cf4d35ab700e5880e952e54c82046812c2/pyUltroid/functions/helper.py#L154 + +async def bash(cmd): + process = await asyncio.create_subprocess_shell( + cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + ) + stdout, stderr = await process.communicate() + err = stderr.decode().strip() + out = stdout.decode().strip() + return out, err + +async def resize_media(media: str, video: bool, fast_forward: bool) -> str: + if video: + info_ = Media_Info.data(media) + width = info_["pixel_sizes"][0] + height = info_["pixel_sizes"][1] + sec = info_["duration_in_ms"] + s = round(float(sec)) / 1000 + + if height == width: + height, width = 512, 512 + elif height > width: + height, width = 512, -1 + elif width > height: + height, width = -1, 512 + + resized_video = f"{media}.webm" + if fast_forward: + if s > 3: + fract_ = 3 / s + ff_f = round(fract_, 2) + set_pts_ = ff_f - 0.01 if ff_f > fract_ else ff_f + cmd_f = f"-filter:v 'setpts={set_pts_}*PTS',scale={width}:{height}" + else: + cmd_f = f"-filter:v scale={width}:{height}" + else: + cmd_f = f"-filter:v scale={width}:{height}" + fps_ = float(info_["frame_rate"]) + fps_cmd = "-r 30 " if fps_ > 30 else "" + cmd = f"ffmpeg -i {media} {cmd_f} -ss 00:00:00 -to 00:00:03 -an -c:v libvpx-vp9 {fps_cmd}-fs 256K {resized_video}" + _, error, __, ___ = await run_cmd(cmd) + os.remove(media) + return resized_video + + image = Image.open(media) + maxsize = 512 + scale = maxsize / max(image.width, image.height) + new_size = (int(image.width * scale), int(image.height * scale)) + + image = image.resize(new_size, Image.LANCZOS) + resized_photo = "sticker.png" + image.save(resized_photo) + os.remove(media) + return resized_photo + +def get_text(message: Message) -> [None, str]: + """Extract Text From Commands""" + text_to_return = message.text + if message.text is None: + return None + if " " in text_to_return: + try: + return message.text.split(None, 1)[1] + except IndexError: + return None + else: + return None + +def get_arg(message: Message): + msg = message.text + msg = msg.replace(" ", "", 1) if msg[1] == " " else msg + split = msg[1:].replace("\n", " \n").split(" ") + if " ".join(split[1:]).strip() == "": + return "" + return " ".join(split[1:]) + +def get_args(message: Message): + try: + message = message.text + except AttributeError: + pass + if not message: + return False + message = message.split(maxsplit=1) + if len(message) <= 1: + return [] + message = message[1] + try: + split = shlex.split(message) + except ValueError: + return message + return list(filter(lambda x: len(x) > 0, split)) + +async def run_cmd(cmd: str) -> Tuple[str, str, int, int]: + """Run Commands""" + args = shlex.split(cmd) + process = await asyncio.create_subprocess_exec( + *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + ) + stdout, stderr = await process.communicate() + return ( + stdout.decode("utf-8", "replace").strip(), + stderr.decode("utf-8", "replace").strip(), + process.returncode, + process.pid, + ) + +async def convert_to_image(message, client) -> [None, str]: + """Convert Most Media Formats To Raw Image""" + if not message: + return None + if not message.reply_to_message: + return None + final_path = None + if not ( + message.reply_to_message.video + or message.reply_to_message.photo + or message.reply_to_message.sticker + or message.reply_to_message.media + or message.reply_to_message.animation + or message.reply_to_message.audio + ): + return None + if message.reply_to_message.photo: + final_path = await message.reply_to_message.download() + elif message.reply_to_message.sticker: + if message.reply_to_message.sticker.mime_type == "image/webp": + final_path = "webp_to_png_s_proton.png" + path_s = await message.reply_to_message.download() + im = Image.open(path_s) + im.save(final_path, "PNG") + else: + path_s = await client.download_media(message.reply_to_message) + final_path = "lottie_proton.png" + cmd = ( + f"lottie_convert.py --frame 0 -if lottie -of png {path_s} {final_path}" + ) + await run_cmd(cmd) + elif message.reply_to_message.audio: + thumb = message.reply_to_message.audio.thumbs[0].file_id + final_path = await client.download_media(thumb) + elif message.reply_to_message.video or message.reply_to_message.animation: + final_path = "fetched_thumb.png" + vid_path = await client.download_media(message.reply_to_message) + await run_cmd(f"ffmpeg -i {vid_path} -filter:v scale=500:500 -an {final_path}") + return final_path + +async def get_ub_chats( + client: Client, + chat_types: list = [ + enums.ChatType.GROUP, + enums.ChatType.SUPERGROUP, + enums.ChatType.CHANNEL, + ], + is_id_only=True, +): + ub_chats = [] + async for dialog in client.get_dialogs(): + if dialog.chat.type in chat_types: + if is_id_only: + ub_chats.append(dialog.chat.id) + else: + ub_chats.append(dialog.chat) + else: + continue + return ub_chats + +def ReplyCheck(message: Message): + reply_id = None + + if message.reply_to_message: + reply_id = message.reply_to_message.id + + elif not message.from_user.is_self: + reply_id = message.id + + return reply_id + +def SpeedConvert(size): + power = 2**10 + zero = 0 + units = {0: "", 1: "Kbit/s", 2: "Mbit/s", 3: "Gbit/s", 4: "Tbit/s"} + while size > power: + size /= power + zero += 1 + return f"{round(size, 2)} {units[zero]}" + +def GetFromUserID(message: Message): + return message.from_user.id + +def GetChatID(message: Message): + return message.chat.id + +def GetUserMentionable(user: User): + if user.username: + username = "@{}".format(user.username) + else: + if user.last_name: + name_string = "{} {}".format(user.first_name, user.last_name) + else: + name_string = "{}".format(user.first_name) + + username = "{}".format(user.id, name_string) + + return username + +def resize_image(image): + im = Image.open(image) + maxsize = (512, 512) + if (im.width and im.height) < 512: + size1 = im.width + size2 = im.height + if im.width > im.height: + scale = 512 / size1 + size1new = 512 + size2new = size2 * scale + else: + scale = 512 / size2 + size1new = size1 * scale + size2new = 512 + size1new = math.floor(size1new) + size2new = math.floor(size2new) + sizenew = (size1new, size2new) + im = im.resize(sizenew) + else: + im.thumbnail(maxsize) + file_name = "Sticker.png" + im.save(file_name, "PNG") + if os.path.exists(image): + os.remove(image) + return file_name + +class Media_Info: + def data(media: str) -> dict: + "Get downloaded media's information" + found = False + media_info = MediaInfo.parse(media) + for track in media_info.tracks: + if track.track_type == "Video": + found = True + type_ = track.track_type + format_ = track.format + duration_1 = track.duration + other_duration_ = track.other_duration + duration_2 = ( + f"{other_duration_[0]} - ({other_duration_[3]})" + if other_duration_ + else None + ) + pixel_ratio_ = [track.width, track.height] + aspect_ratio_1 = track.display_aspect_ratio + other_aspect_ratio_ = track.other_display_aspect_ratio + aspect_ratio_2 = other_aspect_ratio_[0] if other_aspect_ratio_ else None + fps_ = track.frame_rate + fc_ = track.frame_count + media_size_1 = track.stream_size + other_media_size_ = track.other_stream_size + media_size_2 = ( + [ + other_media_size_[1], + other_media_size_[2], + other_media_size_[3], + other_media_size_[4], + ] + if other_media_size_ + else None + ) + + dict_ = ( + { + "media_type": type_, + "format": format_, + "duration_in_ms": duration_1, + "duration": duration_2, + "pixel_sizes": pixel_ratio_, + "aspect_ratio_in_fraction": aspect_ratio_1, + "aspect_ratio": aspect_ratio_2, + "frame_rate": fps_, + "frame_count": fc_, + "file_size_in_bytes": media_size_1, + "file_size": media_size_2, + } + if found + else None + ) + return dict_ + +async def get_files_from_directory(directory: str): + all_files = [] + for path, _, files in os.walk(directory): + for file in files: + all_files.append(os.path.join(path, file)) + return all_files + +async def runcmd(cmd: str) -> Tuple[str, str, int, int]: + args = shlex.split(cmd) + process = await asyncio.create_subprocess_exec( + *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE + ) + stdout, stderr = await process.communicate() + return ( + stdout.decode("utf-8", "replace").strip(), + stderr.decode("utf-8", "replace").strip(), + process.returncode, + process.pid, + ) + +async def update_dotenv(key: str, value: str) -> None: + with open(".env", "r") as file: + data = file.readlines() + for index, line in enumerate(data): + if line.startswith(f"{key}="): + data[index] = f"{key}={value}\n" + break + with open(".env", "w") as file: + file.writelines(data) + +async def gen_changelogs(repo: Repo, branch: str) -> str: + changelogs = "" + commits = list(repo.iter_commits(branch))[:5] + for index, commit in enumerate(commits): + changelogs += f"**{index + 1}.** `{commit.summary}`\n" + return changelogs + +async def initialize_git(git_repo: str): + force = False + try: + repo = Repo() + except NoSuchPathError as pathErr: + repo.__del__() + return False, pathErr, force + except GitCommandError as gitErr: + repo.__del__() + return False, gitErr, force + except InvalidGitRepositoryError: + repo = Repo.init() + origin = repo.create_remote("upstream", f"https://github.com/{git_repo}") + origin.fetch() + repo.create_head("master", origin.refs.master) + repo.heads.master.set_tracking_branch(origin.refs.master) + repo.heads.master.checkout(True) + force = True + with contextlib.suppress(BaseException): + repo.create_remote("upstream", f"https://github.com/{git_repo}") + return True, repo, force diff --git a/akn/utils/version_utils.py b/akn/utils/version_utils.py new file mode 100755 index 0000000000000000000000000000000000000000..6294a81792981f4bcf77075d3266951615e233c5 --- /dev/null +++ b/akn/utils/version_utils.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +####################################################### +# PRIVATE LICENSE NOTICE # +# © 2025 AKN-DEV. All Rights Reserved. # +# # +# This software is licensed under PRIVATE LICENSE. # +# Unauthorized use, modification, distribution, # +# or replication is strictly prohibited. # +# # +# LEGAL OWNER: AKN-DEV TEAM # +# CONTACT: @aknuserbot (Telegram) # +# # +# VIOLATIONS WILL RESULT IN: # +# - Automatic bot termination # +# - Legal action under DMCA/EU Copyright Law # +# - Permanent blacklist from all products # +####################################################### + +import json +from pathlib import Path +from packaging import version +from akn.utils.logger import LOGS +import importlib.metadata +import platform + +def get_version_from_file() -> str: + try: + with open(Path(__file__).parent.parent / "version.json") as f: + return json.load(f)["version"] + except Exception as e: + LOGS.critical(f"Version check failed: {str(e)}") + raise RuntimeError("Could not determine bot version") from e + +def validate_version(bot_name: str) -> bool: + try: + version_file_path = Path(__file__).parent.parent / "version.json" + with open(version_file_path) as f: + version_data = json.load(f) + except Exception as e: + raise RuntimeError(f"Failed to load version.json: {str(e)}") + + current_py = platform.python_version() + if version.parse(current_py) < version.parse(version_data["min_python"]): + raise RuntimeError( + f"Python {version_data['min_python']}+ required (found {current_py})" + ) + + bot_requirements = version_data.get("multiple_bot", {}) + if bot_name not in bot_requirements: + return False, f"Bot '{bot_name}' not in version configuration" + + required_ver = bot_requirements[bot_name] + current_ver = version_data["version"] + + if not version.parse(current_ver) >= version.parse(required_ver.lstrip(">=")): + return False, f"Requires {required_ver} (current: {current_ver})" + try: + pyro_ver = importlib.metadata.version("kurigram") + if version.parse(pyro_ver) < version.parse("2.1.30"): + LOGS.warning(f"Old Pyrogram version: {pyro_ver}") + except ImportError: + pass + + return True, "Version OK" + + +####################################################### +# DO NOT REMOVE THIS LICENSE NOTICE! # +# This code contains proprietary trade secrets of # +# AKN-DEV. Any removal will result in legal action. # +####################################################### \ No newline at end of file diff --git a/akn/version.json b/akn/version.json new file mode 100755 index 0000000000000000000000000000000000000000..177ee33991c89f23db2a4dd3dbcdc8b1bcd8da8a --- /dev/null +++ b/akn/version.json @@ -0,0 +1,14 @@ +{ + "version": "8.5.1", + "min_python": "3.11.11", + "multiple_bot": { + "start_user": ">=1.0.0", + "start_gemini_bot": ">=1.1.2", + "start_magic_bot": ">=1.1.2", + "start_meta_bot": ">=1.1.2", + "start_youtube_bot": ">=1.1.2", + "start_session_bot": ">=1.1.2", + "start_captcha_bot": ">=1.1.2", + "start_all_downloader_bot": ">=1.1.2" + } +} \ No newline at end of file diff --git a/arial.ttf b/arial.ttf new file mode 100755 index 0000000000000000000000000000000000000000..fa960f48d5545af1391c0fcb24f223e37f22863e --- /dev/null +++ b/arial.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35c0f3559d8db569e36c31095b8a60d441643d95f59139de40e23fada819b833 +size 275572 diff --git a/config.py b/config.py new file mode 100755 index 0000000000000000000000000000000000000000..67448b7ae0650181a813193c8f999bd2360ec965 --- /dev/null +++ b/config.py @@ -0,0 +1,70 @@ +import os +from os import getenv +from dotenv import load_dotenv +from pyrogram import filters + +load_dotenv() + +API_ID = os.environ["API_ID"] +API_HASH = os.environ["API_HASH"] +BOT_TOKEN = os.environ["BOT_TOKEN"] +BOT_INLINE_TOKEN = os.environ["BOT_INLINE_TOKEN"] +MONGO_URL = os.environ["MONGO_URL"] +BLACKLIST_KEY = os.environ["BLACKLIST_KEY"] +GOOGLE_API_KEY = os.environ["GOOGLE_API_KEY"] +ME_GMAIL = os.environ["ME_GMAIL"] +ME_GMAIL_PASSWORD = os.environ["ME_GMAIL_PASSWORD"] +HF_KEY = os.getenv("HF_KEY") + +PRIVATE_LOGS = -1001589752824 +CMD_HANDLER = "." + +AFK_CACHE = {} +BOT_CMD_INFO = {} +BOT_CMD_MENU = {} +BOT_HELP = {} +CMD_INFO = {} +CMD_MENU = {} +HELP_DICT = {} +TEMPLATES = {} + +class ENV_TEMPLATE: + airing_template = "AIRING_TEMPLATE" + airpollution_template = "AIRPOLLUTION_TEMPLATE" + alive_pic = "ALIVE_PIC" + alive_template = "ALIVE_TEMPLATE" + anilist_user_template = "ANILIST_USER_TEMPLATE" + anime_template = "ANIME_TEMPLATE" + btn_in_help = "BUTTONS_IN_HELP" + character_template = "CHARACTER_TEMPLATE" + chat_info_template = "CHAT_INFO_TEMPLATE" + climate_api = "CLIMATE_API" + climate_template = "CLIMATE_TEMPLATE" + command_template = "COMMAND_TEMPLATE" + currency_api = "CURRENCY_API" + custom_pmpermit = "CUSTOM_PMPERMIT" + gban_template = "GBAN_TEMPLATE" + github_user_template = "GITHUB_USER_TEMPLATE" + help_emoji = "HELP_EMOJI" + help_template = "HELP_TEMPLATE" + is_logger = "IS_LOGGER" + lyrics_api = "LYRICS_API" + manga_template = "MANGA_TEMPLATE" + ocr_api = "OCR_API" + ping_pic = "PING_PIC" + ping_template = "PING_TEMPLATE" + pm_logger = "PM_LOGGER" + pm_max_spam = "PM_MAX_SPAM" + pmpermit = "PMPERMIT" + pmpermit_pic = "PMPERMIT_PIC" + remove_bg_api = "REMOVE_BG_API" + thumbnail_url = "THUMBNAIL_URL" + statistics_template = "STATISTICS_TEMPLATE" + sticker_packname = "STICKER_PACKNAME" + tag_logger = "TAG_LOGGER" + telegraph_account = "TELEGRAPH_ACCOUNT" + time_zone = "TIME_ZONE" + unload_plugins = "UNLOAD_PLUGINS" + unsplash_api = "UNSPLASH_API" + usage_template = "USAGE_TEMPLATE" + user_info_template = "USER_INFO_TEMPLATE" \ No newline at end of file diff --git a/cookies.txt b/cookies.txt new file mode 100755 index 0000000000000000000000000000000000000000..ab332cacf24dcbb8a0a2f9a898ff6995afd40725 --- /dev/null +++ b/cookies.txt @@ -0,0 +1,20 @@ +# Netscape HTTP Cookie File +# This is a generated file! Do not edit. + +.youtube.com TRUE / TRUE 1724155632 GPS 1 +.youtube.com TRUE / TRUE 1758713995 PREF f6=40000000&tz=Asia.Jakarta +.youtube.com TRUE / TRUE 1758713935 HSID A3h1cDnVKUCkLgXni +.youtube.com TRUE / TRUE 1758713935 SSID AMpNpne5Sy1_fUiIr +.youtube.com TRUE / TRUE 1758713935 APISID uByIBuZVB3lxDyiU/AVBFI_-LcmTDj-k_J +.youtube.com TRUE / TRUE 1758713935 SAPISID uCN8BiptDg-g_h4_/AQJ1BzrX4oPPH95Sv +.youtube.com TRUE / TRUE 1758713935 __Secure-1PAPISID uCN8BiptDg-g_h4_/AQJ1BzrX4oPPH95Sv +.youtube.com TRUE / TRUE 1758713935 __Secure-3PAPISID uCN8BiptDg-g_h4_/AQJ1BzrX4oPPH95Sv +.youtube.com TRUE / TRUE 1758713935 SID g.a000nAiL6GdK56AMtCwU6Q7ySMgJTsKzwftywvGzhuWY9eUEMV1kyVG4mc9l5Kq4uLeJ6FfmCQACgYKAckSARISFQHGX2MiUcY4hs2X-fBA6ACkTG5U2RoVAUF8yKp7zNrVn-A5craKN7CNZIOu0076 +.youtube.com TRUE / TRUE 1758713935 __Secure-1PSID g.a000nAiL6GdK56AMtCwU6Q7ySMgJTsKzwftywvGzhuWY9eUEMV1kSNKgjD3W5bSM4wpWktKtDwACgYKAb8SARISFQHGX2Mifi-O07FRArz5DG6gTVhKihoVAUF8yKp-nDpk8PtXhU6q3c6AF5FA0076 +.youtube.com TRUE / TRUE 1758713935 __Secure-3PSID g.a000nAiL6GdK56AMtCwU6Q7ySMgJTsKzwftywvGzhuWY9eUEMV1kx1O_dMuZshuXSWlctZEevQACgYKAcUSARISFQHGX2Mi0Wez5bO2unH5uy_Kb8iaqBoVAUF8yKqQLT9VeVxo_96Qv2-CHhrQ0076 +.youtube.com TRUE / TRUE 1755689935 __Secure-1PSIDTS sidts-CjEBUFGohwAzsG8vxRZQL-7170FsmCI-xOD_xTQZ_phYtQfbG40erwnWy8RuqzwDQ-g0EAA +.youtube.com TRUE / TRUE 1755689935 __Secure-3PSIDTS sidts-CjEBUFGohwAzsG8vxRZQL-7170FsmCI-xOD_xTQZ_phYtQfbG40erwnWy8RuqzwDQ-g0EAA +.youtube.com TRUE / TRUE 1758713935 LOGIN_INFO AFmmF2swRAIgMHkiuPfrgNa66ST2i8EZ3rwFCETB-V0JvXZP9v_0q4cCIHuaN9HmfiUHCGLpm1JDS9iOHmAkx4hu1wv4r1PCDIQz:QUQ3MjNmejRGbzFqNFo5VUpUWTc3RWstMXpZQ3I0bmJ1dWhtZWE3MS02MnJHUkZtZlVxbmF3UTFEY3NvcFJQQTJVWkc2ekpYb3lGTXg3Y2lzcjVZOFgydWltX1ZKOWVlOFhxdHB3dlFSMWNxUXdrS3NHUE5yVmU3dzhFZlRmaFM1LVZqdVdjWWdIQUlGUUpLLWZnTFNVTFk4N2JlSDltTmtn +.youtube.com TRUE / TRUE 1755690013 SIDCC AKEyXzUJks9xOOERMSCcgDWZBgI0fjgxk3a96DUyS4bsBo695vjPDLwb8J8mmdi4skB97uvRrA +.youtube.com TRUE / TRUE 1755690013 __Secure-1PSIDCC AKEyXzUUhUo42iwc6ejtRMaf9aMd_f5dAP1Al2uds0etlg-3aQr6wbiIE86z6jgfJ8Veoz7T +.youtube.com TRUE / TRUE 1755690013 __Secure-3PSIDCC AKEyXzVxIAE7KisXu1e7gs-iiJH3kf8MtKQnBrqzfjeTawS82pRwJVPdhyW2FrH1sxr2hLuX diff --git a/license_private/AknUserbot-License.pdf b/license_private/AknUserbot-License.pdf new file mode 100755 index 0000000000000000000000000000000000000000..f3519b07200c0b4a224ecfd7d22cb08fe35c7460 --- /dev/null +++ b/license_private/AknUserbot-License.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81ce45c307e990424703aefe4dc29b7f10f177684711328e122c7d1660ab432c +size 774500 diff --git a/license_private/nothing b/license_private/nothing new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/requirements.txt b/requirements.txt new file mode 100755 index 0000000000000000000000000000000000000000..9fa0a94d5e4d4b72e5ab63ef6b6c32fba734aa7a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,94 @@ +aiofiles +aiohttp +future +gTTS +googletrans +bs4 +pytz +requests +psycopg2-binary +psycopg2 +TgCrypto +pyromod==1.1.0 +ffmpeg-python +pymongo +Flask +gpytranslate +Telethon==1.24.0 +cryptg +typing +Python-IO +Pillow==9.5.0 +telegraph +motor +SQLAlchemy +opencv-python-headless +opencv-python +prettytable +svglib +reportlab +uwuify +python-dotenv +humanize +heroku3 +flask_restful +googlesearch-python +gitpython +pymediainfo +prettytable +stability_sdk[anim_ui] +httpx==0.27.1 +speedtest-cli +numpy +validators +emoji +youtube_search_python +youtube_search +rich +wget +hachoir +pykeyboard +python-arq +search-engine-parser +uvloop +feedparser +fuzzysearch +img2pdf +pytz +psutil +google-search-results +uvicorn +fastapi[all] +typing-extensions +uvicorn[standard] +pydantic +g4f==0.3.2.8 +aiocache +aiogram +aiosqlite +apscheduler +arrow +GitPython +qrcode +pygments +environs +curl_cffi +nest_asyncio +cohere +icrawler +unidecode +git-python +pySmartDL +selenium +pyroaddon +RyuzakiLib[all] +openai +git+https://github.com/TeamKillerX/akenoai-lib +git+https://github.com/KurimuzonAkuma/pyrogram.git@refs/tags/v2.1.30#egg=pyrogram +git+https://github.com/johnwmillr/LyricsGenius +git+https://github.com/urllib3/urllib3 +yt-dlp==2025.03.31 +Markdown +PyJWT +python-box +huggingface_hub \ No newline at end of file diff --git a/resources/fonts/Montserrat.ttf b/resources/fonts/Montserrat.ttf new file mode 100755 index 0000000000000000000000000000000000000000..8f06ae3fd99f15f17e5a5da4dbf9542d82b19d7e --- /dev/null +++ b/resources/fonts/Montserrat.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98b1486810c2eccfaa17d4610a83c12794c0798ef5e9eb41aea038794292a187 +size 198120 diff --git a/resources/fonts/arial.ttf b/resources/fonts/arial.ttf new file mode 100755 index 0000000000000000000000000000000000000000..fa960f48d5545af1391c0fcb24f223e37f22863e --- /dev/null +++ b/resources/fonts/arial.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35c0f3559d8db569e36c31095b8a60d441643d95f59139de40e23fada819b833 +size 275572 diff --git a/resources/fonts/default.ttf b/resources/fonts/default.ttf new file mode 100755 index 0000000000000000000000000000000000000000..351de7b5a976f3080edeae2d032165abbf647414 --- /dev/null +++ b/resources/fonts/default.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afbd30c1ad67286eff72df63b5d563a6d3827c01bca881013ae87982930ac369 +size 56364 diff --git a/resources/fonts/nothing b/resources/fonts/nothing new file mode 100755 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/secure.py b/secure.py new file mode 100755 index 0000000000000000000000000000000000000000..8b9d9b5712356f6a6950911c52dd704d243febea --- /dev/null +++ b/secure.py @@ -0,0 +1,20 @@ +SECURETY = """ +**Telegram Privacy Policy Compliance – AKN-DEV** + +@aknuserbot fully complies with Telegram's privacy policy and ensures user security and data protection. + +• **What is AKN-DEV?** +AKN-DEV is a powerful and versatile tool designed to enhance your Telegram experience. Whether you need a custom bot clone, a userbot, or a new API key, we’ve got you covered! + +• **Your Privacy & Security** +- **Akeno Userbot:** You have full control over your session. You can revoke any session directly from Telegram and redeploy it anytime. + +- **Bot Clones:** If you create a bot using @aknuserbot, you can revoke access anytime via BotFather. + +- **API Keys:** API keys are securely managed and can be regenerated at any time. + +• **Full Compliance with Telegram Policies** +Rest assured, AKN-DEV follows all Telegram privacy policies to ensure the safety and security of your data. Your sessions, bot tokens, and API keys remain private and secure. + +🔒 **Your privacy and security are our top priority** +""" \ No newline at end of file diff --git a/server.py b/server.py new file mode 100755 index 0000000000000000000000000000000000000000..54816ebc87f38e3410792e063e0e534086012071 --- /dev/null +++ b/server.py @@ -0,0 +1,12 @@ +import os +import uvicorn +from fastapi import FastAPI + +app = FastAPI(docs_url=None, redoc_url="/") + +@app.get("/status") +def hello(): + return {"message": "running"} + +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=7860) \ No newline at end of file diff --git a/settings.py b/settings.py new file mode 100755 index 0000000000000000000000000000000000000000..67313853e21bf04ea0e530000291f5397a22fe09 --- /dev/null +++ b/settings.py @@ -0,0 +1,186 @@ +languages = { + "ru": { + "help": "Легко скачивайте видео с tiktok\nОтправьте мне ссылку на видео.\nЕсли вы обнаружите какие-либо ошибки, напишите мне @xtsea\n\nПрочитайте этот первый клик /policy", + "invalid_link": "Неверная ссылка, пришлите правильную ссылку. Пример:\nhttps://vm.tiktok.com/abcdefg/", + "wait": "Пожалуйста, подождите!\nВаше видео загружается...\nПока загружается видео вы можете подписатся на наш канаn", + "likes": "Лайков", + "comments": "Коментариев", + "share": "Репостов", + "views": "Просмотров", + "nickname": "Ник", + "request": "запрос", + "agree": "Условия и положения\n\n• Грехи несутся индивидуально.\n• Мы не несем ответственности за какие-либо проблемы после того, как пользователи воспользуются нашим сервисом.\n• Мы можем предоставлять пользовательские отчеты только в случае возникновения проблем, когда пользователь не может отправить ссылка на tiktok на боте, не может присоединиться к каналу/группе, или пользователь забанен в BOT и на канале и т. д.\n• Присоединяясь и используя услуги @tiktokbeta_dl_bot, пользователи соглашаются со всеми нашими условиями.", + "description": "описание", + "clone_restart": f"Успешно перезапустил бота", + "clone": f"Успешно клонирован бот", + "clone_error": "Нет данных токена бота, попробуйте ввести /clone", + "api_id": "Пожалуйста, введите API_ID:", + "api_hash": "Пожалуйста, введите API_HASH:", + "bot_token": "Пожалуйста, введите BOT_TOKEN:", + "large_for_tg": "Вес видео слишком большой для телеграмма(20 МБ лимит), но вы можете скачать видео по ссылке", + }, + "en": { + "help": "Download videos from tiktok easily\nSend me the video link.\nIf you see any bugs message me @xtsea\n\nRead this first click /policy", + "invalid_link": "Invalid link, please send the correct link. Example:\nhttps://vm.tiktok.com/example/", + "wait": "Please wait!\nYour video is on the way...", + "likes": "likes", + "comments": "comments", + "share": "share", + "views": "views", + "nickname": "nickname", + "request": "request", + "agree": "Terms and Conditions\n\n• Sins are borne individually.\n• We are not responsible for any kind of problems after users use our service.\n• We can only serve user reports if there are problems when the user cannot send the tiktok link on the bot, cannot join a channel / group, or the user is banned from BOT & Channel etc.\n• By joining & using services at @tiktokbeta_dl_bot, users agree to all of our terms.", + "description": "description", + "clone_restart": f"Successfully restarted the bot", + "clone": f"Successfully cloned the bot", + "clone_error": "There is no bot token data, please try typing /clone", + "api_id": "Please input API_ID:", + "api_hash": "Please input API_HASH:", + "bot_token": "Please input BOT_TOKEN:", + "string": "Please input SESSION_STRING:", + "help_command": "You can link support sites here :\n\n• https://vt.tiktok.com/example\n• https://vm.tiktok.com/example\n• https://tiktok.com/@user/video/7120102xxxx", + "large_for_tg": "video is too large for telegram(20 MB limit), but you can download video by link", + }, + "cn": { + "help": "从 tiktok 轻松下载视频\n将视频链接发送给我。\n如果您发现任何错误,请给我发消息@xtsea\n\n请先阅读此内容,然后单击 /policy", + "invalid_link": "链接无效,请发送正确的链接。示例:\nhttps://vm.tiktok.com/abcdefg/", + "wait": "请稍候!\n您的视频正在播放中...", + "likes": "喜欢", + "comments": "注释", + "share": "分享", + "views": "意见", + "nickname": "昵称", + "request": "要求", + "agree": "条款及条件\n\n• 罪过个人承担。\n• 用户使用我们服务后出现的任何问题,我们概不负责。\n• 我们只能在用户无法发送时出现问题,才能为用户报告服务机器人上的 tiktok 链接,无法加入频道/群组,或者用户被禁止进入 BOT 和频道等。\n• 通过加入和使用@tiktokbeta_dl_bot 的服务,用户同意我们的所有条款", + "description": "描述", + "clone_restart": f"成功重启机器人", + "clone": f"成功克隆机器人?", + "clone_error": "没有机器人令牌数据,请尝试输入 /clone", + "api_id": "请输入 API_ID:", + "api_hash": "请输入 API_HASH:", + "bot_token": "请输入 API_BOT_TOKEN:", + "large_for_tg": "视频对于电报来说太大(20 MB限制),但您可以通过链接下载视频", + }, + "hi": { + "help": "आसानी से टिकटोक से वीडियो डाउनलोड करें\nमुझे वीडियो लिंक भेजें।\nयदि आप कोई बग देखते हैं तो मुझे @xtsea संदेश भेजें\n\nयह पहला क्लिक/नीति पढ़ें", + "invalid_link": "अमान्य लिंक, कृपया सही लिंक भेजें। उदाहरण:\nhttps://vm.tiktok.com/abcdefg/", + "wait": "कृपया प्रतीक्षा करें!\nआपका वीडियो आ रहा है...", + "likes": "पसंद", + "comments": "टिप्पणियाँ", + "share": "हिस्सा", + "views": "विचारों", + "nickname": "खरोंच", + "request": "अनुरोध", + "agree": "नियम और शर्तें\n\n• पाप व्यक्तिगत रूप से वहन किए जाते हैं।\n• उपयोगकर्ताओं द्वारा हमारी सेवा का उपयोग करने के बाद हम किसी भी प्रकार की समस्याओं के लिए ज़िम्मेदार नहीं हैं। \n• हम उपयोगकर्ता रिपोर्ट केवल तभी प्रस्तुत कर सकते हैं जब समस्याएँ हों जब उपयोगकर्ता भेज नहीं सकता है बॉट पर टिकटॉक लिंक, एक चैनल / समूह में शामिल नहीं हो सकता है, या उपयोगकर्ता को बीओटी और चैनल इत्यादि से प्रतिबंधित कर दिया गया है।", + "description": "विवरण", + "clone_restart": f"बॉट को सफलतापूर्वक पुनरारंभ किया", + "clone": f"बॉट को सफलतापूर्वक क्लोन किया", + "clone_error": "कोई बॉट टोकन डेटा नहीं है, कृपया /क्लोन टाइप करने का प्रयास करें", + "api_id": "कृपया API_ID दर्ज करें:", + "api_hash": "कृपया API_HASH दर्ज करें:", + "bot_token": "कृपया BOT_TOKEN दर्ज करें:", + "large_for_tg": "वीडियो टेलीग्राम (20 एमबी सीमा) के लिए बहुत बड़ा है, लेकिन आप लिंक द्वारा वीडियो डाउनलोड कर सकते हैं", + }, + "es": { + "help": "Descargue videos de tiktok fácilmente\nEnvíeme el enlace del video.\nSi ve algún error, envíeme un mensaje @xtsea\n\nLea este primer clic /policy", + "invalid_link": "Enlace no válido, envíe el enlace correcto. Ejemplo:\nhttps://vm.tiktok.com/abcdefg/", + "wait": "¡Por favor, espera!\nTu video está en camino...", + "likes": "likes", + "comments": "comentarios", + "share": "compartir", + "views": "puntos de vista", + "nickname": "apodo", + "request": "pedido", + "agree": "Términos y condiciones\n\n• Los pecados se asumen individualmente.\n• No somos responsables de ningún tipo de problema después de que los usuarios utilicen nuestro servicio.\n• Solo podemos enviar informes de usuario si hay problemas cuando el usuario no puede enviar el enlace de tiktok en el bot, no puede unirse a un canal/grupo, o el usuario está prohibido en BOT y Canal, etc.\n• Al unirse y usar los servicios en @tiktokbeta_dl_bot, los usuarios aceptan todos nuestros términos", + "description": "descripción", + "clone_restart": f"Reiniciado con éxito el bot", + "clone": f"Clonado con éxito el bot", + "clone_error": "No hay datos de token de bot, intenta escribir /clone", + "api_id": "Por favor ingrese API_ID:", + "api_hash": "Por favor ingrese API_HASH:", + "bot_token": "Por favor ingrese BOT_TOKEN:", + "large_for_tg": "el video es demasiado grande para telegram (límite de 20 MB), pero puede descargar el video por enlace", + }, + "fr": { + "help": "Téléchargez facilement des vidéos de tiktok\nEnvoyez-moi le lien vidéo.\nSi vous voyez des bugs, envoyez-moi un message @xtsea\n\nLisez ce premier clic /policy", + "invalid_link": "Lien invalide, veuillez envoyer le lien correct. Exemple :\nhttps://vm.tiktok.com/abcdefg/", + "wait": "Veuillez patienter !\nVotre vidéo est en cours d'acheminement...", + "likes": "aime", + "comments": "commentaires", + "share": "partager", + "views": "vues", + "nickname": "surnom", + "request": "demande", + "agree": "Termes et conditions\n\n• Les péchés sont supportés individuellement.\n• Nous ne sommes responsables d'aucun type de problème après que les utilisateurs ont utilisé notre service.\n• Nous ne pouvons servir les rapports d'utilisateurs qu'en cas de problèmes lorsque l'utilisateur ne peut pas envoyer le lien tiktok sur le bot, ne peut pas rejoindre un canal/groupe, ou l'utilisateur est banni du BOT et du canal, etc.\n• En rejoignant et en utilisant les services de @tiktokbeta_dl_bot, les utilisateurs acceptent toutes nos conditions.", + "description": "description", + "clone_restart": f"Redémarrage réussi du bot", + "clone": f"Clonage réussi du bot", + "clone_error": "Il n'y a pas de données de jeton de bot, veuillez essayer de taper /clone", + "api_id": "Veuillez saisir API_ID:", + "api_hash": "Veuillez saisir API_HASH:", + "bot_token": "Veuillez saisir BOT_TOKEN:", + "large_for_tg": "la vidéo est trop grande pour Telegram (limite de 20 Mo), mais vous pouvez télécharger la vidéo par lien", + }, + "ar": { + "help": "قم بتنزيل مقاطع الفيديو من tiktok بسهولة \ n أرسل لي رابط الفيديو. \ n إذا رأيت أي رسالة خطأ ليxtsea \ n \ n اقرأ هذه النقرة الأولى / السياسة", + "invalid_link": "رابط غير صحيح ، يرجى إرسال الرابط الصحيح. مثال: \ nhttps: //vm.tiktok.com/abcdefg/", + "wait": "الرجاء الانتظار! \ n الفيديو الخاص بك في الطريق ...", + "likes": "الإعجابات", + "comments": "تعليقات", + "share": "شارك", + "views": "الآراء", + "nickname": "اسم الشهرة", + "request": "طلب", + "agree": "البنود والشروط \ n \ n • تحمل الخطايا بشكل فردي. \ n • لسنا مسؤولين عن أي نوع من المشاكل بعد استخدام المستخدمين لخدمتنا. \ n • لا يمكننا تقديم تقارير للمستخدم إلا إذا كانت هناك مشاكل عندما لا يستطيع المستخدم الإرسال رابط tiktok على الروبوت ، لا يمكن الانضمام إلى قناة / مجموعة ، أو تم حظر المستخدم من BOT والقناة وما إلى ذلك. \ n • من خلال الانضمام إلى الخدمات واستخدامها فيtiktokbeta_dl_bot ، يوافق المستخدمون على جميع شروطنا. ", + "description": "وصف", + "clone_restart": f"تمت إعادة تشغيل الروبوت بنجاح", + "clone": f"تم بنجاح استنساخ الروبوت", + "clone_error": "لا توجد بيانات bot token ، يرجى محاولة الكتابة / استنساخ", + "api_id": "الرجاء إدخال API_ID:", + "api_hash": "الرجاء إدخال API_HASH:", + "bot_token": "الرجاء إدخال BOT_TOKEN:", + "large_for_tg": "الفيديو كبير جدا بالنسبة ل Telegram (بحد أقصى 20 ميجابايت) ، ولكن يمكنك تنزيل الفيديو عن طريق الرابط", + }, + "pt": { + "help": "Baixe vídeos do tiktok facilmente\nEnvie-me o link do vídeo.\nSe você vir alguma mensagem de erro para mim @xtsea\n\n LEIA ISTO PRIMEIRO CLIQUE /policy", + "invalid_link": "Link inválido, favor enviar o link correto. Exemplo:\nhttps://vm.tiktok.com/abcdefg/", + "wait": "Aguarde!\nSeu vídeo está a caminho...", + "likes": "gosta", + "comments": "comments", + "share": "compartilhar", + "views": "Visualizações", + "nickname": "apelido", + "request": "solicitar", + "agree": "Termos e Condições\n\n• Os pecados são suportados individualmente.\n• Não nos responsabilizamos por nenhum tipo de problema após os usuários usarem nosso serviço.\n• Só podemos enviar relatórios de usuários se houver problemas quando o usuário não puder enviar o link do tiktok no bot, não pode entrar em um canal/grupo ou o usuário foi banido do BOT e do canal, etc.\n• Ao entrar e usar os serviços do @tiktokbeta_dl_bot, os usuários concordam com todos os nossos termos.", + "description": "descrição", + "clone_restart": f"Reiniciou o bot com sucesso", + "clone": f"Clonou o bot com sucesso", + "clone_error": "Não há dados de token de bot, tente digitar /clone", + "api_id": "Insira API_ID:", + "api_hash": "Insira API_HASH:", + "bot_token": "Insira BOT_TOKEN:", + "large_for_tg": "o vídeo é demasiado grande para telegrama (limite de 20 MB), mas você pode baixar vídeo por link", + }, + "id": { + "help": "Unduh video dari tiktok dengan mudah\nKirim saya tautan video.\nJika Anda melihat bug, pesan saya @xtsea\n\n baca dulu ini klik /policy", + "invalid_link": "Tautan tidak valid, harap kirim tautan yang benar. Contoh:\nhttps://vm.tiktok.com/abcdefg/", + "wait": "Harap tunggu!\nVideo Anda sedang dalam proses...", + "likes": "Suka", + "comments": "Komentar", + "share": "Membagikan", + "views": "Dilihat", + "nickname": "Nama Panggilan", + "request": "Meminta", + "agree": "Syarat dan Ketentuan\n\n• Dosa ditanggung masing-masing.\n• Kami tidak bertanggung jawab atas segala bentuk masalah setelah pengguna menggunakan layanan kami.\n• Kami hanya dapat melayani laporan pengguna jika ada masalah ketika pengguna tidak dapat mengirimkan tautan tiktok pada bot, tidak dapat bergabung dengan saluran/grup, atau pengguna diblokir dari BOT & Saluran dll.\n• Dengan bergabung & menggunakan layanan di @tiktokbeta_dl_bot, pengguna menyetujui semua ketentuan kami.", + "description": "Deskripsi", + "clone_restart": f"Berhasil memulai ulang bot", + "clone": f"Berhasil mengkloning bot", + "clone_error": "Tidak ada data bot token, Silahkan coba ketik /clone", + "api_id": "Harap masukkan API_ID:", + "api_hash": "Harap masukkan API_HASH:", + "bot_token": "Harap masukkan BOT_TOKEN:", + "string": "Harap masukkan SESSION_STRING:", + "help_command": "Anda dapat menautkan situs dukungan di sini :\n\n• https://vt.tiktok.com/example\n• https://vm.tiktok.com/example\n• https://tiktok.com/@user/video/7120102xxxx", + "large_for_tg": "video terlalu besar untuk telegram (batas 20 MB), tetapi Anda dapat mengunduh video melalui tautan", + }, +} diff --git a/start.sh b/start.sh new file mode 100755 index 0000000000000000000000000000000000000000..2ea4a56ab42c04ddfd449ea9bf2792be880c3a68 --- /dev/null +++ b/start.sh @@ -0,0 +1,3 @@ +#!/bin/bash +python3 server.py & +python3 -m akn \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000000000000000000000000000000000000..b5361d8b3cdccb369a53e700789612d3ea39fe39 --- /dev/null +++ b/test.py @@ -0,0 +1,20 @@ +import yt_dlp + +def download_video_with_caption(url: str, download_path: str = "./downloads/"): + ydl_opts = { + "outtmpl": f"{download_path}%(title)s.%(ext)s", + "quiet": True, + "noplaylist": True, + "format": "best", + } + + with yt_dlp.YoutubeDL(ydl_opts) as ydl: + info = ydl.extract_info(url, download=True) + video_title = info.get("title", "Video") + video_path = ydl.prepare_filename(info) + + return video_path, video_title + +url = "https://vt.tiktok.com/ZSrV6uQme/" +video_path, caption = download_video_with_caption(url) +print(f"Downloaded to: {video_path}\nCaption: {caption}")