├── runtime.txt ├── Procfile ├── meterial ├── fonts │ ├── README.md │ └── Roboto-Bold.ttf └── images │ ├── README.md │ ├── image.jpg │ ├── asterix.png │ └── asterix-round.png ├── Public └── _config.yml ├── start.sh ├── asterix ├── pyrogramx │ ├── __init__.py │ └── methods │ │ ├── __init__.py │ │ └── decorators │ │ ├── __init__.py │ │ ├── on_inline.py │ │ ├── on_callback.py │ │ └── on_message.py ├── clients │ ├── __init__.py │ ├── utils.py │ └── client.py ├── __init__.py ├── helpers │ ├── decorators │ │ ├── __init__.py │ │ └── alertuser.py │ ├── containers │ │ ├── __init__.py │ │ ├── variables.py │ │ └── strings.py │ ├── functions │ │ └── __init__.py │ ├── datavars │ │ ├── __init__.py │ │ ├── userconfig.py │ │ ├── botconfig.py │ │ └── otherconfig.py │ ├── __init__.py │ └── filters.py ├── readme.md ├── modules │ ├── __init__.py │ ├── quotly.py │ ├── keyboard.py │ ├── stats.py │ ├── pastebin.py │ ├── time.py │ ├── wikipedia.py │ ├── sudo.py │ ├── power.py │ ├── reddit.py │ ├── ping.py │ ├── spam.py │ ├── zombies.py │ ├── translate.py │ ├── animepic.py │ ├── telegraph.py │ ├── utube.py │ ├── carbon.py │ ├── alive.py │ ├── group.py │ ├── afk.py │ ├── help.py │ ├── filetools.py │ ├── dev.py │ ├── share.py │ ├── google.py │ ├── welcome.py │ ├── dv.py │ ├── update.py │ ├── song.py │ ├── info.py │ ├── notes.py │ ├── pmpermit.py │ ├── supertools.py │ └── fun.py ├── database │ ├── __init__.py │ └── postgres │ │ ├── __init__.py │ │ ├── afk_sql.py │ │ ├── dv_sql.py │ │ ├── filters_sql.py │ │ ├── welcome_sql.py │ │ ├── notes_sql.py │ │ └── pmpermit_sql.py ├── plugins │ ├── __init__.py │ ├── start.py │ ├── ping.py │ ├── utils.py │ ├── botfun.py │ ├── help.py │ └── inlinequery.py └── __main__.py ├── requirements.txt ├── SECURITY.md ├── .github └── workflows │ └── pylint.yml ├── session.py ├── app.json ├── config.py └── README.md /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.9.10 2 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: bash start.sh 2 | -------------------------------------------------------------------------------- /meterial/fonts/README.md: -------------------------------------------------------------------------------- 1 | # Fonts Folder 2 | -------------------------------------------------------------------------------- /meterial/images/README.md: -------------------------------------------------------------------------------- 1 | # Images Folder 2 | -------------------------------------------------------------------------------- /Public/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-modernist 2 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | python3 -m asterix 4 | -------------------------------------------------------------------------------- /asterix/pyrogramx/__init__.py: -------------------------------------------------------------------------------- 1 | from .methods import Methods 2 | -------------------------------------------------------------------------------- /asterix/clients/__init__.py: -------------------------------------------------------------------------------- 1 | from .client import SuperClient 2 | 3 | app = SuperClient() 4 | -------------------------------------------------------------------------------- /asterix/__init__.py: -------------------------------------------------------------------------------- 1 | from asterix.clients import app 2 | from asterix.helpers import gen, regex 3 | -------------------------------------------------------------------------------- /meterial/images/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAsterix/AsterixUB/HEAD/meterial/images/image.jpg -------------------------------------------------------------------------------- /meterial/images/asterix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAsterix/AsterixUB/HEAD/meterial/images/asterix.png -------------------------------------------------------------------------------- /meterial/fonts/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAsterix/AsterixUB/HEAD/meterial/fonts/Roboto-Bold.ttf -------------------------------------------------------------------------------- /meterial/images/asterix-round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TeamAsterix/AsterixUB/HEAD/meterial/images/asterix-round.png -------------------------------------------------------------------------------- /asterix/helpers/decorators/__init__.py: -------------------------------------------------------------------------------- 1 | from .alertuser import AlertUser 2 | 3 | 4 | class Decorators(AlertUser): 5 | pass 6 | -------------------------------------------------------------------------------- /asterix/pyrogramx/methods/__init__.py: -------------------------------------------------------------------------------- 1 | from .decorators import Decorators 2 | 3 | 4 | class Methods(Decorators): 5 | pass 6 | -------------------------------------------------------------------------------- /asterix/helpers/containers/__init__.py: -------------------------------------------------------------------------------- 1 | from .strings import Strings 2 | from .variables import Variables 3 | 4 | 5 | class Containers(Strings, Variables): 6 | pass 7 | -------------------------------------------------------------------------------- /asterix/helpers/functions/__init__.py: -------------------------------------------------------------------------------- 1 | from .rawfunctions import RawFunctions 2 | from .utilities import Utilities 3 | 4 | 5 | class Functions(RawFunctions, Utilities): 6 | pass 7 | -------------------------------------------------------------------------------- /asterix/readme.md: -------------------------------------------------------------------------------- 1 | >This directory contains all the necessary files which are needed to run the bot, deleting or altering any of the file will might give error. 2 | 3 | >You can make changes here only if and only if you have basic knowledge about programming. 4 | 5 | -------------------------------------------------------------------------------- /asterix/helpers/datavars/__init__.py: -------------------------------------------------------------------------------- 1 | from .botconfig import BOTDV, BotConfig 2 | from .otherconfig import OTHERDV, OtherConfig 3 | from .userconfig import USERDV, UserConfig 4 | 5 | 6 | class DataVars(BotConfig, OtherConfig, UserConfig): 7 | DVLIST = BOTDV + OTHERDV + USERDV 8 | -------------------------------------------------------------------------------- /asterix/helpers/__init__.py: -------------------------------------------------------------------------------- 1 | from .containers import Containers 2 | from .datavars import DataVars 3 | from .decorators import Decorators 4 | from .filters import * 5 | from .functions import Functions 6 | 7 | 8 | class Helpers(Containers, Functions, Decorators, DataVars): 9 | pass 10 | -------------------------------------------------------------------------------- /asterix/pyrogramx/methods/decorators/__init__.py: -------------------------------------------------------------------------------- 1 | from .on_callback import OnCallbackQuery 2 | from .on_inline import OnInlineQuery 3 | from .on_message import OnMessage 4 | 5 | 6 | class Decorators( 7 | OnMessage, 8 | OnInlineQuery, 9 | OnCallbackQuery, 10 | ): 11 | pass 12 | -------------------------------------------------------------------------------- /asterix/helpers/containers/variables.py: -------------------------------------------------------------------------------- 1 | class Variables(object): 2 | # lower 3 | message_ids = {} 4 | 5 | # assistant 6 | assistant_name = "Kushina" 7 | assistant_age = "18" 8 | assistant_gender = "Female" 9 | 10 | # userbot 11 | userbot_name = "Asterix" 12 | 13 | # photo 14 | PIC = "https://telegra.ph/file/38eec8a079706b8c19eae.mp4" 15 | -------------------------------------------------------------------------------- /asterix/modules/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def __list_all_modules(): 5 | import glob 6 | from os.path import basename, dirname, isfile 7 | 8 | mod_paths = glob.glob(dirname(__file__) + "/*.py") 9 | all_modules = [ 10 | basename(f)[:-3] 11 | for f in mod_paths 12 | if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py") 13 | ] 14 | return all_modules 15 | 16 | 17 | MODULES = sorted(__list_all_modules()) 18 | -------------------------------------------------------------------------------- /asterix/database/__init__.py: -------------------------------------------------------------------------------- 1 | from asterix.database.postgres.afk_sql import AFKSQL 2 | from asterix.database.postgres.dv_sql import DVSQL 3 | from asterix.database.postgres.filters_sql import FILTERSSQL 4 | from asterix.database.postgres.notes_sql import NOTESSQL 5 | from asterix.database.postgres.pmpermit_sql import PMPERMITSQL 6 | from asterix.database.postgres.welcome_sql import WELCOMESQL 7 | 8 | 9 | class Database(AFKSQL, NOTESSQL, PMPERMITSQL, DVSQL, WELCOMESQL, FILTERSSQL): 10 | pass 11 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | git+https://github.com/TeamAsterix/pyrogram 2 | pytube 3 | telegraph 4 | heroku3 5 | aiohttp 6 | aiofiles 7 | hachoir 8 | pillow 9 | bs4 10 | covid 11 | pySmartDL 12 | pyDownload 13 | sqlalchemy==1.3.23 14 | TgCrypto==1.2.2 15 | httpx 16 | pytz 17 | psycopg2 18 | currencyconverter 19 | deep_translator 20 | gtts 21 | git-python 22 | wikipedia-api 23 | youtube_dl 24 | speedtest-cli==2.1.3 25 | search-engine-parser 26 | qrcode 27 | bing-image-downloader 28 | pysimplelog 29 | ryoishin 30 | -------------------------------------------------------------------------------- /asterix/database/postgres/__init__.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import create_engine 2 | from sqlalchemy.ext.declarative import declarative_base 3 | from sqlalchemy.orm import scoped_session, sessionmaker 4 | 5 | from config import Config 6 | 7 | 8 | def start() -> scoped_session: 9 | engine = create_engine(Config.DB_URI) 10 | BASE.metadata.bind = engine 11 | BASE.metadata.create_all(engine) 12 | return scoped_session(sessionmaker(bind=engine, autoflush=False)) 13 | 14 | 15 | BASE = declarative_base() 16 | SESSION = start() 17 | -------------------------------------------------------------------------------- /asterix/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def __list_all_plugins(): 5 | """load plugins""" 6 | import glob 7 | from os.path import basename, dirname, isfile 8 | 9 | mod_paths = glob.glob(dirname(__file__) + "/*.py") 10 | all_plugins = [ 11 | basename(f)[:-3] 12 | for f in mod_paths 13 | if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py") 14 | ] 15 | return all_plugins 16 | 17 | 18 | PLUGINS = sorted(__list_all_plugins()) 19 | __all__ = PLUGINS + ["PLUGINS"] 20 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /asterix/plugins/start.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters 2 | from pyrogram.types import Message 3 | 4 | from asterix import app 5 | 6 | 7 | @app.bot.on_message(filters.command("start")) 8 | async def send_response(_, m: Message): 9 | await m.reply("How can i help You ?") 10 | 11 | 12 | @app.bot.on_message(filters.new_chat_members & filters.group) 13 | async def added_to_group_msg(_, m: Message): 14 | if m.new_chat_members[0].is_self: 15 | try: 16 | await app.bot.send_message( 17 | m.chat.id, 18 | "Thank You for adding me in this group !\nUse /help to know my features.", 19 | ) 20 | except Exception as e: 21 | await app.error(m, e) 22 | else: 23 | return 24 | -------------------------------------------------------------------------------- /asterix/helpers/containers/strings.py: -------------------------------------------------------------------------------- 1 | class Strings(object): 2 | def stat_string(self): 3 | return f""" 4 | **Dex:** Stats 5 | 6 | **Location:** /home/stats 7 | 8 | **Name:** {self.UserName()} 9 | **{self.BotName()} version:** {self.assistant_version} 10 | **Python version:** {self.python_version} 11 | **Pyrogram version:** {self.pyrogram_version} 12 | **Database:** {self.db_status()} 13 | **Uptime:** {self.uptime()} 14 | **User Bio:** {self.UserBio()} 15 | """ 16 | 17 | def closed_menu_string(self): 18 | return f""" 19 | Welcome to Asterix World. 20 | This is your Helpdex, Tap on open button to get more buttons which will help you to understand & operate your userbot & assistant. 21 | 22 | • Menu is closed 23 | """ 24 | -------------------------------------------------------------------------------- /asterix/helpers/decorators/alertuser.py: -------------------------------------------------------------------------------- 1 | from pyrogram.errors import MessageNotModified 2 | from pyrogram.types import CallbackQuery 3 | 4 | 5 | class AlertUser(object): 6 | def alert_user(self, func): 7 | async def wrapper(_, cb: CallbackQuery): 8 | if cb.from_user and not ( 9 | cb.from_user.id == self.id or cb.from_user.id in self.SudoUsers() 10 | ): 11 | await cb.answer( 12 | f"Sorry, but you can't use this userbot ! make your own userbot at @TeamAsterix", 13 | show_alert=True, 14 | ) 15 | else: 16 | try: 17 | await func(_, cb) 18 | except MessageNotModified: 19 | pass 20 | 21 | return wrapper 22 | -------------------------------------------------------------------------------- /asterix/plugins/ping.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | from pyrogram import filters 4 | from pyrogram.types import Message 5 | 6 | from asterix import app 7 | 8 | 9 | @app.bot.on_message(filters.command("ping")) 10 | async def bot_ping(_, m: Message): 11 | if not m.chat.type in ["supergroup", "group"]: 12 | start = datetime.now() 13 | end = datetime.now() 14 | ms = (end - start).microseconds / 1000 15 | await app.bot.send_message( 16 | m.chat.id, f"Pong !\n`{ms}`\nUptime: `{app.uptime()}`" 17 | ) 18 | elif m.chat.type in ["supergroup", "group"]: 19 | start = datetime.now() 20 | msg = await app.bot.send_message(m.chat.id, "Pinging . . .") 21 | end = datetime.now() 22 | ms = (end - start).microseconds / 1000 23 | await msg.edit(f"Pong !\n`{ms}`\nUptime: `{app.uptime()}`") 24 | -------------------------------------------------------------------------------- /asterix/pyrogramx/methods/decorators/on_inline.py: -------------------------------------------------------------------------------- 1 | from typing import Callable 2 | 3 | import pyrogram 4 | from pyrogram.filters import Filter 5 | from pyrogram.scaffold import Scaffold 6 | 7 | 8 | class OnInlineQuery(Scaffold): 9 | def on_inline(self=None, filters=None, group: int = 0) -> callable: 10 | def decorator(func: Callable) -> Callable: 11 | if isinstance(self, pyrogram.Client): 12 | self.add_handler( 13 | pyrogram.handlers.InlineQueryHandler(func, filters), group 14 | ) 15 | elif isinstance(self, Filter) or self is None: 16 | if not hasattr(func, "handlers"): 17 | func.handlers = [] 18 | 19 | func.handlers.append( 20 | ( 21 | pyrogram.handlers.InlineQueryHandler(func, self), 22 | group if filters is None else filters, 23 | ) 24 | ) 25 | 26 | return func 27 | 28 | return decorator 29 | -------------------------------------------------------------------------------- /asterix/pyrogramx/methods/decorators/on_callback.py: -------------------------------------------------------------------------------- 1 | from typing import Callable 2 | 3 | import pyrogram 4 | from pyrogram.filters import Filter 5 | from pyrogram.scaffold import Scaffold 6 | 7 | 8 | class OnCallbackQuery(Scaffold): 9 | def on_callback(self=None, filters=None, group: int = 0) -> callable: 10 | def decorator(func: Callable) -> Callable: 11 | if isinstance(self, pyrogram.Client): 12 | self.add_handler( 13 | pyrogram.handlers.CallbackQueryHandler(func, filters), group 14 | ) 15 | elif isinstance(self, Filter) or self is None: 16 | if not hasattr(func, "handlers"): 17 | func.handlers = [] 18 | 19 | func.handlers.append( 20 | ( 21 | pyrogram.handlers.CallbackQueryHandler(func, self), 22 | group if filters is None else filters, 23 | ) 24 | ) 25 | 26 | return func 27 | 28 | return decorator 29 | -------------------------------------------------------------------------------- /asterix/pyrogramx/methods/decorators/on_message.py: -------------------------------------------------------------------------------- 1 | from typing import Callable 2 | 3 | import pyrogram 4 | from pyrogram.filters import Filter 5 | from pyrogram.scaffold import Scaffold 6 | 7 | 8 | class OnMessage(Scaffold): 9 | def on_message(self=None, filters=None, group: int = 0) -> callable: 10 | """Decorator for handling messages : (user defined method).""" 11 | 12 | def decorator(func: Callable) -> Callable: 13 | if isinstance(self, pyrogram.Client): 14 | self.add_handler(pyrogram.handlers.MessageHandler(func, filters), group) 15 | elif isinstance(self, Filter) or self is None: 16 | if not hasattr(func, "handlers"): 17 | func.handlers = [] 18 | 19 | func.handlers.append( 20 | ( 21 | pyrogram.handlers.MessageHandler(func, self), 22 | group if filters is None else filters, 23 | ) 24 | ) 25 | 26 | return func 27 | 28 | return decorator 29 | -------------------------------------------------------------------------------- /asterix/modules/quotly.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | from pyrogram.types import Message 4 | 5 | from asterix import app, gen 6 | 7 | app.CMD_HELP.update( 8 | {"quotly": ("quotly", {"q [reply to message]": "Make Image Of Your Texts."})} 9 | ) 10 | 11 | 12 | @app.on_message(gen(["q"], allow=["sudo", "channel"])) 13 | async def quotly_handler(_, m: Message): 14 | reply = m.reply_to_message 15 | if not reply: 16 | return await app.send_edit(m, "Reply to any users text message", delme=4) 17 | 18 | m = await app.send_edit(m, "Making a Quote . . .", text_type=["mono"]) 19 | await reply.forward("@QuotLyBot") 20 | is_sticker = True 21 | while is_sticker: 22 | try: 23 | msg = await app.get_last_msg(message=m, chat_id="@QuotLyBot", limit=1) 24 | msg[0]["sticker"]["file_id"] 25 | is_sticker = False 26 | except: 27 | await asyncio.sleep(0.5) 28 | if msg_id := msg[0]["message_id"]: 29 | await asyncio.gather( 30 | m.delete(), app.copy_message(m.chat.id, "@QuotLyBot", msg_id) 31 | ) 32 | -------------------------------------------------------------------------------- /asterix/plugins/utils.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters 2 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup 3 | 4 | from asterix import app 5 | 6 | 7 | @app.bot.on_message(filters.command("id")) 8 | async def chat_user_id(_, m): 9 | reply = m.reply_to_message 10 | if not reply: 11 | await app.bot.send_message( 12 | m.chat.id, 13 | f"**{m.from_user.first_name}:** `{m.from_user.id}`\n**{m.chat.title}:** `{m.chat.id}`", 14 | ) 15 | elif reply: 16 | await app.bot.send_message( 17 | m.chat.id, 18 | f"**{m.from_user.first_name}:** `{m.from_user.id}`\n**{m.chat.title}:** `{m.chat.id}`\n**{reply.from_user.first_name}:** `{reply.from_user.id}`", 19 | ) 20 | 21 | 22 | @app.bot.on_message(filters.command("quote")) 23 | async def bot_anime_quotes(_, m): 24 | await app.bot.send_message( 25 | m.chat.id, 26 | app.quote(), 27 | reply_markup=InlineKeyboardMarkup( 28 | [ 29 | [InlineKeyboardButton("More", callback_data="more-anime-quotes")], 30 | ] 31 | ), 32 | ) 33 | -------------------------------------------------------------------------------- /asterix/modules/keyboard.py: -------------------------------------------------------------------------------- 1 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup 2 | 3 | from asterix import app 4 | from asterix.helpers import gen 5 | 6 | 7 | @app.on_message(gen("kbd", allow=["sudo"])) 8 | async def create_keyboard(_, m): 9 | await m.delete() 10 | if m.chat.type == "bot": 11 | return await app.send_edit( 12 | m, "Sorry you can't use it here", delme=4, text_type=["mono"] 13 | ) 14 | 15 | if not app.user_exists(app.bot.id, m.chat.id): 16 | return await app.send_edit( 17 | m, "Your bot is not present in this group.", text_type=["mono"], delme=4 18 | ) 19 | 20 | if app.long(m) >= 3: 21 | await app.bot.send_message( 22 | m.chat.id, 23 | m.text.split(None, 3)[3], 24 | reply_markup=InlineKeyboardMarkup( 25 | [ 26 | [ 27 | InlineKeyboardButton(m.command[1], url=m.command[2]), 28 | ], 29 | ] 30 | ), 31 | ) 32 | else: 33 | await app.send_edit( 34 | m, f"`{app.PREFIX}kbd [ Button text ] [ Button url ] [ Text ]`" 35 | ) 36 | -------------------------------------------------------------------------------- /.github/workflows/pylint.yml: -------------------------------------------------------------------------------- 1 | name: PyLint 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | PEP8: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | 11 | - name: Setup Python 12 | uses: actions/setup-python@v1 13 | with: 14 | python-version: 3.9 15 | - name: Install Python lint libraries 16 | run: | 17 | pip install autoflake isort black 18 | - name: Remove unused imports and variables 19 | run: | 20 | autoflake --in-place --recursive --remove-all-unused-imports --remove-unused-variables --ignore-init-module-imports . 21 | - name: lint with isort 22 | run: | 23 | isort . 24 | - name: lint with black 25 | run: | 26 | black --exclude "exampleconfig\.py" . 27 | # commit changes 28 | - uses: stefanzweifel/git-auto-commit-action@v4 29 | with: 30 | commit_message: 'pylint: auto fixes' 31 | commit_options: '--no-verify' 32 | repository: . 33 | commit_user_name: TheHackerCatX 34 | commit_user_email: TheHackerCatX@users.noreply.github.com 35 | commit_author: TheHackerCatX 36 | -------------------------------------------------------------------------------- /asterix/helpers/datavars/userconfig.py: -------------------------------------------------------------------------------- 1 | USERDV = ["USER_NAME", "USER_USERNAME", "USER_ID", "USER_PIC", "USER_BIO"] 2 | 3 | 4 | class UserConfig(object): 5 | def UserName(self): 6 | """returns name of user""" 7 | return self.getdv("USER_NAME") or self.USER_NAME or self.name or None 8 | 9 | def UserUsername(self): 10 | """returns username of user""" 11 | return ( 12 | self.getdv("USER_USERNAME") or self.USER_USERNAME or self.username or None 13 | ) 14 | 15 | def UserMention(self): 16 | """returns mention of user""" 17 | return ( 18 | self.MentionMarkdown(self.UserId(), self.UserName()) 19 | if self.UserName() and self.UserId() 20 | else None 21 | ) 22 | 23 | def UserId(self): 24 | """returns telegram id of user""" 25 | return self.getdv("USER_ID") or self.USER_ID or self.id or None 26 | 27 | def UserDc(self): 28 | """returns telegram dc id of user""" 29 | return self.getdv("DC_ID") or self.dc_id or None 30 | 31 | def UserPic(self): 32 | """returns pic of user""" 33 | return self.getdv("USER_PIC") or self.USER_PIC or self.pic or None 34 | 35 | def UserBio(self): 36 | """returns bio of user""" 37 | return self.getdv("USER_BIO") or self.USER_BIO or self.bio or None 38 | -------------------------------------------------------------------------------- /asterix/modules/stats.py: -------------------------------------------------------------------------------- 1 | from pyrogram.types import Message 2 | 3 | from asterix import app 4 | from asterix.helpers import gen 5 | 6 | app.CMD_HELP.update( 7 | { 8 | "stats": ( 9 | "stats", 10 | {"stats": "Get information about how many groups/channels/users you have."}, 11 | ) 12 | } 13 | ) 14 | 15 | 16 | @app.on_message(gen("stats", allow=["sudo"])) 17 | async def dialogstats_handler(_, m: Message): 18 | try: 19 | m = await app.send_edit(m, "Getting stats . . .", text_type=["mono"]) 20 | 21 | bot = 0 22 | user = 0 23 | group = 0 24 | channel = 0 25 | stat_format = """ 26 | • **STATS FOR:** {} 27 | 28 | 🤖 • **BOTS:** {} 29 | 👨 • **USERS:** {} 30 | 🛡️ • **GROUPS:** {} 31 | ⚙️ • **CHANNELS:** {} 32 | """ 33 | 34 | async for x in app.iter_dialogs(): 35 | if x.chat.type == "channel": 36 | channel += 1 37 | if x.chat.type == "bot": 38 | bot += 1 39 | if x.chat.type in ("supergroup", "group"): 40 | group += 1 41 | if x.chat.type == "private": 42 | user += 1 43 | 44 | await app.send_edit( 45 | m, stat_format.format(app.UserMention(), bot, user, group, channel) 46 | ) 47 | except Exception as e: 48 | await app.error(m, e) 49 | -------------------------------------------------------------------------------- /session.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.system("pip3 install tgcrypto pyrogram") 4 | os.system("clear") 5 | from pyrogram import Client 6 | 7 | # guide them 8 | 9 | intro = """ 10 | @TeamAsterix Corporation 11 | Get the following values by logging to, 12 | 13 | https://my.telegram.org 14 | 15 | Required: 16 | 17 | 1. API_ID 18 | 2. API_HASH 19 | 3. PHONE NUMBER (WITH COUNTRY CODE) 20 | 21 | """ 22 | 23 | 24 | print(intro) 25 | 26 | 27 | API_ID = input("\nEnter your API_ID: ") 28 | 29 | while not (API_ID.isdigit() and len(API_ID) == 7): 30 | print("\n\nPlease enter a 7 digit API_ID.\n\n") 31 | API_ID = input("Enter your API_ID (1234567): ") 32 | 33 | 34 | # hexadecimal number 35 | API_HASH = input("\nEnter API HASH: ") 36 | 37 | 38 | # create a new pyrogram session 39 | with Client("in_memory=True", api_id=int(API_ID), api_hash=API_HASH) as app: 40 | app.send_message( 41 | "me", 42 | f"This Is Your Asterix Userbot • [ `SESSION` ]\n\n```{app.export_session_string()}```\n\n⚠️• Don't share this with anyone !!\n\nCreate Again • [ Press Here](https://replit.com/@TeamAsterix/AsterixUB)", 43 | disable_web_page_preview=True, 44 | ) 45 | print( 46 | "Your String Session Is Successfully Saved In Telegram Saved (Cloud) Messages !! Don't Share It With Anyone!! Anyone having your session can use (hack) your telegram account !" 47 | ) 48 | -------------------------------------------------------------------------------- /asterix/clients/utils.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import platform 3 | import time 4 | 5 | from pyrogram import __version__ as pyro_version 6 | from telegraph import Telegraph 7 | 8 | from asterix.database import Database 9 | from asterix.helpers import Helpers 10 | from asterix.pyrogramx.methods import Methods 11 | from config import Config 12 | 13 | 14 | class Utils(Methods, Config, Database, Helpers): 15 | # versions / 16 | 17 | userbot_version = "v.0.0.1" 18 | assistant_version = "v.0.0.1" 19 | python_version = str(platform.python_version()) 20 | pyrogram_version = str(pyro_version) 21 | 22 | # containers / 23 | 24 | CMD_HELP = {} 25 | 26 | # owner details / 27 | 28 | owner_name = "🆂нιναηѕн 🇮🇳[Oғғʟιɴᴇ]" 29 | owner_id = 1986676404 30 | owner_username = "@Ryoishin" 31 | 32 | # other / 33 | 34 | Repo = "https://github.com/TeamAsterix/AsterixUB.git" 35 | StartTime = time.time() 36 | 37 | # debugging / 38 | 39 | logging.getLogger("pyrogram.syncer").setLevel( 40 | logging.CRITICAL 41 | ) # turn off pyrogram logging 42 | logging.getLogger("pyrogram").setLevel(logging.CRITICAL) 43 | 44 | logging.basicConfig(format="%(asctime)s %(message)s") 45 | log = logging.getLogger("———") 46 | 47 | # telegraph / 48 | 49 | telegraph = Telegraph() 50 | telegraph.create_account( 51 | short_name=Config.TL_NAME if Config.TL_NAME else "Asterix Userbot" 52 | ) 53 | -------------------------------------------------------------------------------- /asterix/helpers/datavars/botconfig.py: -------------------------------------------------------------------------------- 1 | from pyrogram.types import Message 2 | 3 | BOTDV = ["BOT_NAME", "BOT_USERNAME", "BOT_ID", "BOT_BIO", "BOT_PIC"] 4 | 5 | 6 | class BotConfig(object): 7 | def BotName(self): 8 | """Get your bot name""" 9 | return self.getdv("BOT_NAME") or self.BOT_NAME or self.bot.name or None 10 | 11 | def BotUserName(self): 12 | """Get your bot username""" 13 | return ( 14 | self.getdv("BOT_USERNAME") or self.BOT_USERNAME or self.bot.username or None 15 | ) 16 | 17 | def BotMention(self): 18 | """Get bot mention""" 19 | return ( 20 | f"[{self.BotName()}](tg://user?id={self.BotId()})" 21 | if self.BotName() and self.BotId() 22 | else None 23 | ) 24 | 25 | def BotId(self): 26 | """Get your bots telegram id""" 27 | return self.getdv("BOT_ID") or self.BOT_ID or self.bot.id or None 28 | 29 | def BotBio(self, m: Message): 30 | """Get your bots bio""" 31 | official = f"Hey {m.from_user.mention} my name is {self.BotName()} and I am your assistant bot. I can help you in many ways . Just use the buttons below to get list of possible commands." 32 | get_bio = self.getdv("BOT_BIO") or self.BOT_BIO or official or None 33 | return f"{get_bio}\n\n**Catagory: **" 34 | 35 | def BotPic(self): 36 | """Get your bot pic url""" 37 | return self.getdv("BOT_PIC") or self.BOT_PIC or None 38 | -------------------------------------------------------------------------------- /asterix/modules/pastebin.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | from pyrogram.types import Message 4 | 5 | from asterix import app, gen 6 | from asterix.helpers import gen 7 | 8 | app.CMD_HELP.update( 9 | { 10 | "nekobin": ( 11 | "nekobin", 12 | { 13 | "bin [reply to text]": "Paste Texts To Nekobin Site, You Can Easily Read The Texts Without Downloading The file." 14 | }, 15 | ) 16 | } 17 | ) 18 | 19 | 20 | @app.on_message(gen(["paste", "bin"], allow=["sudo"])) 21 | async def paster_handler(_, m: Message): 22 | reply = m.reply_to_message 23 | 24 | if reply and reply.text or reply.caption: 25 | text = reply.text or reply.caption 26 | elif not reply and app.long(m) > 1: 27 | text = m.text.split(None, 1)[1] 28 | elif not reply and app.long(m) == 1: 29 | return await app.send_edit( 30 | m, 31 | "Please reply to a message or give some text after command.", 32 | text_type=["mono"], 33 | delme=4, 34 | ) 35 | 36 | m = await app.send_edit(m, "Pasting to pastebin . . .", text_type=["mono"]) 37 | url = await app.HasteBinPaste(text) 38 | reply_text = f"**Hastebin** : [Click Here]({url})" 39 | delete = ( 40 | True 41 | if app.long(m) > 1 and m.command[1] in ["d", "del"] and reply.from_user.is_self 42 | else False 43 | ) 44 | if delete: 45 | await asyncio.gather( 46 | app.send_edit(m, reply_text, disable_web_page_preview=True), 47 | await reply.delete(), 48 | ) 49 | else: 50 | await app.send_edit(m, reply_text, disable_web_page_preview=True) 51 | -------------------------------------------------------------------------------- /asterix/modules/time.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | import pytz 4 | from pyrogram.types import Message 5 | 6 | from asterix import app, gen 7 | 8 | app.CMD_HELP.update( 9 | { 10 | "time": ( 11 | "time", 12 | { 13 | "today": "Get date & time information, set your `TIME_ZONE` to get correct time & date.", 14 | "time": "Get time information of your city.", 15 | "date": "Get date information of your city.", 16 | }, 17 | ) 18 | } 19 | ) 20 | 21 | 22 | @app.on_message(gen("today", allow=["sudo"])) 23 | async def today_handler(_, m: Message): 24 | weekday = datetime.datetime.today().weekday() 25 | if weekday == 0: 26 | today = "Monday" 27 | elif weekday == 1: 28 | today = "Tuesday" 29 | elif weekday == 2: 30 | today = "Wednesday" 31 | elif weekday == 3: 32 | today = "Thursday" 33 | elif weekday == 4: 34 | today = "Friday" 35 | elif weekday == 5: 36 | today = "Saturday" 37 | elif weekday == 6: 38 | today = "Sunday" 39 | my_time = pytz.timezone(app.TIME_ZONE) 40 | 41 | time = datetime.datetime.now(my_time) 42 | 43 | text = f"Today is `{today}`, " 44 | text += f"{time.strftime('%d %b %Y')}\n" 45 | text += f"Time: {time.strftime('%r')}" 46 | await app.send_edit(m, text) 47 | 48 | 49 | @app.on_message(gen("time", allow=["sudo", "channel"])) 50 | async def time_handler(_, m: Message): 51 | await app.send_edit(m, f"Today's time: `{app.showtime()}`") 52 | 53 | 54 | @app.on_message(gen("date", allow=["sudo", "channel"])) 55 | async def date_handler(_, m: Message): 56 | await app.send_edit(m, f"Today's date: `{app.showdate()}`") 57 | -------------------------------------------------------------------------------- /asterix/clients/client.py: -------------------------------------------------------------------------------- 1 | from pyrogram import Client 2 | 3 | from .utils import Utils 4 | 5 | 6 | class SuperClient(Utils, Client): 7 | """Userbot (asterix)""" 8 | 9 | def __init__(self): 10 | super().__init__( 11 | session_name=self.SESSION, 12 | api_id=self.API_ID, 13 | api_hash=self.API_HASH, 14 | workers=self.WORKERS, 15 | ) 16 | self.start() 17 | self.me = self.get_chat("me") 18 | self.id = self.me.id 19 | self.dc_id = self.me.dc_id 20 | self.name = self.me.first_name 21 | self.username = f"@{self.me.username}" if self.me.username else "" 22 | self.bio = self.me.bio if self.me.bio else "" 23 | self.pic = ( 24 | self.download_media(self.me.photo.big_file_id) if self.me.photo else "" 25 | ) 26 | self.stop() 27 | 28 | self.bot = self.Bot() # workaround 29 | 30 | class Bot(Client, Utils): 31 | """Assistant (Kushina)""" 32 | 33 | def __init__(self): 34 | super().__init__( 35 | session_name="Kushina", 36 | api_id=self.API_ID, 37 | api_hash=self.API_HASH, 38 | bot_token=self.TOKEN, 39 | ) 40 | self.start() 41 | self.me = self.get_chat("me") 42 | self.id = self.me.id 43 | self.dc_id = self.me.dc_id 44 | self.name = self.me.first_name 45 | self.username = f"@{self.me.username}" 46 | self.bio = self.me.bio if self.me.bio else "" 47 | self.pic = ( 48 | self.download_media(self.me.photo.big_file_id) if self.me.photo else "" 49 | ) 50 | self.stop() 51 | -------------------------------------------------------------------------------- /asterix/database/postgres/afk_sql.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Boolean, Column, Integer, String, UnicodeText 2 | 3 | from . import BASE, SESSION 4 | 5 | MY_AFK = {} 6 | 7 | 8 | class AFK(BASE): 9 | """create table afk""" 10 | 11 | __tablename__ = "afk" 12 | 13 | user_id = Column(String(14), primary_key=True) 14 | is_afk = Column(Boolean, default=False) 15 | reason = Column(UnicodeText, default=False) 16 | afktime = Column(Integer, default=0) 17 | 18 | def __init__(self, user_id, is_afk, reason, afktime): 19 | self.user_id = str(user_id) 20 | self.is_afk = is_afk 21 | self.reason = reason 22 | self.afktime = afktime 23 | 24 | def __repr__(self): 25 | return "".format(self.user_id) 26 | 27 | 28 | AFK.__table__.create(checkfirst=True) 29 | 30 | 31 | class AFKSQL(object): 32 | """AMC -> Afk Modification Class""" 33 | 34 | def set_afk(self, afk, reason, afktime): 35 | global MY_AFK 36 | afk_db = SESSION.query(AFK).get(str(0)) 37 | if afk_db: 38 | SESSION.delete(afk_db) 39 | afk_db = AFK(0, afk, reason, afktime) 40 | SESSION.add(afk_db) 41 | SESSION.commit() 42 | MY_AFK[0] = {"afk": afk, "reason": reason, "afktime": afktime} 43 | 44 | def get_afk(self): 45 | return MY_AFK.get(0) 46 | 47 | def load_afk(): 48 | global MY_AFK 49 | try: 50 | MY_AFK = {} 51 | listall = SESSION.query(AFK).all() 52 | for x in listall: 53 | MY_AFK[(x.user_id)] = { 54 | "afk": x.is_afk, 55 | "reason": x.reason, 56 | "afktime": x.afktime, 57 | } 58 | finally: 59 | SESSION.close() 60 | 61 | 62 | AFKSQL.load_afk() 63 | -------------------------------------------------------------------------------- /asterix/database/postgres/dv_sql.py: -------------------------------------------------------------------------------- 1 | import threading 2 | 3 | from sqlalchemy import Column, String 4 | 5 | from . import BASE, SESSION 6 | 7 | 8 | class DV(BASE): 9 | 10 | __tablename__ = "database var" 11 | 12 | keys = Column(String, primary_key=True) 13 | values = Column(String) 14 | 15 | def __init__(self, keys, values): 16 | self.keys = keys 17 | self.values = values 18 | 19 | 20 | DV.__table__.create(checkfirst=True) 21 | 22 | INSERTION_LOCK = threading.RLock() 23 | 24 | 25 | class DVSQL(object): 26 | def setdv(self, keys, values): 27 | with INSERTION_LOCK: 28 | mydata = SESSION.query(DV).get(keys) 29 | try: 30 | if not mydata: 31 | mydata = DV(keys, values) 32 | else: 33 | mydata.values = values 34 | SESSION.merge(mydata) 35 | SESSION.commit() 36 | finally: 37 | SESSION.close() 38 | return keys 39 | 40 | def deldv(self, keys): 41 | with INSERTION_LOCK: 42 | mydata = SESSION.query(DV).get(keys) 43 | try: 44 | if mydata: 45 | SESSION.delete(mydata) 46 | SESSION.commit() 47 | finally: 48 | SESSION.close() 49 | return True 50 | 51 | def getdv(self, keys): 52 | mydata = SESSION.query(DV).get(keys) 53 | rep = "" 54 | if mydata: 55 | rep = str(mydata.values) 56 | SESSION.close() 57 | return rep 58 | 59 | def getalldv(self): 60 | kv_data = {} 61 | mydata = SESSION.query(DV).distinct().all() 62 | for x in mydata: 63 | kv_data.update({x.keys: x.values}) 64 | 65 | return kv_data 66 | -------------------------------------------------------------------------------- /asterix/helpers/datavars/otherconfig.py: -------------------------------------------------------------------------------- 1 | OTHERDV = [ 2 | "NO_LOAD", 3 | "SUDO_USERS", 4 | "SUDO_CMDS", 5 | "PMPERMIT", 6 | "PM_LIMIT", 7 | "PMPERMIT_PIC", 8 | "PMPERMIT_TEXT", 9 | "PREFIX", 10 | "HELP_EMOJI", 11 | ] 12 | 13 | 14 | class OtherConfig(object): 15 | def NoLoad(self): 16 | """Get your No load module list""" 17 | noloadvar = self.getdv("NO_LOAD") 18 | data_list = noloadvar.split() if noloadvar else False 19 | return data_list or self.NO_LOAD or [] 20 | 21 | def SudoUsers(self): 22 | """Get sudo users""" 23 | sudovar = self.getdv("SUDO_USERS") 24 | data_list = [int(x) for x in sudovar.split()] if sudovar else False 25 | return data_list or self.SUDO_USERS or [] 26 | 27 | def Pmpermit(self): 28 | """Check whether pmpermit is on | off""" 29 | return self.getdv("PMPERMIT") or self.PMPERMIT or None 30 | 31 | def PmpermitLimit(self): 32 | """Check the number of warns, defaults to 4""" 33 | return self.getdv("PM_LIMIT") or self.PM_LIMIT or 4 34 | 35 | def PmpermitPic(self): 36 | """Check whether you have added a pic in your pmpermit or not""" 37 | return self.getdv("PMPERMIT_PIC") or self.PMPERMIT_PIC or None 38 | 39 | def PmpermitText(self): 40 | """Get the pmpermit text""" 41 | return self.getdv("PMPERMIT_TEXT") or self.PMPERMIT_TEXT or None 42 | 43 | def MyPrefix(self): 44 | """Get list of prefixes (command handlers)""" 45 | return self.getdv("PREFIX").split() or self.PREFIX.split() or "." 46 | 47 | def HelpEmoji(self): 48 | """This will return the emoji which will be used in helpdex""" 49 | return self.getdv("HELP_EMOJI") or self.HELP_EMOJI or "" 50 | 51 | def SudoCmds(self): 52 | """returns a list of command names""" 53 | return self.getdv("SUDO_CMDS").split() or [] 54 | -------------------------------------------------------------------------------- /asterix/__main__.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | from pyrogram import idle 4 | 5 | from asterix.clients import app 6 | 7 | loop = asyncio.get_event_loop() 8 | 9 | 10 | async def start_assistant(): 11 | """ 12 | this function starts the pyrogram bot client. 13 | """ 14 | if app.bot: 15 | print("Activating assistant.\n") 16 | await app.bot.start() 17 | print("Assistant activated.\n") 18 | else: 19 | print( 20 | "Assistant start unsuccessful, please check that you have given the bot token.\n" 21 | ) 22 | print("skipping assistant start !") 23 | 24 | 25 | async def start_userbot(): 26 | """ 27 | this function starts the pyrogram userbot client. 28 | """ 29 | if app: 30 | print("Activating userbot.\n") 31 | await app.start() 32 | print("Userbot activated.\n") 33 | else: 34 | print("Userbot startup unsuccessful, please check everything again ...") 35 | print("Couldn't load modules of userbot") 36 | 37 | 38 | async def start_bot(): 39 | """ 40 | This function uses 'start_assistant' & 'start_userbot' with 41 | clients custom 'import_module' to start clients & import modules. 42 | """ 43 | print( 44 | "___________________________________. Welcome to Asterix World .___________________________________\n\n\n" 45 | ) 46 | print("PLUGINS: Installing.\n\n") 47 | plugins = app.import_module("asterix/plugins/", exclude=app.NoLoad()) 48 | print(f"\n\n{plugins} plugins Loaded\n\n") 49 | print("MODULES: Installing.\n\n") 50 | modules = app.import_module("asterix/modules/", exclude=app.NoLoad()) 51 | print(f"\n\n{modules} modules Loaded\n\n") 52 | await start_assistant() 53 | await start_userbot() 54 | print("You successfully deployed Asterix Userbot, try .ping or .alive to test it.") 55 | await idle() # block execution 56 | 57 | 58 | if __name__ == "__main__": 59 | loop.run_until_complete(start_bot()) 60 | -------------------------------------------------------------------------------- /asterix/modules/wikipedia.py: -------------------------------------------------------------------------------- 1 | import wikipediaapi 2 | from pyrogram.types import Message 3 | 4 | from asterix import app, gen 5 | 6 | app.CMD_HELP.update( 7 | { 8 | "wikipedia": ( 9 | "wikipedia", 10 | {"wiki [ query ]": "Get info about anything on Wikipedia."}, 11 | ) 12 | } 13 | ) 14 | # ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 15 | 16 | 17 | @app.on_message(gen("wiki", allow=["sudo", "channel"])) 18 | async def wikipedia_handler(_, m: Message): 19 | if app.long(m) == 1: 20 | await app.send_edit( 21 | m, 22 | "Give me some query to search on wikipedia . . .", 23 | text_type=["mono"], 24 | delme=True, 25 | ) 26 | 27 | elif app.long(m) > 1 and app.long(m) < 4096: 28 | try: 29 | obj = wikipediaapi.Wikipedia("en") 30 | text = m.text.split(None, 1)[1] 31 | result = obj.page(text) 32 | await app.send_edit( 33 | m, f"Searching for: __{text}__ . . .", text_type=["mono"] 34 | ) 35 | if result: 36 | giveresult = result.summary 37 | if len(giveresult) <= 4096: 38 | await app.send_edit( 39 | m, f"**Results for:** `{text}`\n\n```{giveresult}```" 40 | ) 41 | else: 42 | await app.send_edit( 43 | m, f"**Results for:** `{text}`\n\n```{giveresult[:4095]}```" 44 | ) 45 | else: 46 | await app.send_edit( 47 | m, "No results found !", delme=2, text_type=["mono"] 48 | ) 49 | except Exception as e: 50 | await app.error(m, e) 51 | else: 52 | await app.send(m, "Something went wrong !", text_type=["mono"], delme=3) 53 | -------------------------------------------------------------------------------- /asterix/database/postgres/filters_sql.py: -------------------------------------------------------------------------------- 1 | import threading 2 | 3 | from sqlalchemy import Column, String 4 | 5 | from . import BASE, SESSION 6 | 7 | 8 | class FILTERS(BASE): 9 | __tablename__ = "filters" 10 | 11 | trigger = Column(String, primary_key=True) 12 | chat_id = Column(String) 13 | file_id = Column(String) 14 | caption = Column(String) 15 | 16 | def __init__(self, trigger, chat_id, file_id, caption): 17 | self.trigger = trigger 18 | self.chat_id = chat_id 19 | self.file_id = file_id 20 | self.caption = caption 21 | 22 | 23 | FILTERS.__table__.create(checkfirst=True) 24 | 25 | INSERTION_LOCK = threading.RLock() 26 | 27 | 28 | class FILTERSSQL(object): 29 | def set_filter(self, trigger, chat_id, file_id, caption=False): 30 | with INSERTION_LOCK: 31 | mydata = SESSION.query(filters).get(trigger) 32 | try: 33 | if mydata: 34 | SESSION.delete(mydata) 35 | mydata = filters(trigger, chat_id, file_id, caption) 36 | SESSION.add(mydata) 37 | SESSION.commit() 38 | finally: 39 | SESSION.close() 40 | return chat_id 41 | 42 | def del_filter(self, trigger): 43 | with INSERTION_LOCK: 44 | mydata = SESSION.query(filters).get(trigger) 45 | try: 46 | if mydata: 47 | SESSION.delete(mydata) 48 | SESSION.commit() 49 | finally: 50 | SESSION.close() 51 | return False 52 | 53 | def get_filter(self, trigger): 54 | mydata = SESSION.query(filters).get(trigger) 55 | rep = None 56 | repx = None 57 | repy = None 58 | repz = None 59 | if mydata: 60 | rep = str(mydata.file_id) 61 | repx = mydata.trigger 62 | repy = mydata.chat_id 63 | repz = mydata.caption 64 | SESSION.close() 65 | return {"file_id": rep, "trigger": repx, "chat_id": repy, "caption": repz} 66 | -------------------------------------------------------------------------------- /asterix/plugins/botfun.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters 2 | 3 | from asterix import app 4 | 5 | collect = {} 6 | 7 | numbers = [f"{x}" for x in range(1, 10)] 8 | cmd_handler = ["+", "-"] 9 | 10 | 11 | @app.bot.on_message(filters.command(numbers, cmd_handler) & filters.group) 12 | async def increment_decrement(_, m): 13 | reply = m.reply_to_message 14 | 15 | if reply and (reply.from_user.is_self) or (reply.from_user.is_bot): 16 | return 17 | 18 | if reply: 19 | prefix = [x for x in m.text] 20 | if str(reply.from_user.id) in collect: 21 | if prefix[0] == "+": 22 | data = collect.get(str(reply.from_user.id)) 23 | collect.update( 24 | {str(reply.from_user.id): str(int(data) + int(prefix[1]))} 25 | ) 26 | await app.bot.send_message( 27 | m.chat.id, 28 | f"{reply.from_user.first_name}: " 29 | + str(int(data) + int(prefix[1])) 30 | + " increments", 31 | ) 32 | elif prefix[0] == "-": 33 | data = collect.get(str(reply.from_user.id)) 34 | collect.update( 35 | {str(reply.from_user.id): str(int(data) - int(prefix[1]))} 36 | ) 37 | await app.bot.send_message( 38 | m.chat.id, 39 | f"{reply.from_user.first_name}: " 40 | + str(int(data) - int(prefix[1])) 41 | + " increments", 42 | ) 43 | elif str(reply.from_user.id) not in collect: 44 | if prefix[0] == "+": 45 | data = {str(reply.from_user.id): str(1)} 46 | collect.update(data) 47 | await app.bot.send_message( 48 | m.chat.id, f"{reply.from_user.first_name}: 1 increments" 49 | ) 50 | elif prefix[0] == "-": 51 | data = {str(reply.from_user.id): str(-1)} 52 | collect.update(data) 53 | await app.bot.send_message( 54 | m.chat.id, f"{reply.from_user.first_name}: 1 increments" 55 | ) 56 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Asterix", 3 | "description": "Asterix Is A Multifunctional Telegram Userbot with Custom Settings.", 4 | "logo": "https://telegra.ph/file/467a20658b7e7ab6a72b5.jpg", 5 | "keywords": [ 6 | "userbot", 7 | "plugins", 8 | "development", 9 | "tools", 10 | "pyrogram", 11 | "productivity" 12 | ], 13 | "repository": "https://github.com/TeamAsterix/AsterixUB/", 14 | "website": "https://t.me/teamasterix", 15 | "success_url": "/welcome", 16 | "env": { 17 | "API_ID": { 18 | "description": "Login here -> my.telegram.org to get pair of keys", 19 | "value": "", 20 | "required": true 21 | }, 22 | "API_HASH": { 23 | "description": "Again You Will Find This Here -> my.telegram.org", 24 | "value": "", 25 | "required": true 26 | }, 27 | "SESSION": { 28 | "description": "Generated Pyrogram Session", 29 | "value": "", 30 | "required": true 31 | }, 32 | "PREFIX": { 33 | "description": "This Is The Handler Of Your All Commands You Can Change It To -> [ . , ? ' / + - * ] Any Symbol That You Like.", 34 | "value": ".", 35 | "required": true 36 | }, 37 | "HEROKU_API_KEY": { 38 | "description": "Your heroku api key, Go To Heroku >> Profile Icon >> Account settings >> Scroll Down >> Reveal >> Copy.", 39 | "value": "", 40 | "required": true 41 | }, 42 | "HEROKU_APP_NAME": { 43 | "description": "Your Heroku app name, Look Top First Slot You Have Just Filled At The Top, That's The Value.", 44 | "value": "", 45 | "required": true 46 | }, 47 | "TIME_ZONE": { 48 | "description": "For Time Plugin. Change It To Your Time Zone or If You Don't Know Leave As it is.", 49 | "value": "Asia/Kolkata", 50 | "required": true 51 | }, 52 | "LOG_CHAT": { 53 | "description": "A Private Telegram Group Id To Store Your Logs.", 54 | "required": true 55 | }, 56 | "TOKEN": { 57 | "description": "Go to @botfather in telegram and make a new bot and get the bot token.", 58 | "required": true 59 | } 60 | }, 61 | "addons": [ 62 | { 63 | "plan": "heroku-postgresql", 64 | "options": { 65 | "version": "12" 66 | } 67 | } 68 | ], 69 | "buildpacks": [ 70 | { 71 | "url": "heroku/python" 72 | } 73 | ] 74 | } 75 | 76 | -------------------------------------------------------------------------------- /asterix/modules/sudo.py: -------------------------------------------------------------------------------- 1 | from pyrogram.types import Message 2 | 3 | from asterix import app 4 | from asterix.helpers import gen 5 | 6 | app.CMD_HELP.update( 7 | { 8 | "sudo": ( 9 | "sudo", 10 | { 11 | "addsudo [reply to user]": "Add a user into your sudo list.", 12 | "listsudo ": "Get list of available sudo ids.", 13 | "delsudo [reply to user]": "Delete a user from your sudo list.", 14 | }, 15 | ) 16 | } 17 | ) 18 | 19 | 20 | @app.on_message(gen("addsudo")) 21 | async def addsudo_handler(_, m: Message): 22 | reply = m.reply_to_message 23 | 24 | if not reply: 25 | return await app.send_edit( 26 | m, "Reply to a user to add him in sudo list", text_type=["mono"], delme=4 27 | ) 28 | 29 | sudo_list = app.getdv("SUDO_USERS") 30 | if sudo_list: 31 | all_sudo = [x for x in sudo_list.split()] + [str(reply.from_user.id)] 32 | else: 33 | all_sudo = [str(reply.from_user.id)] 34 | 35 | app.setdv("SUDO_USERS", " ".join(list(set(all_sudo)))) # rem duplicates 36 | await app.send_edit( 37 | m, f"{reply.from_user.mention()} `has been added to sudo.`", delme=4 38 | ) 39 | 40 | 41 | @app.on_message(gen("listsudo", allow=["sudo"])) 42 | async def getsudo_handler(_, m: Message): 43 | sudo_list = [x for x in app.getdv("SUDO_USERS").split()] 44 | await app.send_edit(m, "**Available Sudo id:**\n\n" + "\n".join(sudo_list)) 45 | 46 | 47 | @app.on_message(gen("delsudo")) 48 | async def delsudo_handler(_, m: Message): 49 | reply = m.reply_to_message 50 | user_id = str(reply.from_user.id) 51 | if not reply: 52 | return await app.send_edit( 53 | m, "Reply to a user to add him in sudo list", text_type=["mono"], delme=4 54 | ) 55 | 56 | sudo_list = [x for x in app.getdv("SUDO_USERS").split()] 57 | if user_id in sudo_list: 58 | sudo_list.remove(user_id) 59 | app.setdv("SUDO_USERS", " ".join(sudo_list)) 60 | else: 61 | return await app.send_edit( 62 | m, "This user is not in sudo list", text_type=["mono"], delme=4 63 | ) 64 | 65 | await app.send_edit( 66 | m, f"{reply.from_user.mention()} `has been removed from sudo list`", delme=4 67 | ) 68 | -------------------------------------------------------------------------------- /asterix/modules/power.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | 5 | from pyrogram.types import Message 6 | 7 | from asterix import app, gen 8 | 9 | app.CMD_HELP.update( 10 | { 11 | "power": ( 12 | "power", 13 | { 14 | "reboot": "restarts the userbot through sys. (not heroku)", 15 | "sleep [seconds]": "The bot sleeps with your desired given input.\n**Note:** input must be less than <= 86400 seconds", 16 | }, 17 | ) 18 | } 19 | ) 20 | 21 | 22 | @app.on_message(gen("reboot", allow=["sudo"])) 23 | async def reboot_handler(_, m: Message): 24 | try: 25 | msg = await app.send_edit(m, "Restarting bot . . .", text_type=["mono"]) 26 | 27 | os.execv(sys.executable, ["python"] + sys.argv) 28 | await app.edit_message_text( 29 | msg.chat.id, msg.message_id, "Restart completed !\nBot is alive now !" 30 | ) 31 | except Exception as e: 32 | await m.edit("Failed to restart userbot !", delme=2, text_type=["mono"]) 33 | await app.error(m, e) 34 | 35 | 36 | @app.on_message(gen("sleep", allow=["sudo"])) 37 | async def sleep_handler(_, m: Message): 38 | if app.long(m) == 1: 39 | return await app.send_edit(m, "Give me some seconds after command . . .") 40 | 41 | elif app.long(m) > 1: 42 | arg = m.command[1] 43 | 44 | if arg.isdigit(): 45 | cmd = int(arg) 46 | if cmd > 86400: 47 | return await app.send_edit( 48 | m, 49 | "Sorry you can't sleep bot for more than 24 hours (> 86400 seconds) . . .", 50 | text_type=["mono"], 51 | delme=3, 52 | ) 53 | 54 | format = { 55 | cmd < 60: f"{cmd} seconds", 56 | cmd >= 60: f"{cmd//60} minutes", 57 | cmd >= 3600: f"{cmd//3600} hours", 58 | } 59 | 60 | suffix = "`null`" 61 | for x in format.keys(): # very small loop 62 | if x: 63 | suffix = format[x] 64 | break 65 | 66 | await app.send_edit(m, f"Sleeping for {suffix} . . .", delme=cmd) 67 | time.sleep(cmd) 68 | else: 69 | await app.send_edit( 70 | m, "Please give me a number not text . . .", delme=3, text_type=["mono"] 71 | ) 72 | -------------------------------------------------------------------------------- /asterix/database/postgres/welcome_sql.py: -------------------------------------------------------------------------------- 1 | import threading 2 | 3 | from sqlalchemy import Column, String 4 | 5 | from . import BASE, SESSION 6 | 7 | 8 | class WELCOME(BASE): 9 | __tablename__ = "welcome" 10 | 11 | chat_id = Column(String, primary_key=True) 12 | file_id = Column(String) 13 | text = Column(String) 14 | 15 | def __init__(self, chat_id, file_id, text): 16 | self.chat_id = chat_id 17 | self.file_id = file_id 18 | self.text = text 19 | 20 | 21 | WELCOME.__table__.create(checkfirst=True) 22 | 23 | INSERTION_LOCK = threading.RLock() 24 | 25 | 26 | class WELCOMESQL(object): 27 | """setwelcome, getwelcome, delwelcome, get_welcome_ids""" 28 | 29 | def set_welcome(self, chat_id, file_id, text=None): 30 | with INSERTION_LOCK: 31 | it_exists = SESSION.query(WELCOME).get(chat_id) 32 | try: 33 | if it_exists: 34 | SESSION.delete(it_exists) 35 | new_data = WELCOME(chat_id, file_id, text) 36 | SESSION.add(new_data) 37 | SESSION.commit() 38 | finally: 39 | SESSION.close() 40 | return (chat_id, file_id, text) 41 | 42 | def del_welcome(self, chat_id): 43 | with INSERTION_LOCK: 44 | it_exists = SESSION.query(WELCOME).get(chat_id) 45 | try: 46 | if it_exists: 47 | SESSION.delete(it_exists) 48 | SESSION.commit() 49 | SESSION.close() 50 | return True 51 | except Exception as e: 52 | SESSION.close() 53 | print(e) 54 | return False 55 | 56 | def get_welcome(self, chat_id): 57 | it_exists = SESSION.query(WELCOME).get(chat_id) 58 | rep = None 59 | repx = None 60 | if it_exists: 61 | rep = str(it_exists.file_id) 62 | repx = it_exists.text 63 | SESSION.close() 64 | return {"file_id": rep, "caption": repx} 65 | 66 | def get_welcome_ids(self): 67 | chat_ids = [] 68 | all_welcome = SESSION.query(WELCOME).distinct().all() 69 | for x in all_welcome: 70 | if not (int(x.chat_id) in chat_ids): 71 | chat_ids.append(int(x.chat_id)) 72 | SESSION.close() 73 | return chat_ids 74 | -------------------------------------------------------------------------------- /asterix/plugins/help.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters 2 | from pyrogram.types import InlineKeyboardMarkup, Message 3 | 4 | from asterix import app 5 | 6 | settings = app.BuildKeyboard( 7 | (["• Settings •", "open-settings-dex"], ["• Modules •", "asterix-dex-2"]) 8 | ) 9 | extra = app.BuildKeyboard( 10 | (["• Extra •", "open-extra-dex"], ["• Stats •", "open-stats-dex"]) 11 | ) 12 | about = app.BuildKeyboard(([["About", "open-about-dex"]])) 13 | close = app.BuildKeyboard(([["Close", "close-dex"]])) 14 | approve = app.BuildKeyboard(([["Approve", "approve-user"]])) 15 | global_command = app.BuildKeyboard(([["• Global commands •", "global-commands"]])) 16 | home_back = app.BuildKeyboard((["Home", "close-dex"], ["Back", "open-start-dex"])) 17 | 18 | 19 | # /start command for bot 20 | @app.bot.on_message(filters.command("help")) 21 | async def start(_, m: Message): 22 | if m.from_user: 23 | if m.from_user.id == app.id: 24 | # bot pic 25 | if app.BotPic().endswith(".jpg" or "png" or "jpeg"): 26 | info = await app.bot.send_photo( 27 | m.chat.id, 28 | app.BotPic(), 29 | app.BotBio(m), 30 | reply_markup=InlineKeyboardMarkup([settings, extra, about, close]), 31 | ) 32 | elif app.BotPic().endswith(".mp4" or ".gif"): 33 | info = await app.bot.send_photo( 34 | m.chat.id, 35 | app.BotPic(), 36 | app.BotBio(m), 37 | reply_markup=InlineKeyboardMarkup([settings, extra, about, close]), 38 | ) 39 | else: 40 | info = await app.bot.send_message( 41 | m.chat.id, 42 | app.BotBio(m), 43 | reply_markup=InlineKeyboardMarkup([settings, extra, about, close]), 44 | ) 45 | 46 | elif m.from_user.id != app.id: 47 | info = await app.bot.send_photo( 48 | m.chat.id, 49 | app.PIC, 50 | f"Hey {m.from_user.mention} You are eligible to use me. There are some commands you can use, check below.", 51 | reply_markup=InlineKeyboardMarkup([global_command]), 52 | ) 53 | app.message_ids.update({info.chat.id: info.message_id}) 54 | else: 55 | return 56 | -------------------------------------------------------------------------------- /asterix/modules/reddit.py: -------------------------------------------------------------------------------- 1 | import os 2 | import random 3 | 4 | import requests 5 | from pyrogram.types import Message 6 | 7 | from asterix import app 8 | from asterix.helpers import gen 9 | 10 | app.CMD_HELP.update( 11 | {"reddit": ("reddit", {"r [query]": "Get reddit images (limit = 1)"})} 12 | ) 13 | 14 | 15 | @app.on_message(gen(["r", "reddit"], allow=["sudo", "channel"])) 16 | async def reddit_handler(_, m: Message): 17 | if app.long(m) == 1: 18 | return await app.send_edit( 19 | m, "Please give me some query to search on reddit.", delme=2 20 | ) 21 | 22 | elif app.textlen(m) > 4096: 23 | return await app.send_edit( 24 | m, 25 | "Too long query, only 4096 characters are allowed !", 26 | text_type=["mono"], 27 | delme=2, 28 | ) 29 | 30 | elif app.long(m) > 1: 31 | try: 32 | query = m.text.split(None, 1)[1] 33 | m = await app.send_edit( 34 | m, "Getting reddit images . . .", text_type=["mono"] 35 | ) 36 | url = f"https://old.reddit.com/r/{query}.json" 37 | headers = { 38 | "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0" 39 | } 40 | data = requests.get(url, headers=headers).json() 41 | 42 | for ch in data["data"]["children"]: 43 | pic_url = ch["data"].get("url_overridden_by_dest") 44 | if pic_url: 45 | file_name = pic_url.split("/")[-1] 46 | if not "." in file_name: 47 | continue 48 | with open(file_name, "wb") as f_out: 49 | kate = requests.get(pic_url, headers=headers).content 50 | f_out.write(kate) 51 | 52 | photos = [ 53 | x 54 | for x in os.listdir(".") 55 | if x.endswith(".jpg") or x.endswith(".png") or x.endswith(".gif") or "" 56 | ] 57 | await app.send_photo(m.chat.id, random.choice(photos)) 58 | 59 | # finally remove 60 | for x in os.listdir("."): 61 | if x.endswith(".jpg") or x.endswith(".png") or x.endswith(".gif"): 62 | os.remove(x) 63 | 64 | await m.delete() 65 | 66 | except Exception as e: 67 | await app.error(m, e) 68 | -------------------------------------------------------------------------------- /asterix/modules/ping.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import random 3 | from datetime import datetime 4 | 5 | from pyrogram.types import Message 6 | 7 | from asterix import app, gen 8 | 9 | app.CMD_HELP.update( 10 | { 11 | "ping": ( 12 | "ping", 13 | { 14 | "ping": "Shows you the response speed of the bot.", 15 | "ping [ number ]": "Make infinite pings, don't overuse.", 16 | }, 17 | ) 18 | } 19 | ) 20 | 21 | 22 | # animations 23 | data = ["🕜", "🕡", "🕦", "🕣", "🕥", "🕧", "🕓", "🕔", "🕒", "🕑", "🕐"] 24 | 25 | pings = [] 26 | pings.clear() 27 | 28 | 29 | @app.on_message(gen(["ping", "pong"], allow=["sudo", "channel"])) 30 | async def ping_handler(_, m: Message): 31 | try: 32 | 33 | if app.long(m) == 1: 34 | start = datetime.now() 35 | m = await app.send_edit(m, ". . .", text_type=["mono"]) 36 | end = datetime.now() 37 | m_s = (end - start).microseconds / 1000 38 | await app.send_edit( 39 | m, 40 | f"**Pöng !**\n`{m_s} ms`\n⧑ {app.UserMention()}", 41 | disable_web_page_preview=True, 42 | ) 43 | elif app.long(m) == 2: 44 | cmd = m.command 45 | count = int(cmd[1]) if cmd[1] and cmd[1].isdigit() else 0 46 | if count <= 1: 47 | return await app.send_edit( 48 | m, 49 | f"Use `{app.UserPrefix().split()[0]}ping` for pings less than 1.", 50 | delme=4, 51 | ) 52 | 53 | else: 54 | try: 55 | num = int(count) + 1 56 | for x in range(1, num): 57 | m = await infinite(m) 58 | await app.send_edit(m, ". . .", text_type=["mono"]) 59 | await asyncio.sleep(0.30) 60 | await app.send_edit(m, "".join(pings)) 61 | except Exception as e: 62 | await app.error(m, e) 63 | else: 64 | return await app.send_edit( 65 | m, "Something went wrong in ping module.", delme=2 66 | ) 67 | except Exception as e: 68 | await app.error(m, e) 69 | 70 | 71 | # function to create lots of pings 72 | async def infinite(m: Message): 73 | start = datetime.now() 74 | m = await app.send_edit(m, random.choice(data)) # MessageNotModified 75 | end = datetime.now() 76 | m_s = (end - start).microseconds / 1000 77 | msg = f"Pöng !\n{m_s} ms\n⧑ {app.UserMention()}\n\n" 78 | pings.append(msg) 79 | return m 80 | -------------------------------------------------------------------------------- /asterix/modules/spam.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | from pyrogram.types import Message 4 | 5 | from asterix import app, gen 6 | 7 | app.CMD_HELP.update( 8 | { 9 | "spam": ( 10 | "spam", 11 | { 12 | "spam [number] [text]": "You Know The Use Of This Command.", 13 | "dspam [delay] [count] [msg]": "Delay spam use it to spam with a delay between spamming msg.", 14 | }, 15 | ) 16 | } 17 | ) 18 | 19 | 20 | @app.on_message(gen("spam", allow=["sudo"])) 21 | async def spam_handler(_, m: Message): 22 | try: 23 | reply = m.reply_to_message 24 | reply_to_id = reply.message_id if reply else None 25 | cmd = m.text.split(None, 2) 26 | 27 | if not reply and app.long(m) == 1: 28 | await app.send_edit( 29 | m, 30 | "Reply or give me count & spam text after command.", 31 | text_type=["mono"], 32 | delme=4, 33 | ) 34 | 35 | elif not reply and app.long(m) > 1: 36 | await m.delete() 37 | times = int(cmd[1]) if cmd[1].isdigit() else 0 38 | spam_msg = cmd[2] 39 | for x in range(times): 40 | await app.send_message( 41 | m.chat.id, spam_msg, reply_to_message_id=reply_to_id 42 | ) 43 | await asyncio.sleep(0.10) 44 | 45 | elif reply: 46 | await m.delete() 47 | times = int(cmd[1]) if cmd[1].isdigit() else 0 48 | spam_msg = reply.message_id 49 | for x in range(times): 50 | await app.copy_message(m.chat.id, m.chat.id, spam_msg) 51 | except Exception as e: 52 | await app.error(m, e) 53 | 54 | 55 | @app.on_message(gen("dspam", allow=["sudo"])) 56 | async def delayspam_handler(_, m: Message): 57 | try: 58 | reply = m.reply_to_message 59 | m.command 60 | 61 | if app.long(m) < 3: 62 | await app.send_edit( 63 | m, 64 | f"Use like this: `{app.MyPrefix()[0]}dspam [count spam] [delay time in seconds] [text messages]`", 65 | ) 66 | 67 | elif app.long(m) > 2 and not reply: 68 | await m.delete() 69 | msg = m.text.split(None, 3) 70 | times = int(msg[1]) if msg[1].isdigit() else None 71 | sec = int(msg[2]) if msg[2].isdigit() else None 72 | text = msg[3] 73 | for x in range(times): 74 | await app.send_message(m.chat.id, text) 75 | await asyncio.sleep(sec) 76 | else: 77 | await app.send_edit(m, "Something wrong in spam command !") 78 | except Exception as e: 79 | await app.error(m, e) 80 | -------------------------------------------------------------------------------- /asterix/modules/zombies.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | from pyrogram.types import Message 4 | 5 | from asterix import app, gen 6 | 7 | app.CMD_HELP.update( 8 | { 9 | "zombies": ( 10 | "zombies", 11 | { 12 | "zombies": "Get number of deleted accounts in a chat.", 13 | "zombies [clean]": "Remove all deleted accounts from chat.", 14 | }, 15 | ) 16 | } 17 | ) 18 | 19 | 20 | @app.on_message(gen("zombies", allow=["sudo", "channel"])) 21 | async def zombies_handler(_, m: Message): 22 | if await app.check_private(m): 23 | return 24 | 25 | temp_count = 0 26 | admin_count = 0 27 | count = 0 28 | 29 | if app.long(m) != 2: 30 | m = await app.send_edit( 31 | m, "Checking deleted accounts . . .", text_type=["mono"] 32 | ) 33 | 34 | async for x in app.iter_chat_members(chat_id=m.chat.id): 35 | if x.user.is_deleted: 36 | temp_count += 1 37 | 38 | if temp_count > 0: 39 | await app.send_edit( 40 | m, 41 | f"**Found:** `{temp_count}` Deleted accounts\nUse `{app.PREFIX}zombies clean` to remove them from group.", 42 | ) 43 | else: 44 | await app.send_edit( 45 | m, 46 | "No deleted accounts found.\nGroup is clean as Hell ! 😃", 47 | delme=3, 48 | text_type=["mono"], 49 | ) 50 | 51 | elif app.long(m) == 2 and m.command[1] == "clean": 52 | m = await app.send_edit( 53 | m, "Cleaning deleted accounts . . .", text_type=["mono"] 54 | ) 55 | 56 | async for x in app.iter_chat_members(chat_id=m.chat.id): 57 | if x.user.is_deleted: 58 | if x.status in ("administrator", "creator"): 59 | admin_count += 1 60 | continue 61 | try: 62 | await app.kick_chat_member(m.chat.id, x.user.id) 63 | count += 1 64 | await asyncio.sleep(0.2) 65 | except Exception as e: 66 | await app.error(m, e) 67 | await app.send_edit( 68 | m, 69 | f"`Group clean up done !`\n\n**Total:** `{count+admin_count}`\n**Removed:** `{count}`\n**Not Removed:** `{admin_count}`\n\n**Note:** `Not removed accounts can be admins or the owner`", 70 | ) 71 | 72 | elif app.long(m) == 2 and m.command[1] != "clean": 73 | await app.send_edit( 74 | m, f"Check `{app.PREFIX}help zombies` to see how it works !" 75 | ) 76 | else: 77 | await app.send_edit( 78 | m, 79 | "Something went wrong, please try again later !", 80 | text_type=["mono"], 81 | delme=3, 82 | ) 83 | -------------------------------------------------------------------------------- /asterix/modules/translate.py: -------------------------------------------------------------------------------- 1 | from deep_translator import GoogleTranslator 2 | from pyrogram.types import Message 3 | 4 | from asterix import app, gen 5 | 6 | app.CMD_HELP.update( 7 | { 8 | "translate": ( 9 | "translate", 10 | { 11 | "tr [ language code ] [ text ] | [ reply to message ]": "Translates The Message In Your Language.\n\nNote : Use Correct Language Codes To Translate In Your Language.", 12 | "trlist": "Get list of supported translating languages.", 13 | }, 14 | ) 15 | } 16 | ) 17 | 18 | 19 | gtl = GoogleTranslator() 20 | 21 | 22 | @app.on_message(gen(["tr", "tl", "translate"], allow=["sudo", "channel"])) 23 | async def translate_handler(_, m: Message): 24 | reply = m.reply_to_message 25 | cmd = m.command 26 | 27 | try: 28 | lang = cmd[1] if app.long(m) > 1 else "en" 29 | 30 | await app.send_edit(m, f"**Translating in** `{lang}` . . .") 31 | 32 | languages = list((gtl.get_supported_languages(as_dict=True)).values()) 33 | 34 | if not lang in languages: 35 | return await app.send_edit( 36 | m, 37 | "Bot doesn't support this language code, please try different one.", 38 | text_type=["mono"], 39 | delme=5, 40 | ) 41 | 42 | if reply and reply.text: 43 | tdata = await translate(m, lang=lang, text=reply.text) 44 | await app.send_edit(m, f"**Translated to:** `{lang}`\n\n**Text:**`{tdata}`") 45 | 46 | elif not reply and len(m.text) <= 4096: 47 | if app.long(m) <= 2: 48 | return await app.send_edit( 49 | m, 50 | "Give me the language code with text.", 51 | text_type=["mono"], 52 | delme=3, 53 | ) 54 | text = m.text.split(None, 2)[2] 55 | tdata = await translate(m, lang=lang, text=text) 56 | await app.send_edit( 57 | m, f"**Translated to:** `{lang}`\n\n**Text:** `{tdata}`" 58 | ) 59 | else: 60 | await app.send_edit( 61 | m, 62 | "Something went wrong, please try again later !", 63 | text_type=["mono"], 64 | delme=5, 65 | ) 66 | except Exception as e: 67 | await app.error(m, e) 68 | 69 | 70 | async def translate(m: Message, lang, text): 71 | tr = GoogleTranslator(source="auto", target=lang) 72 | return tr.translate(text) 73 | 74 | 75 | @app.on_message(gen(["trlist", "tllist", "translatelist"], allow=["sudo", "channel"])) 76 | async def translatelang_handler(_, m): 77 | data = [] 78 | data.clear() 79 | 80 | langs_list = gtl.get_supported_languages( 81 | as_dict=True 82 | ) # output: {arabic: ar, french: fr, english: en etc...} 83 | for keys, values in zip(langs_list.values(), langs_list.keys()): 84 | data.append(f"`{keys}` : `{values}`") 85 | 86 | await app.send_edit(m, "**Total languages:**\n\n" + "\n".join(data)) 87 | -------------------------------------------------------------------------------- /asterix/modules/animepic.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | import requests 4 | from pyrogram.types import Message 5 | 6 | from asterix import app 7 | from asterix.helpers import gen 8 | 9 | anime_suffix = "`baka`\n`bite`\n`blush`\n`bored`\n`cry`\n`cuddle`\n`dance`\n`facepalm`\n`feed`\n`happy`\n`highfive`\n`hug`\n`kiss`\n`laugh`\n`pat`\n`poke`\n`pout`\n`shrug`\n`slap`\n`sleep`\n`smile`\n`stare`\n`think`\n`thumbsup`\n`tickle`\n`wave`\n`wink`" 10 | anime_list = [ 11 | "baka", 12 | "bite", 13 | "blush", 14 | "bored", 15 | "cry", 16 | "cuddle", 17 | "dance", 18 | "facepalm", 19 | "feed", 20 | "happy", 21 | "highfive", 22 | "hug", 23 | "kiss", 24 | "laugh", 25 | "pat", 26 | "poke", 27 | "pout", 28 | "shrug", 29 | "slap", 30 | "sleep", 31 | "smile", 32 | "stare", 33 | "think", 34 | "thumbsup", 35 | "tickle", 36 | "wave", 37 | "wink", 38 | ] 39 | 40 | 41 | app.CMD_HELP.update( 42 | { 43 | "animepic": ( 44 | "animepic", 45 | { 46 | "npic": "Get a anime neko girl image.", 47 | "animegif [suffix]": "Get gif's of different anime expressions, use the command below to get suffix list.", 48 | "animelist": "Get list of supported suffix for animegif command.", 49 | }, 50 | ) 51 | } 52 | ) 53 | 54 | 55 | def get_anime_gif(arg): 56 | data = requests.get(f"https://nekos.best/api/v1/{arg}").text 57 | img = json.loads(data)["url"] 58 | text = json.loads(data)["anime_name"] 59 | if img and text: 60 | return [img, text] 61 | else: 62 | return False 63 | 64 | 65 | async def send_gif(m: Message, gif_data): 66 | try: 67 | await app.send_video(m.chat.id, gif_data[0], caption=gif_data[1]) 68 | except Exception as e: 69 | await app.error(m, e) 70 | 71 | 72 | @app.on_message(gen("animelist", allow=["sudo"])) 73 | async def animelist(_, m: Message): 74 | await app.send_edit(m, anime_suffix) 75 | 76 | 77 | @app.on_message(gen(["nekopic", "npic"], allow=["sudo"])) 78 | async def nekoanime(_, m: Message): 79 | try: 80 | if m.from_user.is_self: 81 | await m.delete() 82 | 83 | data = requests.get("https://nekos.best/api/v1/nekos").text 84 | data = json.loads(data) 85 | await app.send_photo(m.chat.id, data["url"], caption=data["artist_name"]) 86 | except Exception as e: 87 | await app.error(m, e) 88 | 89 | 90 | @app.on_message(gen("animegif", allow=["sudo"])) 91 | async def animegif(_, m: Message): 92 | if app.long(m) > 1: 93 | arg = m.command[1] 94 | try: 95 | if m.from_user.is_self: 96 | await m.delete() 97 | 98 | if arg in anime_list: 99 | data = get_anime_gif(arg) 100 | await send_gif(m, data) 101 | else: 102 | await app.send_edit(m, anime_suffix) 103 | except Exception as e: 104 | await app.error(m, e) 105 | else: 106 | await app.send_edit( 107 | m, f"Give me a suffix, use `{app.PREFIX}animelist` to get suffix.", delme=4 108 | ) 109 | -------------------------------------------------------------------------------- /asterix/modules/telegraph.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from pyrogram.types import Message 4 | from telegraph import upload_file 5 | 6 | from asterix import app 7 | from asterix.helpers import gen 8 | 9 | app.CMD_HELP.update( 10 | { 11 | "telegraph": ( 12 | "telegraph", 13 | { 14 | "tgm [reply to message | media]": "Reply To Media To Get Links Of That Media.\nSupported Media - (jpg, jpeg, png, gif, mp4)." 15 | }, 16 | ) 17 | } 18 | ) 19 | 20 | 21 | @app.on_message(gen(["tgm", "telegraph"], allow=["sudo", "channel"])) 22 | async def telegraph_handler(_, m: Message): 23 | reply = m.reply_to_message 24 | filesize = 5242880 25 | # if not replied 26 | if not reply: 27 | await app.send_edit( 28 | m, f"Please reply to media / text . . .", text_type=["mono"] 29 | ) 30 | # replied to text 31 | elif reply.text: 32 | if len(reply.text) <= 4096: 33 | await app.send_edit(m, "⏳• Hold on . . .", text_type=["mono"]) 34 | link = app.telegraph.create_page(app.name, html_content=reply.text) 35 | await app.send_edit( 36 | m, 37 | f"**Telegraph Link: [Press Here](https://telegra.ph/{link.get('path')})**", 38 | disable_web_page_preview=True, 39 | ) 40 | else: 41 | await app.send_edit( 42 | m, "The length text exceeds 4096 characters . . .", text_type=["mono"] 43 | ) 44 | # replied to supported media 45 | elif reply.media: 46 | if ( 47 | reply.photo 48 | and reply.photo.file_size <= filesize # png, jpg, jpeg 49 | or reply.video 50 | and reply.video.file_size <= filesize # mp4 51 | or reply.animation 52 | and reply.animation.file_size <= filesize 53 | or reply.sticker 54 | and reply.sticker.file_size <= filesize 55 | or reply.document 56 | and reply.document.file_size <= filesize # [photo, video] document 57 | ): 58 | await app.send_edit(m, "⏳• Hold on . . .", text_type=["mono"]) 59 | # change ext to png to use convert in link 60 | if reply.animation or reply.sticker: 61 | loc = await app.download_media( 62 | reply, file_name=f"{app.TEMP_DICT}telegraph.png" 63 | ) 64 | else: 65 | loc = await app.download_media(reply) 66 | try: 67 | response = upload_file(loc) 68 | except Exception as e: 69 | return await app.error(m, e) 70 | await app.send_edit( 71 | m, 72 | f"**Telegraph Link: [Press Here](https://telegra.ph{response[0]})**", 73 | disable_web_page_preview=True, 74 | ) 75 | if os.path.exists(loc): 76 | os.remove(loc) 77 | else: 78 | await app.send_edit( 79 | m, 80 | "Please check the file format or file size , it must be less than 5 mb . . .", 81 | text_type=["mono"], 82 | ) 83 | else: 84 | # if replied to unsupported media 85 | await app.send_edit( 86 | m, "Sorry, The File is not supported !", delme=2, text_type=["mono"] 87 | ) 88 | -------------------------------------------------------------------------------- /asterix/modules/utube.py: -------------------------------------------------------------------------------- 1 | from pyrogram.types import Message 2 | from pytube import YouTube 3 | 4 | from asterix import app, gen 5 | 6 | app.CMD_HELP.update( 7 | { 8 | "utube": ( 9 | "utube", 10 | { 11 | "yvinfo [link]": "Get a youtube video information . . .", 12 | "yvdl [link]": "Download any video from YouTube . . .", 13 | }, 14 | ) 15 | } 16 | ) 17 | 18 | 19 | @app.on_message(gen("yvinfo", allow=["sudo", "channel"])) 20 | async def videoinfo_handler(_, m: Message): 21 | reply = m.reply_to_message 22 | if reply and reply.text: 23 | link = reply.text 24 | elif not reply and app.long(m) >= 1: 25 | link = m.text.split(None, 1)[1] 26 | elif not reply and app.long(m) == 1: 27 | return await app.send_edit( 28 | m, 29 | "Reply to youtube link or give link as a suffix . . .", 30 | text_type=["mono"], 31 | delme=5, 32 | ) 33 | 34 | await app.send_edit(m, "Getting information . . .", text_type=["mono"]) 35 | yt = YouTube(link) 36 | thumb_link = yt.thumbnail_url 37 | data = f"**Title:** {yt.title}\n\n" 38 | data += f"**Duration:** {app.GetReadableTime(yt.length)}\n\n" 39 | data += f"**Description:** {yt.description}\n\n" 40 | data += f"**Views:** {yt.views}\n\n" 41 | data += f"**Age Restricted:** {'Yes' if yt.age_restricted else 'No'}" 42 | 43 | await app.send_photo(m.chat.id, thumb_link, caption=data) 44 | 45 | 46 | @app.on_message(gen("yvdl", allow=["sudo", "channel"])) 47 | async def ytdownload_handler(_, m): 48 | reply = m.reply_to_message 49 | await app.send_edit(m, "processing link . . .", text_type=["mono"]) 50 | if not reply: 51 | if app.long(m) == 1: 52 | return await app.send_edit( 53 | m, 54 | "Please reply to a yt link or give me link as a suffix . . .", 55 | text_type=["mono"], 56 | delme=4, 57 | ) 58 | elif ( 59 | app.long(m) > 1 60 | and m.command[1].startswith("http://" or "https://") 61 | and not m.command[1].isdigit() 62 | ): 63 | link = m.command[1] 64 | else: 65 | return await app.send_edit( 66 | m, 67 | "Please reply to a link or give me the link as a suffix after command . . .", 68 | text_type=["mono"], 69 | delme=4, 70 | ) 71 | elif reply: 72 | if reply.text and reply.text.startswith("http://" or "https://"): 73 | link = reply.text 74 | else: 75 | return await app.send_edit( 76 | m, 77 | "Please reply to a link or give me the link as a suffix after command . . .", 78 | text_type=["mono"], 79 | delme=4, 80 | ) 81 | else: 82 | return await app.send_edit(m, "Something went wrong . . .") 83 | 84 | yt = YouTube(link) 85 | data = yt.streams.all() 86 | 87 | await app.send_edit(m, "**Trying to download **" + f"`{yt.title}`") 88 | for x in data: 89 | if ( 90 | x.type == "video" 91 | and x.resolution in ("720p" or "1080p") 92 | and x.mime_type == "video/mp4" 93 | ): 94 | try: 95 | loc = x.download() 96 | await app.send_video( 97 | m.chat.id, loc, caption="**Title:**\n\n" + yt.title 98 | ) 99 | await m.delete() 100 | break 101 | except Exception as e: 102 | await error(m, e) 103 | -------------------------------------------------------------------------------- /asterix/modules/carbon.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import urllib 4 | 5 | from pyrogram.types import Message 6 | from requests import post 7 | 8 | from asterix import app 9 | from asterix.helpers import gen 10 | 11 | app.CMD_HELP.update( 12 | { 13 | "carbon": ( 14 | "carbon", 15 | { 16 | "carbon [text]": "Get a carbon image with written text on it.", 17 | "carblist": "Get list of carbon colour codes.", 18 | }, 19 | ) 20 | } 21 | ) 22 | 23 | 24 | colour_code = { 25 | "aqua": "rgba(0, 255, 255, 100)", 26 | "red": "rgba(255, 0, 0, 100)", 27 | "blue": "rgba(0, 0, 255, 100)", 28 | "green": "rgba(0, 255, 0, 100)", 29 | "yellow": "rgba(255, 255, 0, 100)", 30 | "gold": "rgba(255, 215, 0, 100)", 31 | "orange": "rgba(255, 165, 0, 100)", 32 | "purple": "rgba(41, 5, 68, 100)", 33 | "black": "rgba(0, 0, 0, 100)", 34 | "white": "rgba(255, 255, 255, 100)", 35 | "lime": "rgba(0, 255, 0, 100)", 36 | "silver": "rgba(192, 192, 192, 100)", 37 | "maroon": "rgba(128, 0, 0, 100)", 38 | "olive": "rgba(128, 128, 0, 100)", 39 | "teal": "rgba(0, 128, 128, 100)", 40 | "navy": "rgba(0, 128, 128, 100)", 41 | "chocolate": "rgba(210, 105, 30, 100)", 42 | } 43 | 44 | 45 | @app.on_message(gen(["carbon", "carb"], allow=["sudo"])) 46 | async def carbon_handler(_, m: Message): 47 | cmd = m.command 48 | oldmsg = m # fixed for--> m = send_edit() replaces the variable 49 | if app.long(m) < 2: 50 | return await app.send_edit( 51 | m, 52 | f"Usage:\n\n`{app.PREFIX}carbon [colour] [text]`\n`{app.PREFIX}carbon [text]`\n\n**Note:** Default colour is aqua", 53 | delme=4, 54 | ) 55 | 56 | elif app.textlen(m) <= 4096: 57 | try: 58 | m = await app.send_edit(m, "creating carbon . . .", text_type=["mono"]) 59 | if cmd[1] in colour_code: 60 | text = oldmsg.text.split(None, 2)[2] 61 | colour = cmd[1] 62 | else: 63 | text = oldmsg.text.split(None, 1)[1] 64 | colour = "aqua" 65 | await create_carbon(m, text=text, colour=colour) 66 | except Exception as e: 67 | await app.error(m, e) 68 | elif app.textlen(m) > 4096: 69 | await app.send_edit(m, "The text is too long !", delme=2) 70 | 71 | 72 | @app.on_message(gen("carblist", allow=["sudo"])) 73 | async def carblist_handler(_, m: Message): 74 | clist = [f"`{x}`" for x in list(colour_code.keys())] 75 | await app.send_edit(m, "**COLOUR CODES:**\n\n" + "\n".join(clist)) 76 | 77 | 78 | async def create_carbon(m: Message, text, colour): 79 | reply = m.reply_to_message 80 | json = { 81 | "backgroundColor": f"{colour_code.get(colour)}", 82 | "theme": "Dracula", 83 | "exportSize": "4x", 84 | } 85 | json["code"] = urllib.parse.quote(text) 86 | json["language"] = "Auto" 87 | ApiUrl = "http://carbonnowsh.herokuapp.com" 88 | text = post(ApiUrl, json=json, stream=True) 89 | filename = "carbon_image.png" 90 | if text.status_code == 200: 91 | text.raw.decode_content = True 92 | with open(filename, "wb") as f: 93 | shutil.copyfileobj(text.raw, f) 94 | f.close() 95 | reply_msg_id = reply.message_id if reply else None 96 | await app.send_document( 97 | m.chat.id, 98 | filename, 99 | caption=f"**Carbon Made by:** {app.UserMention()}", 100 | reply_to_message_id=reply_msg_id, 101 | ) 102 | await m.delete() 103 | if os.path.exists(f"./{filename}"): 104 | os.remove(filename) 105 | else: 106 | await app.send_edit( 107 | m, "Image Couldn't be retreived.", delme=4, text_type=["mono"] 108 | ) 109 | -------------------------------------------------------------------------------- /asterix/plugins/inlinequery.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters 2 | from pyrogram.types import ( 3 | InlineKeyboardButton, 4 | InlineKeyboardMarkup, 5 | InlineQueryResultArticle, 6 | InlineQueryResultPhoto, 7 | InputTextMessageContent, 8 | ) 9 | 10 | from asterix import app 11 | 12 | settings = app.BuildKeyboard( 13 | (["• Settings •", "open-settings-dex"], ["• Modules •", "asterix-dex-2"]) 14 | ) 15 | extra = app.BuildKeyboard( 16 | (["• Extra •", "open-extra-dex"], ["• Stats •", "open-stats-dex"]) 17 | ) 18 | about = app.BuildKeyboard(([["About", "open-about-dex"]])) 19 | close = app.BuildKeyboard(([["Close", "close-dex"]])) 20 | approve = app.BuildKeyboard(([["Approve", "approve-user"]])) 21 | global_command = app.BuildKeyboard(([["• Global commands •", "global-commands"]])) 22 | home_back = app.BuildKeyboard((["Home", "close-dex"], ["Back", "open-start-dex"])) 23 | 24 | 25 | # via bot messages 26 | @app.bot.on_inline_query(filters.user(app.id)) 27 | def inline_result(_, inline_query): 28 | query = inline_query.query 29 | if query.startswith("#p0e3r4m8i8t5"): 30 | inline_query.answer( 31 | results=[ 32 | InlineQueryResultPhoto( 33 | photo_url=app.PmpermitPic(), 34 | title="asterix security system", 35 | description="This is asterix security system, it helps you to stop spammers from spamming in your dm.", 36 | caption=app.PmpermitText(), 37 | parse_mode="combined", 38 | reply_markup=InlineKeyboardMarkup([approve]), 39 | ) 40 | ], 41 | cache_time=1, 42 | ) 43 | elif query.startswith("#t5r4o9nn6"): 44 | inline_query.answer( 45 | results=[ 46 | InlineQueryResultPhoto( 47 | photo_url=app.BotPic(), 48 | title="Introduction to asterix", 49 | description="This is the asterix helpdex menu.", 50 | caption="**Dex:** Home\n\n**Description:** This is your helpdex use this to navigate in different sub dex, guidence and information is given in each dex.", 51 | parse_mode="combined", 52 | reply_markup=InlineKeyboardMarkup([settings, extra, about, close]), 53 | ) 54 | ], 55 | cache_time=1, 56 | ) 57 | elif query.startswith("#i2l8v3"): 58 | inline_query.answer( 59 | results=[ 60 | InlineQueryResultPhoto( 61 | photo_url=app.ialive_pic(), 62 | title="Inline alive", 63 | description="This is same as alive command, the difference is that this command have inline button.", 64 | caption=f"**⛊ Inline Status:**\n\n**⟐** {app.USER_BIO}\n\n**⟜ Owner**: [{app.name}](https://t.me/{app.username})\n**⟜ asterix:** `{app.userbot_version}`\n**⟜ Python:** `{app.python_version}`\n⟜ **Pyrogram:** `{app.pyrogram_version}`\n⟜ **uptime:** `{app.uptime()}\n\n", 65 | parse_mode="combined", 66 | reply_markup=InlineKeyboardMarkup([home_back]), 67 | ) 68 | ], 69 | cache_time=1, 70 | ) 71 | elif query.startswith("#q7o5e"): 72 | inline_query.answer( 73 | results=[ 74 | InlineQueryResultArticle( 75 | title="Inline quotes", 76 | input_message_content=InputTextMessageContent(app.quote()), 77 | description="Get infinite anime character quotes through this inline loop button.", 78 | reply_markup=InlineKeyboardMarkup( 79 | [ 80 | [ 81 | InlineKeyboardButton( 82 | "More", callback_data="more-anime-quotes" 83 | ) 84 | ], 85 | ] 86 | ), 87 | ) 88 | ], 89 | cache_time=1, 90 | ) 91 | -------------------------------------------------------------------------------- /asterix/modules/alive.py: -------------------------------------------------------------------------------- 1 | from pyrogram.errors import BotInlineDisabled 2 | from pyrogram.types import Message 3 | 4 | from asterix import app 5 | from asterix.helpers import gen 6 | 7 | app.CMD_HELP.update( 8 | { 9 | "alive": ( 10 | "alive", 11 | { 12 | "alive": "Normal alive, in which you will get userbot status without inline buttons.", 13 | "ialive": "Inline alive that contains your & your userbot status.", 14 | "qt": "Get inline quotes with a inline 'more' button.", 15 | }, 16 | ) 17 | } 18 | ) 19 | 20 | 21 | @app.on_message(gen("alive", allow=["sudo"]), group=0) 22 | async def alive_handler(_, m: Message): 23 | try: 24 | m = await app.send_edit(m, ". . .", text_type=["mono"]) 25 | 26 | alive_msg = f"\n" 27 | if app.UserBio(): 28 | alive_msg += f"⦿ I Am Running Perfect.\n\n" 29 | alive_msg += f"⟜ **Owner:** {app.UserMention()}\n" 30 | alive_msg += f"⟜ **Asterix:** `{app.userbot_version}`\n" 31 | alive_msg += f"⟜ **Python:** `{app.python_version}`\n" 32 | alive_msg += f"⟜ **Pyrogram:** `{app.pyrogram_version}`\n" 33 | alive_msg += f"⟜ **Uptime:** {app.uptime()}\n\n" 34 | 35 | await m.delete() 36 | pic = app.UserPic() 37 | 38 | if (pic) and (pic.endswith(".mp4" or ".mkv" or ".gif")): 39 | await app.send_video( 40 | m.chat.id, pic, caption=alive_msg, parse_mode="markdown" 41 | ) 42 | elif (pic) and (pic.endswith(".jpg" or ".jpeg" or ".png")): 43 | await app.send_photo( 44 | m.chat.id, pic, caption=alive_msg, parse_mode="markdown" 45 | ) 46 | elif not pic: 47 | await app.send_edit( 48 | m, 49 | alive_msg, 50 | disable_web_page_preview=True, 51 | parse_mode="markdown", 52 | ) 53 | except Exception as e: 54 | await app.error(m, e) 55 | 56 | 57 | @app.on_message(gen("ialive", allow=["sudo"]), group=1) 58 | async def inlinealive_handler(_, m: Message): 59 | m = await app.send_edit(m, ". . .", text_type=["mono"]) 60 | try: 61 | result = await app.get_inline_bot_results(app.bot.username, "#i2l8v3") 62 | except BotInlineDisabled: 63 | await app.send_edit( 64 | m, "Turning inline mode to on, wait . . .", text_type=["mono"] 65 | ) 66 | await app.toggle_inline(m) 67 | result = await app.get_inline_bot_results(app.bot.username, "#i2l8v3") 68 | 69 | if result: 70 | await app.send_inline_bot_result( 71 | m.chat.id, 72 | query_id=result.query_id, 73 | result_id=result.results[0].id, 74 | disable_notification=True, 75 | hide_via=True, 76 | ) 77 | await m.delete() 78 | else: 79 | await app.send_edit( 80 | m, "Something went wrong, please try again later . . .", delme=2 81 | ) 82 | 83 | 84 | @app.on_message(gen(["quote", "qt"], allow=["sudo"]), group=2) 85 | async def inlinequote_handler(_, m: Message): 86 | try: 87 | m = await app.send_edit(m, ". . .", text_type=["mono"]) 88 | try: 89 | result = await app.get_inline_bot_results(app.bot.username, "#q7o5e") 90 | except BotInlineDisabled: 91 | await app.send_edit( 92 | m, 93 | "Inline mode off. Turning inline mode on, wait . . .", 94 | text_type=["mono"], 95 | ) 96 | await asyncio.sleep(1) 97 | await app.toggle_inline(m) 98 | result = await app.get_inline_bot_results(app.bot.username, "#q7o5e") 99 | 100 | if result: 101 | await app.send_inline_bot_result( 102 | m.chat.id, 103 | query_id=result.query_id, 104 | result_id=result.results[0].id, 105 | disable_notification=True, 106 | hide_via=True, 107 | ) 108 | await m.delete() 109 | else: 110 | await app.send_edit( 111 | m, "Please try again later !", delme=2, text_type=["mono"] 112 | ) 113 | except Exception as e: 114 | await app.error(m, e) 115 | -------------------------------------------------------------------------------- /asterix/database/postgres/notes_sql.py: -------------------------------------------------------------------------------- 1 | import threading 2 | 3 | from sqlalchemy import Column, Integer, UnicodeText 4 | 5 | from . import BASE, SESSION 6 | 7 | 8 | class NOTES(BASE): 9 | __tablename__ = "notes" 10 | 11 | user_id = Column(Integer, primary_key=True) 12 | name = Column(UnicodeText, primary_key=True) 13 | value = Column(UnicodeText, nullable=False) 14 | msgtype = Column(Integer, default=0) 15 | file = Column(UnicodeText) 16 | file_ref = Column(UnicodeText) 17 | message_id = Column(Integer) 18 | 19 | def __init__(self, user_id, name, value, msgtype, file, file_ref, message_id): 20 | self.user_id = user_id 21 | self.name = name 22 | self.value = value 23 | self.msgtype = msgtype 24 | self.file = file 25 | self.file_ref = file_ref 26 | self.message_id = message_id 27 | 28 | def __repr__(self): 29 | return "" % self.name 30 | 31 | 32 | NOTES.__table__.create(checkfirst=True) 33 | 34 | INSERTION_LOCK = threading.RLock() 35 | 36 | SELF_NOTES = {} 37 | 38 | 39 | class NOTESSQL(object): 40 | # save a note 41 | def save_selfnote( 42 | self, 43 | user_id, 44 | note_name, 45 | note_data, 46 | msgtype, 47 | file=None, 48 | file_ref=None, 49 | message_id=0, 50 | ): 51 | global SELF_NOTES 52 | with INSERTION_LOCK: 53 | prev = SESSION.query(NOTES).get((user_id, note_name)) 54 | if prev: 55 | SESSION.delete(prev) 56 | note = NOTES( 57 | user_id, 58 | note_name, 59 | note_data, 60 | msgtype=int(msgtype), 61 | file=file, 62 | file_ref=file_ref, 63 | message_id=message_id, 64 | ) 65 | SESSION.add(note) 66 | SESSION.commit() 67 | 68 | if not SELF_NOTES.get(user_id): 69 | SELF_NOTES[user_id] = {} 70 | SELF_NOTES[user_id][note_name] = { 71 | "value": note_data, 72 | "type": msgtype, 73 | "file": file, 74 | "file_ref": file_ref, 75 | "message_id": message_id, 76 | } 77 | 78 | # get a saved note 79 | def get_selfnote(self, user_id, note_name): 80 | if not SELF_NOTES.get(user_id): 81 | SELF_NOTES[user_id] = {} 82 | return SELF_NOTES[user_id].get(note_name) 83 | 84 | # get list of saved notes 85 | def get_all_selfnotes(self, user_id): 86 | if not SELF_NOTES.get(user_id): 87 | SELF_NOTES[user_id] = {} 88 | return None 89 | allnotes = list(SELF_NOTES[user_id]) 90 | allnotes.sort() 91 | return allnotes 92 | 93 | # get all saved notes with inline buttons 94 | def get_all_selfnote_inline(self, user_id): 95 | if not SELF_NOTES.get(user_id): 96 | SELF_NOTES[user_id] = {} 97 | return None 98 | # Sorting 99 | allnotes = {} 100 | sortnotes = list(SELF_NOTES[user_id]) 101 | sortnotes.sort() 102 | for x in sortnotes: 103 | allnotes[x] = SELF_NOTES[user_id][x] 104 | return allnotes 105 | 106 | # remove a saved note 107 | def rm_selfnote(self, user_id, note_name): 108 | global SELF_NOTES 109 | with INSERTION_LOCK: 110 | note = SESSION.query(NOTES).get((user_id, note_name)) 111 | if note: 112 | SESSION.delete(note) 113 | SESSION.commit() 114 | SELF_NOTES[user_id].pop(note_name) 115 | return True 116 | 117 | else: 118 | SESSION.close() 119 | return False 120 | 121 | # load notes while startup 122 | def load_allnotes(): 123 | global SELF_NOTES 124 | getall = SESSION.query(NOTES).distinct().all() 125 | for x in getall: 126 | if not SELF_NOTES.get(x.user_id): 127 | SELF_NOTES[x.user_id] = {} 128 | SELF_NOTES[x.user_id][x.name] = { 129 | "value": x.value, 130 | "type": x.msgtype, 131 | "file": x.file, 132 | "file_ref": x.file_ref, 133 | "message_id": x.message_id, 134 | } 135 | 136 | 137 | NOTESSQL.load_allnotes() 138 | -------------------------------------------------------------------------------- /asterix/database/postgres/pmpermit_sql.py: -------------------------------------------------------------------------------- 1 | import threading 2 | 3 | from sqlalchemy import Column, Integer, String 4 | 5 | from . import BASE, SESSION 6 | 7 | 8 | # save user ids in whitelists 9 | class PMTABLE(BASE): 10 | __tablename__ = "approve" 11 | 12 | user_id = Column(Integer, primary_key=True) 13 | boolvalue = Column(String) 14 | 15 | def __init__(self, user_id, boolvalue): 16 | self.user_id = user_id 17 | self.boolvalue = boolvalue 18 | 19 | 20 | # save warn msg ids 21 | class MSGID(BASE): 22 | __tablename__ = "pm msg id" 23 | 24 | user_id = Column(Integer, primary_key=True) 25 | msg_id = Column(Integer) 26 | 27 | def __init__(self, user_id, msg_id): 28 | self.user_id = user_id 29 | self.msg_id = msg_id 30 | 31 | 32 | # save warn counts 33 | class DISAPPROVE(BASE): 34 | __tablename__ = "disapprove" 35 | 36 | user_id = Column(Integer, primary_key=True) 37 | warn_count = Column(Integer) 38 | 39 | def __init__(self, user_id, warn_count): 40 | self.user_id = user_id 41 | self.warn_count = warn_count 42 | 43 | 44 | PMTABLE.__table__.create(checkfirst=True) 45 | MSGID.__table__.create(checkfirst=True) 46 | DISAPPROVE.__table__.create(checkfirst=True) 47 | 48 | INSERTION_LOCK = threading.RLock() 49 | 50 | 51 | class PMPERMITSQL(object): 52 | # add message id of a user 53 | def set_msgid(self, user_id, msg_id): 54 | with INSERTION_LOCK: 55 | try: 56 | user = SESSION.query(MSGID).get(user_id) 57 | if not user: 58 | user = MSGID(user_id, msg_id) 59 | else: 60 | user.msg_id = msg_id 61 | SESSION.merge(user) 62 | SESSION.commit() 63 | finally: 64 | SESSION.close() 65 | 66 | # get warn message id 67 | def get_msgid(self, user_id): 68 | try: 69 | user = SESSION.query(MSGID).get(user_id) 70 | msg_id = None 71 | if user: 72 | msg_id = user.msg_id 73 | return msg_id 74 | finally: 75 | SESSION.close() 76 | 77 | # add user id to whitelist 78 | def set_whitelist(self, user_id, boolvalue): 79 | with INSERTION_LOCK: 80 | user = SESSION.query(PMTABLE).get(user_id) 81 | try: 82 | if not user: 83 | user = PMTABLE(user_id, boolvalue) 84 | else: 85 | user.boolvalue = str(boolvalue) 86 | SESSION.add(user) 87 | SESSION.commit() 88 | finally: 89 | SESSION.close() 90 | return user_id 91 | 92 | # remove user id from whitelist 93 | def del_whitelist(self, user_id): 94 | with INSERTION_LOCK: 95 | user = SESSION.query(PMTABLE).get(user_id) 96 | try: 97 | if user: 98 | SESSION.delete(user) 99 | SESSION.commit() 100 | finally: 101 | SESSION.close() 102 | return False 103 | 104 | # get whitelist (approved) 105 | def get_whitelist(self, user_id): 106 | user = SESSION.query(PMTABLE).get(user_id) 107 | rep = "" 108 | if user: 109 | rep = str(user.boolvalue) 110 | SESSION.close() 111 | return rep 112 | 113 | # warn table func 114 | def set_warn(self, user_id, warn_count): 115 | with INSERTION_LOCK: 116 | try: 117 | user = SESSION.query(DISAPPROVE).get(user_id) 118 | if not user: 119 | user = DISAPPROVE(user_id, warn_count) 120 | else: 121 | user.warn_count = warn_count 122 | SESSION.merge(user) 123 | SESSION.commit() 124 | finally: 125 | SESSION.close() 126 | 127 | # get warn func 128 | def get_warn(self, user_id): 129 | user = SESSION.query(DISAPPROVE).get(user_id) 130 | rep = "" 131 | if user: 132 | rep = str(user.warn_count) 133 | SESSION.close() 134 | return rep 135 | 136 | # del warn func 137 | def del_warn(self, user_id): 138 | with INSERTION_LOCK: 139 | user = SESSION.query(DISAPPROVE).get(user_id) 140 | try: 141 | if user: 142 | SESSION.delete(user) 143 | SESSION.commit() 144 | finally: 145 | SESSION.close() 146 | return False 147 | -------------------------------------------------------------------------------- /asterix/modules/group.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | from pyrogram.raw import functions 4 | from pyrogram.types import Message 5 | 6 | from asterix import app, gen 7 | 8 | app.CMD_HELP.update( 9 | { 10 | "group": ( 11 | "group", 12 | { 13 | "bgroup [group name]": "Creates a basic group.", 14 | "sgroup [group name]": "Creates a super group.", 15 | "unread": "Mark a chat as unread in your telegram folders.", 16 | "channel [channel name]": "Create a channel through this command.", 17 | }, 18 | ) 19 | } 20 | ) 21 | 22 | 23 | @app.on_message(gen(["bgroup", "bgp"], allow=["sudo"])) 24 | async def basicgroup_handler(_, m: Message): 25 | grpname = None 26 | users = None 27 | if app.long(m) == 1: 28 | return await app.send_edit( 29 | m, f"Usage: `{app.PREFIX}bgroup mygroupname`", delme=4 30 | ) 31 | elif app.long(m) > 1: 32 | grpname = m.text.split(None, 1)[1] 33 | users = "@KushinaRobot" 34 | elif app.long(m) > 2: 35 | grpname = m.text.split(None, 1)[1] 36 | users = m.text.split(None, 2)[2].split() 37 | else: 38 | grpname = False 39 | users = "@KushinaRobot" # required 40 | 41 | try: 42 | if grpname: 43 | m = await app.send_edit(m, f"Creating a new basic group: `{grpname}`") 44 | group = await app.create_group(title=f"{grpname}", users=users) 45 | await app.send_edit( 46 | m, 47 | f"**Created a new basic group:** [{grpname}]({(await app.get_chat(group.id)).invite_link})", 48 | ) 49 | else: 50 | await app.send_edit( 51 | m, "No group name is provided.", text_type=["mono"], delme=4 52 | ) 53 | except Exception as e: 54 | await app.error(m, e) 55 | 56 | 57 | @app.on_message(gen(["sgroup", "sgp"], allow=["sudo"])) 58 | async def supergroup_handler(_, m: Message): 59 | grpname = None 60 | about = None 61 | if app.long(m) == 1: 62 | return await app.send_edit( 63 | m, f"`Usage: {app.PREFIX}sgroup mygroupname`", delme=4 64 | ) 65 | elif app.long(m) > 1: 66 | grpname = m.text.split(None, 1)[1] 67 | about = "" 68 | elif app.long(m) > 2: 69 | grpname = m.text.split(None, 1)[1] 70 | about = m.text.split(None, 2)[2] 71 | else: 72 | grpname = False 73 | about = "" 74 | 75 | try: 76 | if grpname: 77 | m = await app.send_edit(m, f"Creating a new super group: `{grpname}`") 78 | group = await app.create_supergroup(title=f"{grpname}", description=about) 79 | await app.send_edit( 80 | m, 81 | f"**Created a new super group:** [{grpname}]({(await app.get_chat(group.id)).invite_link})", 82 | ) 83 | else: 84 | await app.send_edit( 85 | m, "No group name is provided.", text_type=["mono"], delme=4 86 | ) 87 | except Exception as e: 88 | await app.error(m, e) 89 | 90 | 91 | @app.on_message(gen(["unread", "un"], allow=["sudo"])) 92 | async def unreadchat_handler(_, m: Message): 93 | try: 94 | await asyncio.gather( 95 | m.delete(), 96 | app.send( 97 | functions.messages.MarkDialogUnread( 98 | peer=await app.resolve_peer(m.chat.id), unread=True 99 | ) 100 | ), 101 | ) 102 | except Exception as e: 103 | await app.error(m, e) 104 | 105 | 106 | @app.on_message(gen("channel", allow=["sudo"])) 107 | async def channel_handler(_, m: Message): 108 | chname = None 109 | about = None 110 | if app.long(m) == 1: 111 | return await app.send_edit( 112 | m, f"Usage: `{app.PREFIX}channel [channel name]`", delme=4 113 | ) 114 | 115 | elif app.long(m) > 1: 116 | chname = m.text.split(None, 1)[1] 117 | about = "" 118 | elif app.long(m) > 2: 119 | chname = m.text.split(None, 1)[1] 120 | about = m.text.split(None, 2)[2] 121 | 122 | try: 123 | if chname: 124 | m = await app.send_edit(m, f"Creating your channel: `{chname}`") 125 | response = await app.create_channel(title=f"{chname}", description=about) 126 | if response: 127 | await app.send_edit( 128 | m, 129 | f"**Created a new channel:** [{chname}]({(await app.get_chat(response.id)).invite_link})", 130 | disable_web_page_preview=True, 131 | ) 132 | else: 133 | await app.send_edit(m, "Couldn't create a channel.") 134 | except Exception as e: 135 | await app.error(m, e) 136 | -------------------------------------------------------------------------------- /asterix/modules/afk.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from pyrogram import filters 4 | from pyrogram.types import Message 5 | 6 | from asterix import app 7 | from asterix.helpers import gen 8 | 9 | app.CMD_HELP.update( 10 | { 11 | "afk": ( 12 | "afk", 13 | {"afk": "leave your chats untouchable, stop yourself from chatting . . ."}, 14 | ) 15 | } 16 | ) 17 | 18 | 19 | @app.on_message(gen("afk", allow=["sudo"]), group=0) 20 | async def go_offline(_, m: Message): 21 | try: 22 | start = int(time.time()) 23 | if app.long(m) >= 2: 24 | reason = m.text.split(None, 1)[1] 25 | app.set_afk(True, reason, start) # with reason 26 | await app.send_edit( 27 | m, f"{app.UserMention()} is now Offline.\nBecause: {reason}", delme=2 28 | ) 29 | 30 | elif app.long(m) == 1 and app.long(m) < 4096: 31 | if app.getdv("AFK_TEXT"): 32 | reason = app.getdv("AFK_TEXT") 33 | elif app.AFK_TEXT: 34 | reason = app.AFK_TEXT # config.AFK_TEXT 35 | else: 36 | reason = False 37 | 38 | if reason: 39 | app.set_afk(True, reason, start) # with reason 40 | await app.send_edit( 41 | m, 42 | f"{app.UserMention()} is now offline.\nBecause: {reason}", 43 | delme=2, 44 | ) 45 | else: 46 | app.set_afk(True, "", start) # without reason 47 | await app.send_edit(m, f"{app.UserMention()} is now offline.", delme=2) 48 | 49 | except Exception as e: 50 | await app.error(m, e) 51 | 52 | 53 | # notify mentioned users 54 | @app.on_message( 55 | ~filters.bot & ~filters.channel & filters.private | filters.mentioned, group=1 56 | ) 57 | async def offline_mention(_, m: Message): 58 | try: 59 | get = app.get_afk() 60 | if get and get["afk"]: 61 | if m.from_user.id == app.id: 62 | return 63 | 64 | if "-" in str(m.chat.id): 65 | cid = str(m.chat.id)[4:] 66 | else: 67 | cid = str(m.chat.id) 68 | 69 | end = int(time.time()) 70 | otime = app.GetReadableTime(end - get["afktime"]) 71 | if get["reason"] and get["afktime"]: 72 | msg = await app.send_message( 73 | m.chat.id, 74 | "Sorry {} is currently offline !\n**Time:** {}\n**Because:** {}".format( 75 | app.UserMention(), otime, get["reason"] 76 | ), 77 | reply_to_message_id=m.message_id, 78 | ) 79 | await app.delete(msg, 3) 80 | elif get["afktime"] and not get["reason"]: 81 | msg = await app.send_message( 82 | m.chat.id, 83 | "Sorry {} is currently offline !\n**Time:** {}".format( 84 | app.UserMention(), otime 85 | ), 86 | reply_to_message_id=m.message_id, 87 | ) 88 | await app.delete(msg, 3) 89 | content, message_type = app.GetMessageType(m) 90 | if message_type == app.TEXT: 91 | if m.text: 92 | text = m.text 93 | else: 94 | text = m.caption 95 | else: 96 | text = message_type.name 97 | 98 | await app.send_message( 99 | app.LOG_CHAT, 100 | f"""#mention\n\n 101 | **User:** `{m.from_user.first_name}`\n 102 | **Id:** {m.from_user.id}\n 103 | **Group:** `{m.chat.title}`\n 104 | **Message:** `{text[:4096]}`\n 105 | [Go to message](https://t.me/c/{cid}/{m.message_id}) 106 | """, 107 | parse_mode="markdown", 108 | ) 109 | except Exception as e: 110 | await app.error(m, e) 111 | 112 | 113 | # come back online 114 | @app.on_message(filters.me & ~filters.channel, group=2) 115 | async def afkme_handler(_, m: Message): 116 | try: 117 | # don't break afk while going offline 118 | if m.text: 119 | if m.text.startswith(f"{app.PREFIX}afk"): 120 | return 121 | elif "#afk" in m.text: 122 | return 123 | elif m.media: 124 | pass 125 | 126 | get = app.get_afk() 127 | if get and get["afk"] and filters.outgoing: 128 | end = int(time.time()) 129 | afk_time = app.GetReadableTime(end - get["afktime"]) 130 | msg = await app.send_message( 131 | m.chat.id, 132 | f"{app.UserMention()} is now online !\n**Offline Time:** `{afk_time}`", 133 | ) 134 | app.set_afk(False, "", 0) 135 | 136 | except Exception as e: 137 | await app.error(m, e) 138 | -------------------------------------------------------------------------------- /asterix/modules/help.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from pyrogram import filters 4 | from pyrogram.errors.exceptions.bad_request_400 import BotInlineDisabled 5 | from pyrogram.types import CallbackQuery, Message 6 | 7 | from asterix import app 8 | from asterix.helpers import gen 9 | 10 | app.CMD_HELP.update( 11 | { 12 | "help": ( 13 | "help", 14 | { 15 | "help [ module name ]": "Get commands info of that plugin.", 16 | "help": "Get your inline help dex.", 17 | "inline": "Toggle inline mode to On or Off of your bot through @BotFather", 18 | "mods": "Get list of available module names", 19 | "plugs": "Get list of available plugin names", 20 | }, 21 | ) 22 | } 23 | ) 24 | 25 | 26 | helpdex_ids = [ 27 | x 28 | for x in app.getdv("DELETE_DEX_ID").strip("[]").split("," " ") 29 | if bool(app.getdv("DELETE_DEX_ID")) 30 | ] 31 | 32 | 33 | @app.bot.on_callback_query(filters.regex("delete-dex")) 34 | @app.alert_user 35 | async def delete_helpdex(_, cb: CallbackQuery): 36 | if not bool(helpdex_ids): 37 | await cb.answer( 38 | "This message is expired, hence it can't be deleted !", 39 | show_alert=True, 40 | ) 41 | else: 42 | try: 43 | for x in helpdex_ids[1:]: # list 44 | for y in x: # dicts 45 | if y in ("None", "none", None): 46 | continue 47 | await app.delete_messages(int(y), x[y]) 48 | app.deldv("DELETE_DEX_ID") # empty var 49 | except Exception as e: 50 | app.log.error(e) 51 | 52 | 53 | @app.on_message(gen("help", allow=["sudo"])) 54 | async def helpdex_handler(_, m: Message): 55 | args = m.command if app.long(m) > 1 else False 56 | 57 | try: 58 | if args is False: 59 | m = await app.send_edit(m, ". . .", text_type=["mono"]) 60 | result = await app.get_inline_bot_results(app.bot.username, "#t5r4o9nn6") 61 | if result: 62 | await m.delete() 63 | info = await app.send_inline_bot_result( 64 | m.chat.id, 65 | query_id=result.query_id, 66 | result_id=result.results[0].id, 67 | disable_notification=True, 68 | hide_via=True, 69 | ) 70 | 71 | if m.chat.type in ["bot", "private"]: 72 | app.setdv( 73 | "DELETE_DEX_ID", 74 | helpdex_ids.append({m.chat.id: info.updates[1].message.id}), 75 | ) 76 | else: 77 | app.setdv( 78 | "DELETE_DEX_ID", 79 | helpdex_ids.append({m.chat.id: info.updates[2].message.id}), 80 | ) 81 | else: 82 | await app.send_edit( 83 | m, 84 | "Please check your bots inline mode is on or not . . .", 85 | delme=3, 86 | text_type=["mono"], 87 | ) 88 | elif args: 89 | 90 | module_help = await app.data(args[1]) 91 | if not module_help: 92 | await app.send_edit( 93 | m, 94 | f"Invalid module name specified, use `{app.PREFIX}mods` to get list of modules", 95 | delme=3, 96 | ) 97 | else: 98 | await app.send_edit( 99 | m, f"**MODULE:** {args[1]}\n\n" + "".join(module_help) 100 | ) 101 | else: 102 | await app.send_edit(m, "Try again later !", text_type=["mono"], delme=3) 103 | except BotInlineDisabled: 104 | await app.toggle_inline(m) 105 | await help_menu(client, m) 106 | except Exception as e: 107 | await app.error(m, e) 108 | 109 | 110 | # get all module name 111 | @app.on_message(gen("mods", allow=["sudo"])) 112 | async def allmodules_handler(_, m: Message): 113 | store = [] 114 | store.clear() 115 | for x in os.listdir("asterix/modules/"): 116 | if not x in ["__pycache__", "__init__.py"]: 117 | store.append(x + "\n") 118 | 119 | await app.send_edit(m, "**MODULES OF USERBOT🤖:**\n\n" + "".join(store)) 120 | 121 | 122 | # get all plugins name 123 | @app.on_message(gen("plugs", allow=["sudo"])) 124 | async def allplugins_handler(_, m: Message): 125 | store = [] 126 | store.clear() 127 | for x in os.listdir("asterix/plugins/"): 128 | if not x in ["__pycache__", "__init__.py"]: 129 | store.append(x + "\n") 130 | 131 | await app.send_edit(m, "**PLUGINS OF BOT:**\n\n" + "".join(store)) 132 | 133 | 134 | @app.on_message(gen("inline", allow=["sudo"])) 135 | async def toggleinline_handler(_, m: Message): 136 | return await app.toggle_inline(m) 137 | -------------------------------------------------------------------------------- /asterix/helpers/filters.py: -------------------------------------------------------------------------------- 1 | import re 2 | from typing import List, Pattern, Union 3 | 4 | from pyrogram import Client 5 | from pyrogram.filters import create 6 | from pyrogram.types import CallbackQuery, InlineQuery, Message, Update 7 | 8 | 9 | # custom regex filter 10 | def regex(pattern: Union[str, Pattern], flags: int = 0, allow: list = []): 11 | async def func(flt, client: Client, update: Update): 12 | 13 | # work for -> sudo & bot owner if sudo 14 | if "sudo" in allow: 15 | if update.from_user and not ( 16 | update.from_user.is_self or update.from_user.id in client.SudoUsers() 17 | ): 18 | return False 19 | 20 | # allow some specific commands to sudos 21 | if update.from_user and update.from_user.id in client.SudoUsers(): 22 | if update.text or update.caption and not "full" in client.SudoCmds(): 23 | for x in pattern.split(): # list of texts 24 | if not x in client.SudoCmds(): 25 | return False 26 | 27 | # work only for -> bot owner if not sudo 28 | elif not "sudo" in allow: 29 | if update.from_user and not update.from_user.is_self: 30 | return False 31 | 32 | # work for -> forwarded message 33 | if not "forward" in allow: 34 | if update.forward_date: 35 | return False 36 | 37 | # work for -> messages in channel 38 | if not "channel" in allow: 39 | if update.chat.type == "channel": 40 | return False 41 | 42 | # work for -> edited message 43 | if not "edited" in allow: 44 | if update.edit_date: 45 | return False 46 | 47 | if isinstance(update, Message): 48 | value = update.text or update.caption 49 | elif isinstance(update, CallbackQuery): 50 | value = update.data 51 | elif isinstance(update, InlineQuery): 52 | value = update.query 53 | else: 54 | raise ValueError(f"Regex filter doesn't work with {type(update)}") 55 | 56 | if value: 57 | update.matches = list(flt.p.finditer(value)) or None 58 | 59 | return bool(update.matches) 60 | 61 | return create( 62 | func, 63 | "RegexCommandFilter", 64 | p=pattern if isinstance(pattern, Pattern) else re.compile(pattern, flags), 65 | ) 66 | 67 | 68 | # custom command filter 69 | def gen( 70 | commands: Union[str, List[str]], 71 | prefixes: Union[str, List[str]] = [], 72 | case_sensitive: bool = True, 73 | allow: list = [], 74 | ): 75 | 76 | # modified function of pyrogram.filters.command 77 | async def func(flt, client: Client, message: Message): 78 | 79 | try: 80 | text = message.text or message.caption or None 81 | 82 | if not text: 83 | return False 84 | 85 | message.command = None 86 | 87 | user = message.from_user if message.from_user else None 88 | 89 | if not user: 90 | return False 91 | 92 | message_owner = ( 93 | "owner" 94 | if user.is_self 95 | else "sudo" 96 | if user.id in client.SudoUsers() 97 | else None 98 | ) 99 | 100 | if not message_owner: 101 | return False 102 | 103 | if message.forward_date: # forwarded messages can't be edited 104 | return False 105 | 106 | flt.prefixes = client.MyPrefix() # workaround 107 | 108 | for prefix in flt.prefixes: 109 | if not text.startswith(prefix): 110 | continue 111 | 112 | cmd = text.split()[0][1:] 113 | if cmd in flt.commands: 114 | message.command = [cmd] + text.split()[1:] 115 | if message_owner == "sudo": 116 | if ( 117 | not client.SudoCmds() 118 | ): # empty config -> full command access to sudo 119 | return True 120 | 121 | if not cmd in client.SudoCmds(): 122 | return False 123 | 124 | return True 125 | 126 | return False 127 | except Exception as e: 128 | print(e) 129 | 130 | commands = commands if isinstance(commands, list) else [commands] 131 | commands = {c if case_sensitive else c.lower() for c in commands} 132 | 133 | prefixes = [] if prefixes is None else prefixes 134 | prefixes = prefixes if isinstance(prefixes, list) else [prefixes] 135 | prefixes = set(prefixes) if prefixes else {""} 136 | 137 | return create( 138 | func, 139 | "MessageCommandFilter", 140 | commands=commands, 141 | prefixes=prefixes, 142 | case_sensitive=case_sensitive, 143 | ) 144 | -------------------------------------------------------------------------------- /asterix/modules/filetools.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import zipfile 4 | 5 | from pyrogram.types import Message 6 | 7 | from asterix import app 8 | from asterix.helpers import gen 9 | 10 | app.CMD_HELP.update( 11 | { 12 | "zip": ( 13 | "zip", 14 | { 15 | "zip [reply to file]": "Zip a file and save it in your local directories.", 16 | "unzip [file path]": "Unzip a file and save it in your local directories.", 17 | "new [file name]": "Create a python file with your codes.", 18 | }, 19 | ) 20 | } 21 | ) 22 | 23 | 24 | def zipdir(dirName): 25 | dice = [] 26 | for root, directories, files in os.walk(dirName): 27 | for filename in files: 28 | filePath = os.path.join(root, filename) 29 | dice.append(filePath) 30 | return filePaths 31 | 32 | 33 | async def unzipfiles(zippath): 34 | foldername = zippath.split("/")[-1] 35 | extract_path = f"asterix/downloads/{foldername}" 36 | shutil.unpack_archive(zippath, extract_path) 37 | return extract_path 38 | 39 | 40 | @app.on_message(gen("zip", allow=["sudo"])) 41 | async def zip_handler(_, m: Message): 42 | reply = m.reply_to_message 43 | if not reply: 44 | return await app.send_edit( 45 | m, f"Reply to some media file . . .", text_type=["mono"], delme=4 46 | ) 47 | 48 | elif reply: 49 | if not reply.media: 50 | return await app.send_edit( 51 | m, "Reply to some media not text . . .", text_type=["mono"] 52 | ) 53 | 54 | m = await app.send_edit(m, "Zipping . . .", text_type=["mono"]) 55 | 56 | if app.TEMP_DICT: 57 | app.TEMP_DICT 58 | else: 59 | pass 60 | dl = await app.download_media(reply, block=False) 61 | zipfile.ZipFile(dl.replace("/app/downloads/", "") + ".zip", "w").write(dl) 62 | place = dl.replace("/app/downloads/", "") + ".zip" 63 | await app.send_edit( 64 | m, f"**Your file is compressed and saved here:** \n`{place}`" 65 | ) 66 | else: 67 | await app.send_edit( 68 | m, "Something went wrong . . .", delme=2, text_type=["mono"] 69 | ) 70 | 71 | 72 | @app.on_message(gen("unzip", allow=["sudo"])) 73 | async def unzip_handler(_, m: Message): 74 | if app.long(m) == 2: 75 | if app.long(m) <= 4096: 76 | loc = m.text.split(None, 1)[1] 77 | m = await app.send_edit(m, "Unzipping file . . .", text_type=["mono"]) 78 | extract_path = await unzipfiles(loc) 79 | await app.send_edit(m, f"File unzipped and saved here: `{extract_path}`") 80 | else: 81 | await app.send_edit(m, "Text is too long !", delme=2, text_type=["mono"]) 82 | else: 83 | await app.send_edit( 84 | m, 85 | "Give me the file path to unzip the file . . .", 86 | delme=4, 87 | text_type=["mono"], 88 | ) 89 | 90 | 91 | @app.on_message(gen("new", allow=["sudo"])) 92 | async def createfile_handler(app, m: Message): 93 | reply = m.reply_to_message 94 | mytext = "Making file . . ." 95 | oldmsg = m # workaround 96 | 97 | try: 98 | if app.textlen(m) > 4096: 99 | return await app.send_edit( 100 | m, 101 | "The message is too long. (it must be <= 4096)", 102 | delme=4, 103 | text_type=["mono"], 104 | ) 105 | 106 | if app.long(m) == 1: 107 | return await app.send_edit( 108 | m, 109 | "Give me filename & content of file after command.", 110 | text_type=["mono"], 111 | delme=4, 112 | ) 113 | 114 | if reply and app.long(m) >= 2: 115 | name = oldmsg.text.split(None, 1)[1] 116 | m = await app.send_edit(m, mytext, text_type=["mono"]) 117 | text = reply.text or reply.caption 118 | await app.create_file(message=m, filename=name, content=text, send=True) 119 | 120 | # if replied to text without file name 121 | elif not reply and app.long(m) >= 3: 122 | m = await app.send_edit(m, mytext, text_type=["mono"]) 123 | name = oldmsg.text.split(None, 1)[1] 124 | text = oldmsg.text.split(None, 2)[2] 125 | await app.create_file( 126 | message=m, filename="file.py", content=text, send=True 127 | ) 128 | 129 | # if replied to text with file name 130 | elif not reply and app.long(m) <= 2: 131 | await app.send_edit( 132 | m, 133 | "Are you dumb, give me the file contents with the file name.", 134 | text_type=["mono"], 135 | delme=4, 136 | ) 137 | 138 | else: 139 | await app.send_edit(m, "Something went wrong !") 140 | 141 | except Exception as e: 142 | await app.error(m, e) 143 | -------------------------------------------------------------------------------- /asterix/modules/dev.py: -------------------------------------------------------------------------------- 1 | import re 2 | import subprocess 3 | import sys 4 | import traceback 5 | from io import StringIO 6 | 7 | from pyrogram.types import Message 8 | 9 | from asterix import app 10 | from asterix.helpers import gen 11 | 12 | app.CMD_HELP.update( 13 | { 14 | "dev": ( 15 | "dev", 16 | { 17 | "eval print('cat')": "A nice tool to test python codes.", 18 | "term pip3 install colorama": "Run commands in shell.", 19 | }, 20 | ) 21 | } 22 | ) 23 | 24 | 25 | bot = app.bot 26 | p = print 27 | 28 | 29 | @app.on_message(gen(["eval", "e"], allow=["sudo"])) 30 | async def evaluate_handler(_, m: Message): 31 | """This function is made to execute python codes""" 32 | 33 | if app.textlen(m) > 4096: 34 | return await send_edit( 35 | m, 36 | "Your message is too long ! only 4096 characters are allowed", 37 | text_type=["mono"], 38 | delme=4, 39 | ) 40 | 41 | global reply, chat_id, chat_type 42 | 43 | reply = m.reply_to_message 44 | chat_type = m.chat.type 45 | chat_id = m.chat.id 46 | m.text 47 | 48 | try: 49 | cmd = m.text.split(None, 1)[1] 50 | except IndexError: 51 | return await app.send_edit( 52 | m, "Give me some text (code) to execute . . .", text_type=["mono"], delme=4 53 | ) 54 | 55 | msg = await app.send_edit(m, "Running . . .", text_type=["mono"]) 56 | 57 | old_stderr = sys.stderr 58 | old_stdout = sys.stdout 59 | redirected_output = sys.stdout = StringIO() 60 | redirected_error = sys.stderr = StringIO() 61 | stdout, stderr, exc = None, None, None 62 | 63 | try: 64 | await app.aexec(msg, cmd) 65 | except Exception: 66 | exc = traceback.format_exc() 67 | 68 | stdout = redirected_output.getvalue() 69 | stderr = redirected_error.getvalue() 70 | sys.stdout = old_stdout 71 | sys.stderr = old_stderr 72 | evaluation = exc or stderr or stdout or "Success" 73 | final_output = ( 74 | f"**• COMMAND:**\n\n`{cmd}`\n\n**• OUTPUT:**\n\n`{evaluation.strip()}`" 75 | ) 76 | 77 | if len(final_output) > 4096: 78 | await app.create_file( 79 | message=msg, 80 | filename="eval_output.txt", 81 | content=str(final_output), 82 | caption=f"`{m.text}`", 83 | ) 84 | await msg.delete() 85 | else: 86 | await app.send_edit(msg, final_output) 87 | 88 | 89 | @app.on_message(gen("term", allow=["sudo"])) 90 | async def terminal_handler(_, m: Message): 91 | if app.long(m) == 1: 92 | return await app.send_edit(m, "Use: `.term pip3 install colorama`", delme=5) 93 | 94 | elif app.textlen(m) > 4096: 95 | return await send_edit( 96 | m, 97 | "Your message is too long ! only 4096 characters are allowed", 98 | text_type=["mono"], 99 | delme=4, 100 | ) 101 | 102 | msg = await app.send_edit(m, "Running . . .", text_type=["mono"]) 103 | args = m.text.split(None, 1) 104 | teks = args[1] 105 | if "\n" in teks: 106 | code = teks.split("\n") 107 | output = "" 108 | for x in code: 109 | shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x) 110 | try: 111 | process = subprocess.Popen( 112 | shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE 113 | ) 114 | except Exception as e: 115 | await app.error(m, e) 116 | output += "**{}**\n".format(code) 117 | output += process.stdout.read()[:-1].decode("utf-8") 118 | output += "\n" 119 | else: 120 | shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", teks) 121 | for a in range(len(shell)): 122 | shell[a] = shell[a].replace('"', "") 123 | try: 124 | process = subprocess.Popen( 125 | shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE 126 | ) 127 | except Exception: 128 | exc_type, exc_obj, exc_tb = sys.exc_info() 129 | errors = traceback.format_exception( 130 | etype=exc_type, value=exc_obj, tb=exc_tb 131 | ) 132 | return await app.send_edit( 133 | msg, """**Error:**\n```{}```""".format("".join(errors)) 134 | ) 135 | 136 | output = process.stdout.read()[:-1].decode("utf-8") 137 | if str(output) == "\n": 138 | output = None 139 | if output: 140 | if len(output) > 4096: 141 | await app.create_file( 142 | message=msg, 143 | filename="term_output.txt", 144 | content=output, 145 | caption=f"`{m.text}`", 146 | ) 147 | else: 148 | await app.send_edit( 149 | msg, f"**COMMAND:**\n\n{m.text}\n\n\n**OUTPUT:**\n\n`{output}`" 150 | ) 151 | else: 152 | await app.send_edit(msg, "**OUTPUT:**\n\n`No Output`") 153 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | # todo 4 | if os.uname()[1] == "localhost": 5 | response = os.system("pip3 install -r requirements.txt --no-cache-dir") 6 | if response == 0: 7 | print("Successfully Installed all requirements") 8 | else: 9 | print("Failed to install requirements") 10 | 11 | 12 | # if you deployed this userbot using localhost method, then replace all the necessary parts of the variables given below after '=' sign with the required values. 13 | # for example edit like 'API_ID = 1234567' instead of 'API_ID = os.getenv("API_ID")' 14 | # Warning: don't touch anything else given below except the values you wanna change otherwise you'll get errors. 15 | # ------------------------------------------------------------------------------------------------------------- 16 | class Config(object): 17 | """configuration class""" 18 | 19 | # api id of your telegram account (required) 20 | API_ID = int(os.getenv("API_ID")) 21 | # api hash of your telegram account (required) 22 | API_HASH = os.getenv("API_HASH") 23 | # create a session using command [ python3 session.py ] or use repl.it (required) 24 | SESSION = os.getenv("SESSION") 25 | # ------------------ 26 | # temporary download location (required) 27 | TEMP_DICT = os.getenv("TEMP_DICT", os.path.abspath(".") + "/downloads/") 28 | # official repo for updates 29 | UPSTREAM_REPO = os.getenv( 30 | "UPSTREAM_REPO", "https://github.com/TeamAsterix/AsterixUB.git" 31 | ) 32 | # ------------------ 33 | # heroku api key (required -> if hosted on heroku) 34 | HEROKU_API_KEY = os.getenv("HEROKU_API_KEY") 35 | # heroku app name (required -> if hosted on heroku) 36 | HEROKU_APP_NAME = os.getenv("HEROKU_APP_NAME") 37 | # database url (required) 38 | DB_URI = os.getenv("DATABASE_URL") 39 | # ------------------ 40 | # these users can use your userbot 41 | SUDO_USERS = [ 42 | int(x) for x in os.getenv("SUDO_USERS", "").split() 43 | ] # splits on spaces 44 | # a group to store logs, etc (required) 45 | LOG_CHAT = int(os.getenv("LOG_CHAT")) 46 | # command handler, if you give (exclamation symbol = !) then you can do like this command: !ping => result: pong ! 47 | PREFIX = os.getenv("PREFIX", ".") 48 | # for more info visit docs.pyrogram.org, workers section 49 | WORKERS = int(os.getenv("WORKERS", 8)) 50 | # exclude official plugins from installing, give a space between plugin names 51 | NO_LOAD = [int(x) for x in os.getenv("NO_LOAD", "").split()] # splits on spaces 52 | # default reason for afk plugin 53 | AFK_TEXT = os.getenv("AFK_TEXT", "I am busy Now !") 54 | # ------------------ 55 | # add True to enable (default: False) 56 | PMPERMIT = os.getenv("PMPERMIT", False) 57 | # pmpermit pic (optional) 58 | PMPERMIT_PIC = os.getenv("PMPERMIT_PIC") 59 | # custom pmpermit security text (optional) 60 | PMPERMIT_TEXT = os.getenv( 61 | "PMPERMIT_TEXT", 62 | "Hey ! This is [ Asterix Userbot](https://t.me/TeamAsterix) Security System.\n**You will be blocked if you spammed my owner's pm**\nCurrently My Owner is busy! So Wait Until He Arrives. 👍🏻\nAnd Better Not To Spam His here!", 63 | ) 64 | # pmpermit warn limit (optional) 65 | PM_LIMIT = int(os.getenv("PM_LIMIT", 4)) 66 | # this is used to get your accurate time 67 | TIME_ZONE = os.getenv("TIME_ZONE", "Asia/Kolkata") 68 | # ------------------- 69 | # your custom name (default: telegram name) 70 | USER_NAME = os.getenv("USER_NAME") 71 | # your custom bio (default: telegram bio) 72 | USER_BIO = os.getenv("USER_BIO") 73 | # used for alive plugin (default: asterixuserbot logo image) 74 | USER_PIC = os.getenv("USER_PIC", "") 75 | # add your telegram id if bot fails to get your id 76 | USER_ID = os.getenv("USER_ID") 77 | # add your username if bot fails to get your username 78 | USER_USERNAME = os.getenv("USER_USERNAME") 79 | # -------------------- 80 | # this bio will be shown in '/help' menu (default: official bio from bot) 81 | BOT_BIO = os.getenv("BOT_BIO") 82 | # your assistants custom name (default: Kushina) 83 | BOT_NAME = os.getenv("BOT_NAME", "Kushina") 84 | # your assistants alive pic (optional) 85 | BOT_PIC = os.getenv("BOT_PIC", "https://telegra.ph/file/3930fb44de59f65849f5b.jpg") 86 | # provide this if bot fails to get username of bot (optional) 87 | BOT_USERNAME = os.getenv("BOT_USERNAME") 88 | # telegram id of bot if failed to get automatically (optional) 89 | BOT_ID = os.getenv("BOT_ID") 90 | # access token of your bot, without this the bot will not work (required) 91 | TOKEN = os.getenv("TOKEN") 92 | # --------------------- 93 | # thumbnail used while uploading plugins, etc. (optional) 94 | THUMB_PIC = os.getenv("THUMB_PIC", "material/images/asterix.png") 95 | # --------------------- 96 | # your telegraph account name (default: Asterixuserbot) 97 | TL_NAME = os.getenv("TL_NAME") 98 | # this will be shown before (as a prefix) the texts in the help dex (default: None) 99 | HELP_EMOJI = os.getenv("HELP_EMOJI") 100 | -------------------------------------------------------------------------------- /asterix/modules/share.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | 4 | from pyrogram.types import Message 5 | 6 | from asterix import app, gen 7 | 8 | app.CMD_HELP.update( 9 | { 10 | "share": ( 11 | "share", 12 | { 13 | "send [plugin name]": "Send official plugin files from userbot to telegram chat.", 14 | "install [reply to plugin]": "Reply to a .py file to install it in external modules directory.", 15 | "uninstall [name of local plugin]": "Uninstall Local installed modules.", 16 | }, 17 | ) 18 | } 19 | ) 20 | 21 | # ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 22 | 23 | 24 | @app.on_message(gen("send", allow=["sudo", "channel"])) 25 | async def sendmodule_handler(app, m: Message): 26 | if app.long(m) > 1: 27 | m = await app.send_edit(m, "Checking module . . .", text_type=["mono"]) 28 | filename = m.command[1] 29 | modulename = f"asterix/modules/{filename}.py" 30 | if os.path.exists(modulename): 31 | thumb_image = await app.IsThumbExists(modulename) 32 | 33 | if thumb_image: 34 | thumb_pic = thumb_image 35 | elif app.getdv("THUMB_PIC"): 36 | thumb_pic = app.getdv("THUMB_PIC") 37 | else: 38 | thumb_pic = app.THUMB_PIC 39 | 40 | time.time() 41 | module_caption = os.path.basename(modulename) 42 | m = await app.send_edit(m, f"Uploading {module_caption} . . .") 43 | 44 | try: 45 | await app.send_document( 46 | m.chat.id, 47 | document=modulename, 48 | thumb=thumb_pic, 49 | caption=( 50 | f"File name: `{module_caption}`\n\nUploaded By: {app.UserMention()}" 51 | ), 52 | ) 53 | await m.delete() 54 | except Exception as e: 55 | await app.error(m, e) 56 | await app.send_edit(m, "Try again later, check log chat . . .", delme=3) 57 | else: 58 | await app.send_edit( 59 | m, "404: plugin not found . . .", delme=2, text_type=["mono"] 60 | ) 61 | else: 62 | await app.send_edit( 63 | m, f"`{app.PREFIX}send [ plugin name ]` to upload plugin file.", delme=3 64 | ) 65 | 66 | 67 | @app.on_message(gen("install")) 68 | async def install_handler(_, m: Message): 69 | reply = m.reply_to_message 70 | if not reply: 71 | return await app.send_edit( 72 | m, "Reply to a python file to install . . .", text_type=["mono"], delme=4 73 | ) 74 | if reply: 75 | if not reply.document.file_name.endswith(".py"): 76 | return await app.send_edit( 77 | m, "Only (.py) modules can be installed !!", text_type=["mono"], delme=2 78 | ) 79 | doc_name = reply.document.file_name 80 | 81 | module_loc = f"asterix/modules/{doc_name}" 82 | await app.send_edit(m, "Installing module . . .", text_type=["mono"]) 83 | if os.path.exists(module_loc): 84 | return await app.send_edit( 85 | m, 86 | f"Module `{doc_name}` already exists ! skipping installation !", 87 | delme=5, 88 | ) 89 | 90 | try: 91 | download_loc = await app.download_media(message=reply, file_name=module_loc) 92 | if download_loc: 93 | await app.send_edit(m, f"**Installed module:** `{doc_name}`", delme=5) 94 | data = open(download_loc, "r") 95 | await app.aexec(m, data.read()) 96 | else: 97 | await app.send_edit( 98 | m, 99 | f"Failed to install module {doc_name}", 100 | text_type=["mono"], 101 | delme=4, 102 | ) 103 | except Exception as e: 104 | await app.error(m, e) 105 | 106 | 107 | @app.on_message(gen("uninstall")) 108 | async def uninstall_handler(_, m: Message): 109 | cmd = m.command 110 | try: 111 | if app.long(m) > 1: 112 | if cmd[1].endswith(".py"): 113 | module_loc = f"asterix/modules/{cmd[1]}" 114 | elif not cmd[1].endswith(".py"): 115 | module_loc = f"asterix/modules/{cmd[1]}.py" 116 | if os.path.exists(module_loc): 117 | os.remove(module_loc) 118 | await app.send_edit(m, f"**Uninstalled module:** {cmd[1]}", delme=5) 119 | else: 120 | await app.send_edit( 121 | m, "Module doesn't exist !", delme=4, text_type=["mono"] 122 | ) 123 | else: 124 | await app.send_edit( 125 | m, "Give me a module name . . .", text_type=["mono"], delme=4 126 | ) 127 | except Exception as e: 128 | await app.error(m, e) 129 | -------------------------------------------------------------------------------- /asterix/modules/google.py: -------------------------------------------------------------------------------- 1 | import os 2 | import random 3 | import shutil 4 | import urllib 5 | 6 | import requests 7 | from bing_image_downloader import downloader as bing_downloader 8 | from bs4 import BeautifulSoup 9 | from pyrogram.types import Message 10 | 11 | from asterix import app, gen 12 | 13 | app.CMD_HELP.update( 14 | { 15 | "google": ( 16 | "google", 17 | { 18 | "img [number of pic] [query]": "uploads searched images on telegram using bing.com", 19 | "sauce [reply to pic]": "Get the source link of that image", 20 | "pic [query]": "Get Images from @bing bot.", 21 | }, 22 | ) 23 | } 24 | ) 25 | 26 | 27 | search_url = "http://www.google.com" 28 | 29 | headers = { 30 | "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0" 31 | } 32 | 33 | 34 | def get_soup(url, header): 35 | return BeautifulSoup( 36 | urllib.request.urlopen(urllib.request(url, headers=header)), "html.parser" 37 | ) 38 | 39 | 40 | @app.on_message(gen("sauce", allow=["sudo"])) 41 | async def imagesauce_handler(_, m: Message): 42 | try: 43 | reply = m.reply_to_message 44 | if not reply: 45 | return await app.send_edit( 46 | m, "Reply to some media.", text_type=["mono"], delme=4 47 | ) 48 | 49 | if reply.photo: 50 | m = await app.send_edit(m, "⏳ • Hold on ...") 51 | savename = "photo_{}_{}.png".format(reply.photo.file_id, reply.photo.date) 52 | await app.download_media(reply, file_name="./downloads/" + savename) 53 | elif reply.animation: 54 | m = await app.send_edit(m, "⏳ • Hold on ...") 55 | savename = "giphy_{}-{}.gif".format( 56 | reply.animation.date, reply.animation.file_size 57 | ) 58 | await app.download_media(reply, file_name="./downloads/" + savename) 59 | else: 60 | return await app.send_edit( 61 | m, 62 | "Only photo & animation media's are supported.", 63 | text_type=["mono"], 64 | delme=4, 65 | ) 66 | 67 | searchUrl = "http://www.google.co.id/searchbyimage/upload" 68 | filePath = "./downloads/{}".format(universe) 69 | multipart = { 70 | "encoded_image": (filePath, open(filePath, "rb")), 71 | "image_content": "", 72 | } 73 | response = requests.post(searchUrl, files=multipart, allow_redirects=False) 74 | fetchUrl = response.headers["Location"] 75 | await app.send_edit( 76 | m, "Results: [Tap Here]({})".format(fetchUrl), disable_web_page_preview=True 77 | ) 78 | except Exception as e: 79 | await app.error(m, e) 80 | 81 | 82 | @app.on_message(gen("pic", allow=["sudo"])) 83 | async def yandeximages_handler(_, m: Message): 84 | oldmsg = m 85 | if app.long(m) == 1: 86 | return await app.send_edit(m, "Usage: `.pic cat`", delme=4) 87 | 88 | try: 89 | if app.long(m) > 1: 90 | m = await app.send_edit(m, "Getting image . . .", text_type=["nono"]) 91 | photo = oldmsg.text.split(None, 1)[1] 92 | result = await app.get_inline_bot_results("@pic", photo) 93 | await m.delete() 94 | saved = await app.send_inline_bot_result( 95 | msg.chat.id, 96 | query_id=result.query_id, 97 | result_id=result.results[random.randint(0, len(result.results))].id, 98 | hide_via=True, 99 | ) 100 | else: 101 | await app.send_edit( 102 | m, 103 | "Failed to get the image, try again later !", 104 | text_type=["mono"], 105 | delme=4, 106 | ) 107 | except Exception as e: 108 | await app.error(m, e) 109 | 110 | 111 | @app.on_message(gen("img", allow=["sudo"])) 112 | async def imagesearch_handler(_, m: Message): 113 | cmd = m.command 114 | if app.long(m) == 1: 115 | return await app.send_edit( 116 | m, "Please give me some query.", text_type=["mono"], delme=4 117 | ) 118 | 119 | if app.long(m) > 2 and bool(cmd[1].isdigit()): 120 | limit = int(cmd[1]) 121 | query = m.text.split(None, 2)[2] 122 | else: 123 | limit = 3 # default 124 | query = m.text.split(None, 1)[1] 125 | 126 | try: 127 | m = await app.send_edit(m, f"**Getting images:** `{query}`") 128 | bing_downloader.download( 129 | query, 130 | limit=limit, 131 | output_dir="images", 132 | adult_filter_off=True, 133 | force_replace=False, 134 | timeout=60, 135 | verbose=False, 136 | ) 137 | img_dir = os.path.exists("./images") 138 | 139 | if img_dir: 140 | for img in os.listdir(f"./images/{query}"): 141 | await app.send_photo(m.chat.id, f"./images/{query}/{img}") 142 | else: 143 | await app.send_edit(m, "No images found !", text_type=["mono"], delme=4) 144 | 145 | if os.path.exists(f"./images/{query}/"): 146 | shutil.rmtree(f"./images") # remove folder 147 | 148 | await m.delete() 149 | 150 | except Exception as e: 151 | await app.error(m, e) 152 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Asterix UserBot 2 | * A Powerful Telegram userbot based on Pyrogram. 3 | 4 | [![Alphonse/Asterix logo](https://telegra.ph/file/2167f38bae9c10c01ecf0.jpg)](https://dashboard.heroku.com/new?button-url=https%3A%2F%2Fgithub.com%2FTeamAsterix%2FAsterixUB%2Ftree%2Fbugs&template=https%3A%2F%2Fgithub.com%2FTeamAsterix%2FAsterixUB) 5 | [![](https://img.shields.io/badge/Asterix-v0.0.1-red)](#) 6 | [![Stars](https://img.shields.io/github/stars/TeamAsterix/Asterixub?style=flat-square&color=yellow)](https://github.com/TeamAsterix/AsterixUB/stargazers) 7 | [![Forks](https://img.shields.io/github/forks/TeamAsterix/Asterixub?style=flat-square&color=orange)](https://github.com/TeamAsterix/Asterixub/fork) 8 | [![Size](https://img.shields.io/github/repo-size/TeamAsterix/Asterixub?style=flat-square&color=green)](https://github.com/TeamAsterix/Asterixub/) 9 | [![Python](https://img.shields.io/badge/Python-v3.9.10-blue)](https://www.python.org/) 10 | [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/TeamAsterix/Asterixub/graphs/commit-activity) 11 | [![Contributors](https://img.shields.io/github/contributors/TeamAsterix/Asterixub?style=flat-square&color=green)](https://github.com/TeamAsterix/Asterixub/graphs/contributors) 12 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://makeapullrequest.com) 13 | [![License](https://img.shields.io/badge/License-AGPL-blue)](https://github.com/TeamAsterix/AsterixUB/blob/master/LICENSE) 14 | 15 | 16 | 17 | ## How To Deploy Asterix 18 | 19 | - [Heroku](#Heroku-Deploy) 20 | - [Railway](#Railway-Deploy) 21 | - [Qovery](#Deploy-Qovery) 22 | - [Termux](#Deploy-On-Termux) 23 | 24 | # Tutorial 25 | - Railway Deploy Comming Soon. 26 | - Heroku Comming Soon. 27 | 28 | ## Heroku Deploy 29 | 30 | - [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/TeamAsterix/AsterixUB) 31 | 32 | ## Railway Deploy 33 | 34 | - [![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/-U4IQf?referralCode=pmqzRk) 35 | 36 | ## Deploy Qovery 37 | 38 | - [![Deploy](https://img.shields.io/badge/Deploy-Qovery-purple)](https://www.qovery.com/) 39 | 40 | ## Deploy On Termux 41 | 42 |
43 | 1. Deploy on Termux 44 | 45 | 46 |

1. Install termux app in your device ( lastest version )

47 | 48 |

2. Run The code in the termux that are given below.

49 | 50 | `apt update & apt upgrade` 51 | 52 | `pkg install python git nano` 53 | 54 | `git clone https://github.com/TeamAsterix/AsterixUB` 55 | 56 | `cd Asterix` 57 | 58 | `nano config.py` 59 | 60 |

Note: Fill those required values from your value.

61 | 62 | `bash start.sh` 63 | 64 |

3. Done, Have fun using asterix userbot.

65 | 66 | 67 |
68 | 69 | ### Documentation 70 | 71 | - Soon Complete 72 | 73 | ## Variables 74 | 75 | - `APP_ID` = Get this value from my.telegram.org 76 | - `API_HASH` = Get this value from my.telegram.org 77 | - `SESSION` = Get this by using Repl.it or from terminal. 78 | - `LOG_CHAT` = Make A Private Chat And Get it's ID. 79 | - `DATABASE_URL` = A Postgresql database url. 80 | - `TOKEN` = Go to @botfather in telegram and make a new bot and get the bot token. 81 | 82 | ## Session String 83 | - Open Repl Link. 84 | - Click Green Button To Play. 85 | - Wait for requirements to finish. 86 | - Fill API ID, API HASH, Phone number (with country code). 87 | - Paste the OTP received on Telegram. 88 | - If You have Enabled 2-Step Verification then fill your password. 89 | - Your String Session Will be saved in your Telegram Saved Message. 90 | - There's a bug in repl which prints your input twice or more. You need to long tap and paste the required information in repl. 91 | - [Click Here](https://replit.com/@TeamAsterix/AsterixUB#main.py) 92 | 93 | 94 | 95 | 96 | ## Telegram Support 🏪 97 | - [![Telegram Group](https://img.shields.io/badge/Telegram-Group-brightgreen)](https://t.me/Adterix_Support) 98 | - [![Telegram Channel](https://img.shields.io/badge/Telegram-Channel-brightgreen)](https://t.me/AstetixUpdates) 99 | - [![Telegram Team](https://img.shields.io/badge/Telegram-Team-brightgreen)](https://t.me/TeamAsterix) 100 | 101 | 102 | 103 | ## Disclaimer 104 | 105 | ``` 106 | YOU ARE FOREWARNED 107 | Your Telegram account may get banned. 108 | Alphonse or we are not responsible for your account, 109 | This bot is intended for the purpose of having fun with some fun commands 110 | and group management with some helpfull commands. 111 | 112 | If you ended up spamming groups, getting reported left and right, 113 | and you ended up in being fight with Telegram 114 | and at the end Telegram Team deleted your account. DON'T BLAME US. 115 | 116 | No personal support will be provided / We won't spoon feed you. 117 | If you need help ask in our support group 118 | and we or our friends will try to help you. 119 | 120 | Thanks for using our bot 121 | ``` 122 | # License 123 | [![License](https://www.gnu.org/graphics/agplv3-155x51.png)](LICENSE) 124 | Ryoishin is licensed under [GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.en.html) v3 or later. 125 | 126 | > Copyright © 2021, Asterix. Released under the [Licence](https://github.com/TeamAsterix/AsterixUB/blob/master/LICENSE).. 127 | 128 | 129 | ## Credits 130 | - Special thanks to [Dan](https://github.com/pyrogram/pyrogram) for Pyrogram library.💖 131 | - To all devs of these [Userbots](https://t.me/AsterixDevs)❣️ 132 | - Finally to all [contributors of Asterix](https://github.com/TeamAsterix/AsterixUB/graphs/contributors)❤️ 133 | 134 | -------------------------------------------------------------------------------- /asterix/modules/welcome.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters 2 | from pyrogram.types import Message 3 | 4 | from asterix import app 5 | from asterix.helpers import gen 6 | 7 | app.CMD_HELP.update( 8 | { 9 | "welcome": ( 10 | "welcome", 11 | { 12 | "setwc [reply to media/text]": "Set welcome message for group.", 13 | "getwc": "Use it in group to get saved welcome message.", 14 | "delwc": "Use it in group to delete saved welcome message.", 15 | }, 16 | ) 17 | } 18 | ) 19 | 20 | 21 | IgnoreChat = app.get_welcome_ids() 22 | 23 | 24 | @app.on_message(filters.new_chat_members & filters.group & filters.chat(IgnoreChat)) 25 | async def sendwelcome_handler(_, m: Message): 26 | chat = app.get_welcome(str(m.chat.id)) 27 | if bool(chat) is True: 28 | if chat["file_id"] is None: 29 | return 30 | 31 | try: 32 | file_id = chat["file_id"] if chat["file_id"] else False 33 | caption = chat["caption"] if chat["caption"] else False 34 | if file_id and not file_id.startswith("#"): # as a text 35 | return await app.send_message( 36 | m.chat.id, f"{file_id}", reply_to_message_id=m.message_id 37 | ) 38 | 39 | elif file_id and file_id.startswith("#"): # as a file id 40 | file_id = file_id.replace("#", "") 41 | 42 | if caption: 43 | await app.send_cached_media( 44 | m.chat.id, 45 | file_id=file_id, 46 | caption=f"{caption}", 47 | reply_to_message_id=m.message_id, 48 | ) 49 | elif not caption: 50 | await app.send_cached_media( 51 | chat_id=m.chat.id, file_id=file_id, reply_to_message_id=m.message_id 52 | ) 53 | except Exception as e: 54 | await app.error(m, e) 55 | 56 | 57 | @app.on_message(gen(["setwelcome", "setwc"], allow=["sudo", "channel"])) 58 | async def savewelcome_handler(_, m: Message): 59 | if await app.check_private(m): 60 | return 61 | 62 | await app.send_edit( 63 | m, "Setting this media as a welcome message . . .", text_type=["mono"] 64 | ) 65 | reply = m.reply_to_message 66 | if reply: 67 | try: 68 | if bool(reply.media) is True: 69 | fall = app.get_file_id(reply) 70 | file_id = fall["data"] if fall["data"] else None 71 | caption = fall["caption"] if fall["caption"] else None 72 | 73 | if caption: 74 | app.set_welcome(str(m.chat.id), "#" + file_id, caption) 75 | else: 76 | app.set_welcome(str(m.chat.id), "#" + file_id) 77 | await app.send_edit( 78 | m, 79 | "Added this media to welcome message . . .", 80 | delme=2, 81 | text_type=["mono"], 82 | ) 83 | elif bool(reply.media) is False: 84 | app.set_welcome(str(m.chat.id), reply.text.markdown) 85 | await app.send_edit( 86 | m, 87 | "Added this text to welcome message . . .", 88 | delme=2, 89 | text_type=["mono"], 90 | ) 91 | except Exception as e: 92 | await app.error(m, e) 93 | print(e) 94 | else: 95 | await app.send_edit( 96 | m, 97 | "Please reply to some media or text to set welcome message . . .", 98 | delme=2, 99 | text_type=["mono"], 100 | ) 101 | 102 | 103 | @app.on_message(gen(["delwelcome", "delwc"], allow=["sudo", "channel"])) 104 | async def deletewelcome_handler(_, m: Message): 105 | if await app.check_private(m): 106 | return 107 | 108 | try: 109 | await app.send_edit( 110 | m, "Checking welcome message for this group . . .", text_type=["mono"] 111 | ) 112 | app.del_welcome(str(m.chat.id)) 113 | await app.send_edit( 114 | m, 115 | "Successfully deleted welcome message for this chat . . .", 116 | delme=2, 117 | text_type=["mono"], 118 | ) 119 | except Exception as e: 120 | await app.error(m, e) 121 | 122 | 123 | @app.on_message(gen(["getwelcome", "getwc"], allow=["sudo", "channel"])) 124 | async def getwelcome_handler(_, m: Message): 125 | if await app.check_private(m): 126 | return 127 | 128 | try: 129 | await app.send_edit(m, "Getting welcome message of this group . . .") 130 | data = app.get_welcome(str(m.chat.id)) 131 | text = data["file_id"] 132 | cap = data["caption"] 133 | 134 | if text is None and cap is None: 135 | await app.send_edit( 136 | m, 137 | "No welcome message was assigned to this group.", 138 | text_type=["mono"], 139 | delme=3, 140 | ) 141 | elif text is not None and cap is None: 142 | if text.startswith("#"): 143 | await app.send_cached_media( 144 | m.chat.id, 145 | file_id=text.replace("#", ""), 146 | reply_to_message_id=m.message_id, 147 | ) 148 | await m.delete() 149 | else: 150 | await app.send_edit(m, text, text_type=["mono"]) 151 | elif text is not None and cap is not None: 152 | if text.startswith("#"): 153 | await app.send_cached_media( 154 | m.chat.id, 155 | file_id=text.replace("#", ""), 156 | caption=cap, 157 | reply_to_message_id=m.message_id, 158 | ) 159 | await m.delete() 160 | except Exception as e: 161 | await app.error(m, e) 162 | -------------------------------------------------------------------------------- /asterix/modules/dv.py: -------------------------------------------------------------------------------- 1 | from pyrogram.types import Message 2 | 3 | from asterix import app, gen 4 | 5 | app.CMD_HELP.update( 6 | { 7 | "dv": ( 8 | "dv", 9 | { 10 | "setdv [varname] [value]": "Set any database vars, for ex: .setdv [USER_NAME] [RYOISHIN]", 11 | "getdv [varname]": "Get a existing database vars value.", 12 | "deldv [varname]": "Delete a existing database var with its value.", 13 | "alldv": "Get all existing database vars.", 14 | "listdv": "Get all available dv vars which you set.", 15 | "pm [on | off]": "Turn on & off your pmguard", 16 | }, 17 | ) 18 | } 19 | ) 20 | 21 | 22 | @app.on_message(gen("setdv", allow=["sudo"])) 23 | async def setdv_handler(_, m: Message): 24 | if app.long(m) == 1: 25 | await app.send_edit( 26 | m, "Give me a key & a value to set dv vars.", text_type=["mono"], delme=4 27 | ) 28 | 29 | elif app.textlen(m) > 4096: 30 | await app.send_edit( 31 | m, 32 | "Text is too long. only 4096 characters are allowed.", 33 | text_type=["mono"], 34 | delme=4, 35 | ) 36 | 37 | elif app.long(m) == 2: 38 | await app.send_edit( 39 | m, "Please give me key with a value.", text_type=["mono"], delme=4 40 | ) 41 | 42 | elif app.long(m) > 2: 43 | key = m.command[1] 44 | value = m.text.split(None, 2)[2] 45 | done = app.setdv(key, value) 46 | 47 | if done: 48 | await app.send_edit( 49 | m, 50 | f"Added database var with [ **key** = `{key}` ] and [ **value** = `{value}` ]", 51 | ) 52 | 53 | elif not done: 54 | await app.send_edit( 55 | m, 56 | "Failed to a add key & value to database var.", 57 | text_type=["mono"], 58 | delme=2, 59 | ) 60 | 61 | 62 | @app.on_message(gen("deldv", allow=["sudo"])) 63 | async def deldv_handler(_, m: Message): 64 | if app.long(m) == 1: 65 | await app.send_edit( 66 | m, 67 | "Give me some key to delete that a var from database . . . ", 68 | text_type=["mono"], 69 | delme=2, 70 | ) 71 | 72 | elif app.textlen(m) > 4096: 73 | await app.send_edit( 74 | m, 75 | "text is too long. only 4096 characters are allowed.", 76 | text_type=["mono"], 77 | delme=4, 78 | ) 79 | 80 | elif app.long(m) > 1: 81 | keys = "**Deleted vars:**\n\n" 82 | cmd = m.command 83 | for key in cmd[1:]: 84 | app.deldv(key) 85 | keys += f"`{key}`" 86 | 87 | await app.send_edit(m, f"Successfully deleted keys.\n\n{keys}", delme=4) 88 | else: 89 | await app.send_edit( 90 | m, "Something went wrong, try again later !", text_type=["mono"], delme=4 91 | ) 92 | 93 | 94 | @app.on_message(gen("getdv", allow=["sudo"])) 95 | async def getdv_handler(_, m: Message): 96 | if app.long(m) == 1: 97 | await app.send_edit( 98 | m, 99 | "Give me some key to get value that a var from database . . . ", 100 | text_type=["mono"], 101 | delme=2, 102 | ) 103 | 104 | elif app.long(m) > 1: 105 | key = m.command[1] 106 | done = app.getdv(key) 107 | 108 | if done: 109 | await app.send_edit( 110 | m, f"**Here:**\n\n**key** = `{key}`\n\n**value** = `{done}`", delme=4 111 | ) 112 | else: 113 | await app.send_edit( 114 | m, "This var doesn't exist in my database.", text_type=["mono"], delme=4 115 | ) 116 | else: 117 | await app.send_edit( 118 | m, 119 | "Maximum 4096 characters in one message . . .", 120 | text_type=["mono"], 121 | delme=4, 122 | ) 123 | 124 | 125 | @app.on_message(gen("pm", allow=["sudo"])) 126 | async def pm_handler(_, m: Message): 127 | arg = m.command 128 | if app.long(m) == 1: 129 | await app.send_edit( 130 | m, "Provide me a suffix to do some work.\n\nSuffix: `on` & `off`", delme=4 131 | ) 132 | 133 | elif app.long(m) > 1 and arg[1] == "on": 134 | if app.Pmpermit() is True: 135 | return await app.send_edit( 136 | m, "Pmguard is already active !", text_type=["mono"], delme=4 137 | ) 138 | 139 | done = app.setdv("PMPERMIT", "True") 140 | if done: 141 | await app.send_edit( 142 | m, "Pmguard is now turned on.", text_type=["mono"], delme=4 143 | ) 144 | else: 145 | await app.send_edit( 146 | m, "Failed to turn on pmguard.", text_type=["mono"], delme=4 147 | ) 148 | 149 | elif app.long(m) > 1 and arg[1] == "off": 150 | if app.Pmpermit() is False: 151 | return await app.send_edit( 152 | m, "Pmguard is already off !", text_type=["mono"], delme=4 153 | ) 154 | 155 | done = app.deldv("PMPERMIT") 156 | if done: 157 | await app.send_edit( 158 | m, "Pmguard is now turned off.", text_type=["mono"], delme=4 159 | ) 160 | else: 161 | await app.send_edit( 162 | m, "Failed to turn off pmguard.", text_type=["mono"], delme=4 163 | ) 164 | 165 | elif app.long(m) > 1 and arg[1] not in ("on", "off"): 166 | await app.send_edit( 167 | m, "Use `on` or `off` after command to turn on & off pmguard.", delme=4 168 | ) 169 | else: 170 | await app.send_edit( 171 | m, 172 | "Something went wrong, please try again later !", 173 | text_type=["mono"], 174 | delme=4, 175 | ) 176 | 177 | 178 | @app.on_message(gen("alldv", allow=["sudo"])) 179 | async def alldv_handler(_, m: Message): 180 | if bool(app.getalldv()) is True: 181 | m = await app.send_edit( 182 | m, "Getting all database vars . . .", text_type=["mono"] 183 | ) 184 | my_dict = app.getalldv() 185 | dict_data = [] 186 | dict_data.clear() 187 | 188 | for key, value in zip(my_dict.keys(), my_dict.values()): 189 | dict_data.append(f"`{key}` = `{value}`\n\n") 190 | 191 | await app.send_edit(m, "**All DB VARS:**\n\n" + "".join(dict_data)) 192 | else: 193 | await app.send_edit( 194 | m, "There are no database vars (empty) !", text_type=["mono"], delme=4 195 | ) 196 | 197 | 198 | @app.on_message(gen("listdv", allow=["sudo"])) 199 | async def dvlist_handler(_, m: Message): 200 | allvars = [f"`{x}`" for x in app.DVLIST] 201 | await app.send_edit(m, "**AVAILABLE DB VARS:**\n\n" + "\n".join(allvars)) 202 | -------------------------------------------------------------------------------- /asterix/modules/update.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import sys 3 | from os import remove 4 | 5 | from git import Repo 6 | from git.exc import GitCommandError, InvalidGitRepositoryError, NoSuchPathError 7 | 8 | from asterix import app 9 | from asterix.helpers import gen 10 | 11 | app.CMD_HELP.update( 12 | { 13 | "update": ( 14 | "update", 15 | { 16 | "update": "To check if new update is available or not.", 17 | "update [ now ]": "To update userbot to latest version.", 18 | }, 19 | ) 20 | } 21 | ) 22 | 23 | 24 | TRON_REPO = app.UPSTREAM_REPO 25 | 26 | 27 | async def gen_chlog(repo, diff): 28 | ch_log = "" 29 | dateform = "On %d/%m/%y at %H:%M:%S" 30 | for data in repo.iter_commits(diff): 31 | ch_log += f"**#{data.count()}** : {data.committed_datetime.strftime(dateform)} : [{data.summary}]({TRON_REPO.rstrip('/')}/commit/{data}) by `{data.author}`\n" 32 | return ch_log 33 | 34 | 35 | async def install_requirements(): 36 | try: 37 | process = await asyncio.create_subprocess_shell( 38 | " ".join( 39 | [sys.executable, "-m", "pip", "install", "-r", "requirements.txt"] 40 | ), 41 | stdout=asyncio.subprocess.PIPE, 42 | stderr=asyncio.subprocess.PIPE, 43 | ) 44 | await process.communicate() 45 | return process.returncode 46 | except Exception as e: 47 | return repr(e) 48 | 49 | 50 | @app.on_message(gen("update", allow=["sudo", "channel"])) 51 | async def update_handler(_, m): 52 | cmd = False 53 | errtext = "Some problem occurred:\n\n" 54 | 55 | await app.send_edit( 56 | m, "Checking for updates, please wait . . .", text_type=["mono"] 57 | ) 58 | 59 | if app.long(m) > 1: 60 | cmd = m.command 61 | 62 | try: 63 | repo = Repo() 64 | except NoSuchPathError as e: 65 | await app.send_edit(m, f"{errtext}`{e}`") 66 | return repo.__del__() 67 | 68 | except GitCommandError as e: 69 | await app.send_edit(m, f"{errtext}`{e}`") 70 | return repo.__del__() 71 | 72 | except InvalidGitRepositoryError: 73 | repo = Repo.init() 74 | origin = repo.create_remote("upstream", TRON_REPO) 75 | origin.fetch() 76 | repo.create_head("master", origin.refs.master) 77 | repo.heads.master.set_tracking_branch(origin.refs.master) 78 | repo.heads.master.checkout(True) 79 | ACTIVE_BRANCH = repo.active_branch.name 80 | if ACTIVE_BRANCH != "master": 81 | await app.send_edit( 82 | m, 83 | f"**[ UPDATER ]:** You are on [ {ACTIVE_BRANCH} ]\n\nPlease change to `master` branch.`", 84 | ) 85 | return repo.__del__() 86 | 87 | try: 88 | repo.create_remote("upstream", TRON_REPO) 89 | except BaseException: 90 | pass 91 | ups_rem = repo.remote("upstream") 92 | ups_rem.fetch(ACTIVE_BRANCH) 93 | changelog = await gen_chlog(repo, f"{ACTIVE_BRANCH}") 94 | if cmd is False: 95 | if changelog: 96 | changelog_str = f"**New update is available for [{ACTIVE_BRANCH}]({TRON_REPO}/tree/{ACTIVE_BRANCH}):\n\n[CHANGE LOG]:**\n\n{changelog}" 97 | if len(changelog_str) > 4096: 98 | await app.send_edit( 99 | m, 100 | "Changelog is too big, view the file below to see it.", 101 | text_type=["mono"], 102 | delme=6, 103 | ) 104 | file = open("up_output.txt", "w+") 105 | file.write(changelog_str) 106 | file.close() 107 | await app.send_document( 108 | m.chat.id, 109 | "up_output.txt", 110 | caption="**[ STATUS ]:** Do `.update now` to update.", 111 | ) 112 | remove("up_output.txt") 113 | else: 114 | return await app.send_edit( 115 | m, 116 | f"{changelog_str}\n\n[ UPDATE ]: Do `.update now` to update.", 117 | disable_web_page_preview=True, 118 | ) 119 | else: 120 | await app.send_edit( 121 | m, 122 | f"**[ STATUS ]:** Your bot is upto date !\n**[ VERSION ]:** `{app.userbot_version}`\n**[ BRANCH ]:** [{ACTIVE_BRANCH}]({TRON_REPO}/tree/{ACTIVE_BRANCH})", 123 | disable_web_page_preview=True, 124 | ) 125 | return repo.__del__() 126 | 127 | if app.HEROKU_API_KEY: 128 | import heroku3 129 | 130 | heroku = heroku3.from_key(app.HEROKU_API_KEY) 131 | heroku_app = None 132 | heroku_applications = heroku.apps() 133 | if not app.HEROKU_APP_NAME: 134 | await app.send_edit( 135 | m, 136 | "Please set up the [ HEROKU_APP_NAME ] variable to be able to update userbot.", 137 | text_type=["mono"], 138 | delme=4, 139 | ) 140 | return repo.__del__() 141 | 142 | for apps in heroku_applications: 143 | if apps.name == app.HEROKU_APP_NAME: 144 | heroku_app = apps 145 | break 146 | 147 | if heroku_app is None: 148 | await app.send_edit( 149 | m, 150 | "Invalid Heroku credentials for updating userbot.", 151 | text_type=["mono"], 152 | delme=4, 153 | ) 154 | return repo.__del__() 155 | 156 | m = await app.send_edit( 157 | m, 158 | "Userbot update in progress, please wait for few minutes . . .", 159 | text_type=["mono"], 160 | ) 161 | ups_rem.fetch(ACTIVE_BRANCH) 162 | repo.git.reset("--hard", "FETCH_HEAD") 163 | heroku_git_url = heroku_app.git_url.replace( 164 | "https://", "https://api:" + app.HEROKU_API_KEY + "@" 165 | ) 166 | 167 | if "heroku" in repo.remotes: 168 | remote = repo.remote("heroku") 169 | remote.set_url(heroku_git_url) 170 | else: 171 | remote = repo.create_remote("heroku", heroku_git_url) 172 | 173 | try: 174 | remote.push(refspec=f"HEAD:refs/heads/{ACTIVE_BRANCH}", force=True) 175 | except GitCommandError as e: 176 | app.log.error(e) 177 | 178 | await app.send_edit( 179 | m, "Successfully Updated, initialing . . .", text_type=["mono"], delme=8 180 | ) 181 | 182 | else: 183 | try: 184 | ups_rem.pull(ACTIVE_BRANCH) 185 | except GitCommandError: 186 | repo.git.reset("--hard", "FETCH_HEAD") 187 | await install_requirements() 188 | await app.send_edit( 189 | m, 190 | "Successfully updated Userbot!\nBot is restarting . . .", 191 | text_type=["mono"], 192 | delme=8, 193 | ) 194 | -------------------------------------------------------------------------------- /asterix/modules/song.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | from pyrogram.types import Message 4 | 5 | from asterix import app, gen 6 | 7 | app.CMD_HELP.update( 8 | { 9 | "song": ( 10 | "song", 11 | { 12 | "ly [song title]": "Get Song Lyrics [ Japanese Songs Doesn't Work For Now.]", 13 | "song [song name]": "Get songs in mp3 format.", 14 | "dz [song name]": "Get songs from deezer bot in mp3 format.", 15 | }, 16 | ) 17 | } 18 | ) 19 | 20 | 21 | @app.on_message(gen(["song", "music"], allow=["sudo", "channel"])) 22 | async def song_handler(_, m: Message): 23 | await app.send_edit(m, "Getting song . . .") 24 | try: 25 | cmd = m.command 26 | reply = m.reply_to_message 27 | if len(cmd) > 1: 28 | song_name = m.text.split(None, 1)[1] 29 | elif reply and len(cmd) == 1: 30 | song_name = reply.text or reply.caption 31 | elif not reply and len(cmd) == 1: 32 | return await app.send_edit( 33 | m, "Give me a song name . . .", text_type=["mono"], delme=3 34 | ) 35 | 36 | song_results = await app.get_inline_bot_results("audio_storm_bot", song_name) 37 | 38 | try: 39 | # send to Saved Messages because hide_via doesn't work sometimes 40 | saved = await app.send_inline_bot_result( 41 | chat_id="me", 42 | query_id=song_results.query_id, 43 | result_id=song_results.results[0].id, 44 | hide_via=True, 45 | ) 46 | 47 | # forward as a new message from Saved Messages 48 | saved = await app.get_messages("me", int(saved.updates[1].message.id)) 49 | reply_to = m.reply_to_message.message_id if m.reply_to_message else None 50 | 51 | await app.send_audio( 52 | chat_id=m.chat.id, 53 | audio=str(saved.audio.file_id), 54 | reply_to_message_id=reply_to, 55 | caption=f"**Song:** `{song_name}`\n**Uploaded By:** {app.UserMention()}", 56 | ) 57 | 58 | # delete the message from Saved Messages 59 | await app.delete_messages("me", saved.message_id) 60 | except TimeoutError: 61 | return await app.send_edit(m, "Something went wrong, tru again !") 62 | except Exception as e: 63 | await app.error(m, e) 64 | await app.send_edit(m, "failed to process your request, please check logs") 65 | 66 | 67 | @app.on_message(gen(["dz", "deezer"], allow=["sudo", "channel"])) 68 | async def deezer_handler(_, m: Message): 69 | try: 70 | m = await app.send_edit(m, "Searching on deezer . . .") 71 | m.command 72 | reply = m.reply_to_message 73 | if app.long(m) > 1: 74 | song_name = m.text.split(None, 1)[1] 75 | elif reply and app.long(m) == 1: 76 | song_name = reply.text or reply.caption 77 | elif not reply and app.long(m) == 1: 78 | return await app.send_edit( 79 | m, "Give a song name . . .", delme=3, text_type=["mono"] 80 | ) 81 | 82 | song_results = await app.get_inline_bot_results("DeezerMusicBot", song_name) 83 | 84 | try: 85 | # send to Saved Messages because hide_via doesn't work sometimes 86 | saved = await app.send_inline_bot_result( 87 | chat_id="me", 88 | query_id=song_results.query_id, 89 | result_id=song_results.results[0].id, 90 | hide_via=True, 91 | ) 92 | 93 | # forward as a new message from Saved Messages 94 | saved = await app.get_messages("me", int(saved.updates[1].message.id)) 95 | reply_to = m.reply_to_message.message_id if m.reply_to_message else None 96 | 97 | await app.send_audio( 98 | chat_id=m.chat.id, 99 | audio=str(saved.audio.file_id), 100 | reply_to_message_id=reply_to, 101 | caption=f"**Song:** `{song_name}`\n**Uploaded By:** {app.UserMention()}", 102 | ) 103 | 104 | # delete the message from Saved Messages 105 | await app.delete_messages("me", [saved.message_id, m.message_id]) 106 | except TimeoutError: 107 | return await app.send_edit( 108 | m, "Something went wrong, try again . . .", delme=3, text_type=["mono"] 109 | ) 110 | except Exception as e: 111 | await app.error(m, e) 112 | await app.send_edit( 113 | m, "Something went wrong, try again !", text_type=["mono"], delme=3 114 | ) 115 | 116 | 117 | @app.on_message(gen(["ly", "lyrics"], allow=["sudo", "channel"])) 118 | async def lyrics_handler(_, m: Message): 119 | try: 120 | cmd = m.command 121 | reply = m.reply_to_message 122 | 123 | if not reply and len(cmd) > 1: 124 | song_name = m.text.split(None, 1)[1] 125 | elif reply: 126 | if reply.audio: 127 | song_name = f"{reply.audio.title} {reply.audio.performer}" 128 | elif reply.text or reply.caption and len(cmd) == 1: 129 | song_name = reply.text or reply.caption 130 | elif reply.text and len(cmd) > 1: 131 | song_name = m.text.split(None, 1)[1] 132 | else: 133 | return await app.send_edit( 134 | m, "Give me a song name . . .", text_type=["mono"], delme=3 135 | ) 136 | 137 | elif not reply and len(cmd) == 1: 138 | return await app.send_edit( 139 | m, "Give me a song name . . .", text_type=["mono"], delme=3 140 | ) 141 | 142 | await app.send_edit(m, f"**Finding lyrics for:** `{song_name}`") 143 | 144 | lyrics_results = await app.get_inline_bot_results("ilyricsbot", song_name) 145 | 146 | try: 147 | # send to cloud because hide_via doesn't work sometimes 148 | saved = await app.send_inline_bot_result( 149 | chat_id="me", 150 | query_id=lyrics_results.query_id, 151 | result_id=lyrics_results.results[0].id, 152 | hide_via=True, 153 | ) 154 | await asyncio.sleep(0.50) 155 | 156 | # forward from Saved Messages 157 | await app.copy_message( 158 | chat_id=m.chat.id, 159 | from_chat_id="me", 160 | message_id=saved.updates[1].message.id, 161 | ) 162 | 163 | # delete the message from Saved Messages 164 | await app.delete_messages("me", saved.updates[1].message.id) 165 | except TimeoutError: 166 | return await app.send_edit( 167 | m, "Something went Wrong !", text_type=["mono"], delme=3 168 | ) 169 | except Exception as e: 170 | await app.error(m, e) 171 | await app.send_edit( 172 | m, 173 | "Something went wrong, please try again later !", 174 | text_type=["mono"], 175 | delme=3, 176 | ) 177 | -------------------------------------------------------------------------------- /asterix/modules/info.py: -------------------------------------------------------------------------------- 1 | from pyrogram.types import Message 2 | 3 | from asterix import app 4 | from asterix.helpers import gen 5 | 6 | app.CMD_HELP.update( 7 | { 8 | "info": ( 9 | "info", 10 | { 11 | "minfo [reply to media]": "Check media info including text information.", 12 | "chatinfo": "Get chats information.", 13 | }, 14 | ) 15 | } 16 | ) 17 | 18 | 19 | @app.on_message(gen("minfo", allow=["sudo"])) 20 | async def mediainfo_handler(_, m: Message): 21 | replied = m.reply_to_message 22 | if not replied: 23 | return await app.send_edit( 24 | m, "Please reply to some media to get media info . . .", text_type=["mono"] 25 | ) 26 | 27 | if (app.get_file_id(replied))["type"] == "photo": 28 | pie = replied.photo 29 | msg = "**Type:** Photo\n" 30 | msg += f"**Width:** `{pie.width}`\n" 31 | msg += f"**Height:** `{pie.height}`\n" 32 | msg += f"**Size:** `{pie.file_size}`\n" 33 | msg += f"**Date:** `{pie.date}`\n" 34 | if replied.caption: 35 | msg += f"**Caption:** `{replied.caption}`\n" 36 | else: 37 | msg += " " 38 | await app.send_edit( 39 | m, "**⚶ Media Information ⚶**\n\n" + msg, parse_mode="markdown" 40 | ) 41 | elif (app.get_file_id(replied))["type"] == "video": 42 | pie = replied.video 43 | msg = "**Types:** Video\n" 44 | msg += f"**Width:** `{pie.width}`\n" 45 | msg += f"**Height:** `{pie.height}`\n" 46 | msg += f"**Duration:** `{pie.duration}`\n" 47 | msg += f"**Mime type:** `{pie.mime_type}`\n" 48 | msg += f"**Size:** `{pie.file_size}`\n" 49 | msg += f"**Streamable:** `{pie.supports_streaming}`\n" 50 | msg += f"**Date:** `{pie.date}`\n" 51 | if replied.caption: 52 | msg += f"**Caption:** `{replied.caption}`\n" 53 | else: 54 | msg += " " 55 | await app.send_edit( 56 | m, "**⚶ Media Information ⚶**\n\n" + msg, parse_mode="markdown" 57 | ) 58 | elif (app.get_file_id(replied))["type"] == "sticker": 59 | pie = replied.sticker 60 | msg = "**Types:** sticker\n" 61 | msg += f"**File name:** `{pie.file_name}`\n" 62 | msg += f"**Width:** `{pie.width}`\n" 63 | msg += f"**Height:** `{pie.height}`\n" 64 | msg += f"**Mime type:** `{pie.mime_type}`\n" 65 | msg += f"**Size:** `{pie.file_size}`\n" 66 | msg += f"**Emoji:** `{pie.emoji}`\n" 67 | msg += f"**Animated:** `{pie.is_animated}`\n" 68 | msg += f"**Set name:** `{pie.set_name}`\n" 69 | msg += f"**Date:** `{pie.date}`\n" 70 | if replied.caption: 71 | msg += f"**Caption:** `{replied.caption}`\n" 72 | else: 73 | msg += " " 74 | await app.send_edit( 75 | m, "**⚶ Media Information ⚶**\n\n" + msg, parse_mode="markdown" 76 | ) 77 | elif (app.get_file_id(replied))["type"] == "document": 78 | pie = replied.document 79 | msg = "**Types:** Document\n" 80 | msg += f"**File name:** `{pie.file_name}`\n" 81 | msg += f"**Mime type:** `{pie.mime_type}`\n" 82 | msg += f"**Size:** `{pie.file_size}`\n" 83 | msg += f"**Date:** `{pie.date}`\n" 84 | if replied.caption: 85 | msg += f"**Caption:** `{replied.caption}`\n" 86 | else: 87 | msg += " " 88 | await app.send_edit( 89 | m, "**⚶ Media Information ⚶**\n\n" + msg, parse_mode="markdown" 90 | ) 91 | elif (app.get_file_id(replied))["type"] == "animation": 92 | pie = replied.animation 93 | msg = "**Types:** Animation\n" 94 | msg += f"**File name:** `{pie.file_name}`\n" 95 | msg += f"**Width:** `{pie.width}`\n" 96 | msg += f"**Height:** `{pie.height}`\n" 97 | msg += f"**Duration:** `{pie.duration}`\n" 98 | msg += f"**Mime type:** `{pie.mime_type}`\n" 99 | msg += f"**Size:** `{pie.file_size}`\n" 100 | msg += f"**Date:** `{pie.date}`\n" 101 | if replied.caption: 102 | msg += f"**Caption:** `{replied.caption}`\n" 103 | else: 104 | msg += " " 105 | await app.send_edit( 106 | m, "**⚶ Media Information ⚶**\n\n" + msg, parse_mode="markdown" 107 | ) 108 | elif (app.get_file_id(replied))["type"] == "audio": 109 | pie = replied.audio 110 | msg = "**Types:** Audio\n" 111 | msg += f"**Title:** `{pie.title}`\n" 112 | msg += f"**Performer:** `{pie.performer}`\n" 113 | msg += f"**File name:** `{pie.file_name}`\n" 114 | msg += f"**Duration:** `{pie.duration}`\n" 115 | msg += f"**Mime type:** `{pie.mime_type}`\n" 116 | msg += f"**Size:** `{pie.file_size}`\n" 117 | msg += f"**Date:** `{pie.date}`\n" 118 | if replied.caption: 119 | msg += f"**Caption:** `{replied.caption}`\n" 120 | else: 121 | msg += " " 122 | await app.send_edit( 123 | m, "**⚶ Media Information ⚶**\n\n" + msg, parse_mode="markdown" 124 | ) 125 | elif (app.get_file_id(replied))["type"] == "text": 126 | msg = "**Types:** Text\n" 127 | msg += f"**Text:** `{replied.text}`\n" 128 | await app.send_edit( 129 | m, "**⚶ Text Information ⚶**\n\n" + msg, parse_mode="markdown" 130 | ) 131 | 132 | 133 | @app.on_message(gen("chatinfo", allow=["sudo"])) 134 | async def chatinfo_handler(_, m: Message): 135 | try: 136 | if len(m.command) > 1: 137 | chat_u = m.command[1] 138 | chat = await app.get_chat(chat_u) 139 | else: 140 | if m.chat.type == "private": 141 | return await app.send_edit( 142 | m, 143 | "Please use it in groups or use `.chatinfo [group username or id]`", 144 | delme=2, 145 | ) 146 | 147 | else: 148 | chat_v = m.chat.id 149 | chat = await app.get_chat(chat_v) 150 | 151 | if bool(await app.get_profile_photos(m.chat.id)) is True: 152 | poto = await app.get_profile_photos(m.chat.id) 153 | else: 154 | poto = False 155 | 156 | m = await app.send_edit(m, "Processing . . .") 157 | neel = chat.permissions 158 | data = "**Chat Info:**\n\n" 159 | data += f"**Title:** `{chat.title}`\n" 160 | data += f"**Chat Id:** `{chat.id}`\n" 161 | data += f"**Chat Type:** `{chat.type}`\n" 162 | data += f"**Dc Id:** `{chat.dc_id}`\n" 163 | if chat.username: 164 | data += f"**Username:** `@{chat.username}`\n" 165 | data += f"**Members:** `{chat.members_count}`\n" 166 | data += f"**Description:** `{chat.description}`\n" 167 | data += f"**Permissions:**\n\n" 168 | data += f"**Send Messages:** `{neel.can_send_messages}`\n" 169 | data += f"**Send Media:** `{neel.can_send_media_messages}`\n" 170 | data += f"**Web Page Preview:** `{neel.can_add_web_page_previews}`\n" 171 | data += f"**Send Polls:** `{neel.can_send_polls}`\n" 172 | data += f"**Change Group Info:** `{neel.can_change_info}`\n" 173 | data += f"**Invite Users:** `{neel.can_invite_users}`\n" 174 | data += f"**Pin Messages:** `{neel.can_pin_messages}`\n" 175 | if poto and data: 176 | await app.send_cached_media( 177 | m.chat.id, file_id=poto[0].file_id, caption=data 178 | ) 179 | await m.delete() 180 | elif not poto: 181 | await app.send_edit(m, data) 182 | else: 183 | await app.send_edit( 184 | m, "Failed to get information of this group . . .", delme=2 185 | ) 186 | except Exception as e: 187 | await app.error(m, e) 188 | -------------------------------------------------------------------------------- /asterix/modules/notes.py: -------------------------------------------------------------------------------- 1 | from pyrogram.types import InlineKeyboardMarkup, Message 2 | 3 | from asterix import app 4 | from asterix.helpers import gen, regex 5 | 6 | app.CMD_HELP.update( 7 | { 8 | "notes": ( 9 | "notes", 10 | { 11 | "save [note mame ] [reply to message]": "Save A Note Of Any Type Of Media In Your Database.", 12 | ">": "Get Your Note. Example: `>mynote`, Where mynote is note name and command ( >)", 13 | "notes": "Get Your Saved Note List.", 14 | "clear": "Delete A Note.", 15 | }, 16 | ) 17 | } 18 | ) 19 | 20 | 21 | GET_FORMAT = { 22 | app.TEXT: app.send_message, 23 | app.DOCUMENT: app.send_document, 24 | app.PHOTO: app.send_photo, 25 | app.VIDEO: app.send_video, 26 | app.STICKER: app.send_sticker, 27 | app.AUDIO: app.send_audio, 28 | app.VOICE: app.send_voice, 29 | app.VIDEO_NOTE: app.send_video_note, 30 | app.ANIMATION: app.send_animation, 31 | app.ANIMATED_STICKER: app.send_sticker, 32 | app.CONTACT: app.send_contact, 33 | } 34 | 35 | 36 | @app.on_message(gen("save", allow=["sudo"])) 37 | async def savenote_hanlder(_, m: Message): 38 | reply = m.reply_to_message 39 | if app.long(m) == 1: 40 | return await app.send_edit( 41 | m, 42 | "A note name is required with command to save a note.", 43 | text_type=["mono"], 44 | ) 45 | 46 | note_name, text, message_type, content = app.GetNoteType(reply if reply else m) 47 | if not note_name: 48 | return await app.send_edit( 49 | m, "A note name is necessary to save a note !", text_type=["mono"] 50 | ) 51 | 52 | if message_type == app.TEXT: 53 | teks, button = app.ParseButton(text) 54 | if not teks: 55 | await app.send_edit( 56 | m, f"Text: `{m.text}`\n\nError: There is no text in here !" 57 | ) 58 | 59 | app.save_selfnote(m.from_user.id, note_name, text, message_type, content) 60 | await app.send_edit(m, "Saved note = **[ `{}` ]**".format(note_name)) 61 | 62 | 63 | @app.on_message(regex(">")) 64 | async def getnote_handler(_, m: Message): 65 | reply = m.reply_to_message 66 | if m.text and m.text.startswith(">"): 67 | if app.long(m) == 1: 68 | note = m.text.replace(">", "") 69 | else: 70 | return # no response 71 | 72 | getnotes = app.get_selfnote(m.from_user.id, note) 73 | 74 | if not getnotes: 75 | return await app.send_edit(m, "This note does not exist !") 76 | 77 | msg_id = reply.message_id if reply else None 78 | 79 | if getnotes["type"] == app.TEXT: 80 | teks, button = app.ParseButton(getnotes.get("value")) 81 | button = app.BuildKeyboard(button) 82 | if button: 83 | button = InlineKeyboardMarkup(button) 84 | else: 85 | button = False 86 | if button: 87 | return await app.send_edit( 88 | m, "Inline button not supported in this userbot version :(" 89 | ) 90 | else: 91 | await app.send_edit(m, teks) 92 | 93 | elif getnotes["type"] in ( 94 | app.STICKER, 95 | app.VOICE, 96 | app.VIDEO_NOTE, 97 | app.CONTACT, 98 | app.ANIMATED_STICKER, 99 | ): 100 | await m.delete() 101 | try: 102 | if msg_id: 103 | await GET_FORMAT[getnotes["type"]]( 104 | message.chat.id, getnotes["file"], reply_to_message_id=msg_id 105 | ) 106 | else: 107 | await GET_FORMAT[getnotes["type"]]( 108 | message.chat.id, getnotes["file"] 109 | ) 110 | except errors.exceptions.bad_request_400.BadRequest: 111 | msg = await app.get_messages(m.chat.id, getnotes["message_id"]) 112 | note_name, text, message_type, content = app.FetchNoteType(msg) 113 | app.save_selfnote( 114 | m.chat.id, 115 | note, 116 | "", 117 | getnotes["type"], 118 | content, 119 | getnotes["message_id"], 120 | ) 121 | if msg_id: 122 | await GET_FORMAT[getnotes["type"]]( 123 | m.chat.id, content, reply_to_message_id=msg_id 124 | ) 125 | else: 126 | await GET_FORMAT[getnotes["type"]](m.chat.id, content) 127 | else: 128 | await m.delete() 129 | if getnotes.get("value"): 130 | teks, button = app.ParseButton(getnotes.get("value")) 131 | button = app.BuildKeyboard(button) 132 | if button: 133 | button = InlineKeyboardMarkup(button) 134 | else: 135 | button = False 136 | else: 137 | teks = False 138 | button = False 139 | 140 | if button: 141 | return await app.send_edit( 142 | m, "Inline button not supported in this userbot." 143 | ) 144 | else: 145 | try: 146 | if msg_id: 147 | await GET_FORMAT[getnotes["type"]]( 148 | m.chat.id, 149 | getnotes["file"], 150 | caption=teks, 151 | reply_to_message_id=msg_id, 152 | ) 153 | else: 154 | await GET_FORMAT[getnotes["type"]]( 155 | m.chat.id, getnotes["file"], caption=teks 156 | ) 157 | except errors.exceptions.bad_request_400.BadRequest: 158 | msg = await app.get_messages(m.chat.id, getnotes["message_id"]) 159 | note_name, text, message_type, content = app.FetchNoteType(msg) 160 | app.save_selfnote( 161 | m.chat.id, 162 | note, 163 | teks, 164 | getnotes["type"], 165 | content, 166 | getnotes["message_id"], 167 | ) 168 | if msg_id: 169 | await GET_FORMAT[getnotes["type"]]( 170 | m.chat.id, 171 | getnotes["file"], 172 | caption=teks, 173 | reply_to_message_id=msg_id, 174 | ) 175 | else: 176 | await GET_FORMAT[getnotes["type"]]( 177 | m.chat.id, getnotes["file"], caption=teks 178 | ) 179 | 180 | 181 | @app.on_message(gen("notes", allow=["sudo"])) 182 | async def notelist_handler(_, m: Message): 183 | getnotes = app.get_all_selfnotes(m.from_user.id) 184 | if not getnotes: 185 | return await app.send_edit( 186 | m, "There are no saved notes !", text_type=["mono"], delme=4 187 | ) 188 | 189 | notelist = "**NOTEBOOK:**\n\n" 190 | for x in getnotes: 191 | notelist += f"`>{x}`\n" 192 | 193 | await app.send_edit(m, notelist) 194 | 195 | 196 | @app.on_message(gen("clear")) 197 | async def clearnote_handler(_, m: Message): 198 | if app.long(m) <= 1: 199 | return await app.send_edit( 200 | m, f"Sir, give me a note name after command, Ex: `{app.PREFIX}clear cat`" 201 | ) 202 | 203 | notename = m.text.split()[1] 204 | getnotes = app.rm_selfnote(m.from_user.id, notename) 205 | if not getnotes: 206 | return await app.send_edit(m, "This note does not exist!") 207 | else: 208 | await app.send_edit(m, f"Deleted note = **[ `{notename}` ]**") 209 | -------------------------------------------------------------------------------- /asterix/modules/pmpermit.py: -------------------------------------------------------------------------------- 1 | from pyrogram import filters 2 | from pyrogram.errors import PeerIdInvalid, UsernameInvalid, UsernameNotOccupied 3 | from pyrogram.types import Message 4 | 5 | from asterix import app, gen 6 | 7 | app.CMD_HELP.update( 8 | { 9 | "pmpermit": ( 10 | "pmpermit", 11 | { 12 | "a": "approve a user when pmpermit is on", 13 | "da": "disapprove a user when pmpermit is on", 14 | }, 15 | ) 16 | } 17 | ) 18 | 19 | 20 | async def old_msg(m: Message, user_id): 21 | """Delete warn messages""" 22 | if bool(app.get_msgid(user_id)) is True: 23 | old_msgs = app.get_msgid(user_id) 24 | await app.delete_messages(chat_id=m.chat.id, message_ids=old_msgs) 25 | return True 26 | return False 27 | 28 | 29 | async def send_warn(m: Message, user): 30 | """Send warning messages""" 31 | pic = app.PmpermitPic() 32 | text = app.PmpermitText() 33 | 34 | if pic: 35 | msg = await app.send_photo(m.chat.id, pic, caption=text) 36 | app.set_msgid(user, msg.message_id) 37 | return True 38 | elif not pic: 39 | msg = await app.send_message(m.chat.id, text, disable_web_page_preview=True) 40 | app.set_msgid(user, msg.message_id) 41 | return True 42 | else: 43 | return print("The bot didn't send pmpermit warning message.") 44 | return False 45 | 46 | 47 | # incoming autoblock 48 | @app.on_message( 49 | filters.private & filters.incoming & (~filters.bot & ~filters.me), group=-1 50 | ) 51 | async def pmpermit_handler(_, m: Message): 52 | try: 53 | users = [] 54 | is_user = False 55 | pmlimit = app.PmpermitLimit() 56 | 57 | if ( 58 | bool(app.Pmpermit()) is False or m.chat.is_verified 59 | ): # allow verified accounts 60 | return 61 | 62 | if bool(app.get_whitelist(m.chat.id)) is True: 63 | return 64 | else: 65 | # this will reduce the use of pyrogram's get_users method 66 | if bool(users): 67 | for x in users: 68 | if x.get(m.chat.id): 69 | is_user = True 70 | break 71 | 72 | if is_user: 73 | user = users.get(m.chat.id) 74 | else: 75 | user = await app.get_users(m.chat.id) 76 | users.append({m.chat.id: user}) # whole object 77 | 78 | # log user info to log chat 79 | 80 | msg = "#pmpermit\n\n" 81 | msg += f"Name: `{user.first_name}`\n" 82 | msg += f"Id: `{user.id}`\n" 83 | msg += ( 84 | f"Username: `@{user.username}`\n" 85 | if user.username 86 | else f"Username: `None`\n" 87 | ) 88 | msg += f"Message: `{m.text or m.caption}`\n" 89 | 90 | warns = bool(app.get_warn(user.id)) 91 | 92 | if warns is False: 93 | app.set_warn(user.id, 1) 94 | await send_warn(m, user.id) 95 | 96 | elif warns is True: 97 | warn = int(app.get_warn(user.id)) 98 | if warn < pmlimit: 99 | new_warn = warn + 1 100 | app.set_warn(user.id, new_warn) 101 | await old_msg(m, user.id) # delete old warns 102 | await send_warn(m, user.id) # send new warns 103 | elif warn >= pmlimit: 104 | done = await app.block_user(user.id) 105 | if done: 106 | try: 107 | await app.send_message( 108 | app.LOG_CHAT, 109 | f"{user.mention} is now blocked for spamming !", 110 | ) 111 | except PeerIdInvalid: 112 | print( 113 | f"{user.first_name} was blocked in your pm for some reason." 114 | ) 115 | else: 116 | await app.send_edit( 117 | m, 118 | f"Failed to block {user.mention} because through pmpermit.", 119 | text_type=["mono"], 120 | delme=4, 121 | ) 122 | else: 123 | print("Something went wrong in pmpermit") 124 | except Exception as e: 125 | await app.error(m, e) 126 | 127 | 128 | @app.on_message(gen(["a", "approve"], allow=["sudo"]), group=0) 129 | async def approve_handler(_, m: Message): 130 | if m.chat.type == "bot": 131 | return await app.send_edit( 132 | m, "No need to approve innocent bots !", text_type=["mono"], delme=4 133 | ) 134 | 135 | reply = m.reply_to_message 136 | cmd = m.command 137 | user_data = False 138 | 139 | if m.chat.type == "private": 140 | user_id = m.chat.id 141 | 142 | elif m.chat.type != "private": 143 | if reply: 144 | user_id = reply.from_user.id 145 | 146 | elif not reply and app.long(m) == 1: 147 | return await app.send_edit( 148 | m, "Whom should i approve, piro ?", text_type=["mono"], delme=4 149 | ) 150 | 151 | elif not reply and app.long(m) > 1: 152 | try: 153 | user_data = await app.get_users(cmd[1]) 154 | user_id = user_data.id 155 | except PeerIdInvalid: 156 | return await app.send_edit( 157 | m, 158 | "You have to pass username instead of user id.", 159 | text_type=["mono"], 160 | delme=4, 161 | ) 162 | except UsernameNotOccupied: 163 | return await app.send_edit( 164 | m, 165 | "This user doesn't exists in telegram.", 166 | text_type=["mono"], 167 | delme=4, 168 | ) 169 | except UsernameInvalid: 170 | return await app.send_edit( 171 | m, "The username | user id is invalid.", text_type=["mono"], delme=4 172 | ) 173 | 174 | else: 175 | return await app.send_edit( 176 | m, "Something went wrong.", text_type=["mono"], delme=4 177 | ) 178 | if user_data: 179 | info = user_data 180 | else: 181 | info = await app.get_users(user_id) 182 | 183 | try: 184 | m = await app.send_edit(m, f"`Approving` {info.mention} `. . .`") 185 | app.set_whitelist(user_id, True) 186 | await app.send_edit(m, f"{info.mention} `is now approved.`", delme=4) 187 | app.del_warn(user_id) 188 | 189 | if app.get_msgid(user_id): 190 | await old_msg(m, user_id) 191 | 192 | except Exception as e: 193 | await app.send_edit(m, f"Something went wrong.", text_type=["mono"], delme=4) 194 | await app.error(m, e) 195 | 196 | 197 | @app.on_message(gen(["da", "disapprove"], allow=["sudo"]), group=-2) 198 | async def diapprove_handler(_, m: Message): 199 | if m.chat.type == "bot": 200 | return await app.send_edit( 201 | m, "No need to approve innocent bots !", text_type=["mono"], delme=4 202 | ) 203 | 204 | reply = m.reply_to_message 205 | cmd = m.command 206 | user_data = False 207 | 208 | if m.chat.type == "private": 209 | user_id = m.chat.id 210 | 211 | elif m.chat.type != "private": 212 | if reply: 213 | user_id = reply.from_user.id 214 | 215 | elif not reply and app.long(m) == 1: 216 | return await app.send_edit( 217 | m, "Whom should i disapprove, piro ?", text_type=["mono"], delme=4 218 | ) 219 | 220 | elif not reply and app.long(m) > 1: 221 | try: 222 | user_data = await app.get_users(cmd[1]) 223 | user_id = user_data.id 224 | except PeerIdInvalid: 225 | return await app.send_edit( 226 | m, "Pass username instead of user id.", text_type=["mono"], delme=4 227 | ) 228 | except UsernameNotOccupied: 229 | return await app.send_edit( 230 | m, 231 | "This user doesn't exists in telegram.", 232 | text_type=["mono"], 233 | delme=4, 234 | ) 235 | except UsernameInvalid: 236 | return await app.send_edit( 237 | m, "The username | user id is invalid.", text_type=["mono"], delme=4 238 | ) 239 | else: 240 | return await app.send_edit( 241 | m, "Failed to disapprove user !", text_type=["mono"], delme=4 242 | ) 243 | if user_data: 244 | info = user_data 245 | else: 246 | info = await app.get_users(user_id) 247 | 248 | if info: 249 | m = await app.send_edit(m, f"`Disapproving` {info.mention} `. . .`") 250 | app.del_whitelist(user_id) 251 | await app.send_edit( 252 | m, f"{info.mention} `has been disapproved for pm.`", delme=4 253 | ) 254 | try: 255 | await app.send_message( 256 | app.LOG_CHAT, f"#disallow\n\n{info.mention} `has been disapproved.`" 257 | ) 258 | except PeerIdInvalid: 259 | print(f"{info.first_name} has been disapproved.") 260 | else: 261 | return await app.send_edit( 262 | m, "Sorry there is no user id to disapprove.", text_type=["mono"], delme=4 263 | ) 264 | -------------------------------------------------------------------------------- /asterix/modules/supertools.py: -------------------------------------------------------------------------------- 1 | import os 2 | from html import escape 3 | 4 | import requests 5 | from gtts import gTTS 6 | from pyrogram.types import Message 7 | 8 | from asterix import app, gen 9 | 10 | app.CMD_HELP.update( 11 | { 12 | "supertools": ( 13 | "supertools", 14 | { 15 | "ud [query]": "Get The Meaning Of Any Word In Urban Dictionary.", 16 | "short [link]": "Shorten a link into da.gd link.", 17 | "unshort [shortlink]": "Reverse the da.gd link to real link.", 18 | "tts [reply to text]": "Text To Speech, Convert Text Message To Voice | audio (mp3).", 19 | "wtr [city name]": "Type Command And Your City Name To Get Weather Details.", 20 | "ws [site link]": "Take A Screenshot Of Any Website And Get The Image Of That Site.", 21 | "undlt [count]": "Get deleted messages from recent history of group . . .", 22 | }, 23 | ) 24 | } 25 | ) 26 | 27 | 28 | weather_lang_code = "en" 29 | 30 | lang_code = os.getenv("LANG_CODE", "en") 31 | 32 | 33 | def replace_text(text): 34 | return text.replace('"', "").replace("\\r", "").replace("\\n", "").replace("\\", "") 35 | 36 | 37 | async def text_to_voice(m: Message, text): 38 | tts = gTTS(text, lang=lang_code) 39 | tts.save(f"{app.TEMP_DICT}voice.mp3") 40 | await app.send_voice( 41 | m.chat.id, voice=f"{app.TEMP_DICT}voice.mp3", reply_to_message_id=m.message_id 42 | ) 43 | await m.delete() 44 | os.remove(f"{app.TEMP_DICT}voice.mp3") 45 | return 46 | 47 | 48 | async def shorten_link(m: Message, text): 49 | sample_url = f"https://da.gd/s?url={text}" 50 | response = requests.get(sample_url).text 51 | if response: 52 | await app.send_edit( 53 | m, 54 | f"**Generated Link:**\n\nShorted Link: {response}\nYour Link: {text}", 55 | disable_web_page_preview=True, 56 | ) 57 | else: 58 | await app.send_edit( 59 | m, "something is wrong. please try again later.", text_type=["mono"] 60 | ) 61 | 62 | 63 | async def unshorten_link(m: Message, text): 64 | if not text.startswith("https://da.gd/"): 65 | await app.send_edit( 66 | m, "Please Give me a valid link that starts with `https://da.gd/`" 67 | ) 68 | else: 69 | r = requests.get(text, allow_redirects=False) 70 | if str(r.status_code).startswith("3"): 71 | fakelink = r.headers["Location"] 72 | await app.send_edit( 73 | m, 74 | f"**Generated Links:**\n\nUnshorted Link: {fakelink}\nYour Link: {text}", 75 | disable_web_page_preview=True, 76 | ) 77 | else: 78 | await app.send_edit( 79 | m, 80 | "Something went wrong, please try again later . . .", 81 | text_type=["mono"], 82 | ) 83 | 84 | 85 | @app.on_message(gen("tts", allow=["sudo", "channel"])) 86 | async def tts_handler(_, m: Message): 87 | reply = m.reply_to_message 88 | 89 | try: 90 | if not reply and app.long(m) == 1: 91 | return await app.send_edit( 92 | m, 93 | "Reply to someone's text message or give me the text as a suffix . . .", 94 | delme=True, 95 | text_type=["mono"], 96 | ) 97 | 98 | elif not reply and app.long(m) > 1: 99 | await app.send_edit(m, "Converting text to voice . . .", text_type=["mono"]) 100 | text = m.text.split(None, 1)[1] 101 | await text_to_voice(m, text) 102 | 103 | elif reply: 104 | if not reply.text: 105 | return await app.send_edit( 106 | m, "Please reply to a text . . .", text_type=["mono"], delme=3 107 | ) 108 | await app.send_edit(m, "Converting text to voice . . .", text_type=["mono"]) 109 | text = reply.text 110 | await text_to_voice(m, text) 111 | 112 | else: 113 | await app.send_edit(m, "Something went wrong !", text_type=["mono"]) 114 | except Exception as e: 115 | await app.error(m, e) 116 | 117 | 118 | @app.on_message(gen("ud", allow=["sudo", "channel"])) 119 | async def ud_handler(_, m: Message): 120 | if app.long(m) == 1: 121 | return await app.send_edit(m, f"Use: `{app.PREFIX}ud cats`") 122 | 123 | try: 124 | await app.send_edit(m, f"Searching for `{m.text.split(None, 1)[1]}`") 125 | text = m.text.split(None, 1)[1] 126 | response = await app.get_json( 127 | f"http://api.urbandictionary.com/v0/define?term={text}" 128 | ) 129 | word = response["list"][0]["word"] 130 | definition = response["list"][0]["definition"] 131 | example = response["list"][0]["example"] 132 | resp = ( 133 | f"**Text**: __`{replace_text(word)}`__\n\n" 134 | f"**Meaning:**\n\n`{replace_text(definition)}`\n\n" 135 | f"**Example:**\n\n`{replace_text(example)}` " 136 | ) 137 | await app.send_edit(m, resp) 138 | except IndexError: 139 | await app.send_edit(m, "No Results Found !", text_type=["mono"], delme=3) 140 | except Exception as e: 141 | await app.error(m, e) 142 | 143 | 144 | @app.on_message(gen("short", allow=["sudo", "channel"])) 145 | async def shortlink_handler(_, m: Message): 146 | reply = m.reply_to_message 147 | try: 148 | if not reply and app.long(m) == 1: 149 | return await app.send_edit( 150 | m, "Please give me some link or reply to a link", text_type=["mono"] 151 | ) 152 | 153 | if not reply and app.long(m) > 1: 154 | text = m.text.split(None, 1)[1] 155 | await shorten_link(m, text) 156 | elif reply: 157 | if not reply.text: 158 | return await app.send_edit( 159 | m, "Please reply to text . . .", text_type=["mono"] 160 | ) 161 | text = reply.text 162 | await shorten_link(m, text) 163 | except Exception as e: 164 | await app.error(m, e) 165 | 166 | 167 | @app.on_message(gen(["unshort", "noshort"], allow=["sudo", "channel"])) 168 | async def unshortlink_handler(_, m: Message): 169 | reply = m.reply_to_message 170 | try: 171 | if not reply and app.long(m) == 1: 172 | return await app.send_edit( 173 | m, 174 | "Please give me a da.gd link to convert to orginal link", 175 | text_type=["mono"], 176 | ) 177 | 178 | elif not reply and app.long(m) > 1: 179 | text = m.text.split(None, 1)[1] 180 | await unshorten_link(m, text) 181 | 182 | elif reply: 183 | if not reply.text: 184 | return await app.send_edit( 185 | m, "Please reply to a text . . .", text_type=["mono"] 186 | ) 187 | text = reply.text 188 | await unshorten_link(m, text) 189 | 190 | else: 191 | await app.send_edit( 192 | m, "Something went wrong, try again later !", text_type=["mono"] 193 | ) 194 | except Exception as e: 195 | await app.error(m, e) 196 | 197 | 198 | @app.on_message(gen(["wtr", "weather"], allow=["sudo", "channel"])) 199 | async def weather_handler(_, m: Message): 200 | if app.long(m) == 1: 201 | return await app.send_edit( 202 | m, "Piro Master Atleast Give Me Some Location !", text_type=["mono"] 203 | ) 204 | 205 | await app.send_edit(m, "Checking weather . . .", text_type=["mono"]) 206 | location = m.command[1] 207 | headers = {"user-agent": "httpie"} 208 | response = requests.get( 209 | f"https://wttr.in/{location}?mnTC0&lang={weather_lang_code}", headers=headers 210 | ) 211 | if ( 212 | "Sorry, we processed more than 1M requests today and we ran out of our datasource capacity." 213 | in response.text 214 | ): 215 | return await app.send_edit( 216 | m, "Too many requests, try again later !", text_type=["mono"] 217 | ) 218 | 219 | weather = f"__{escape(response.text)}__" 220 | await app.send_edit(m, weather) 221 | 222 | 223 | @app.on_message(gen(["ws", "webshot"], allow=["sudo", "channel"])) 224 | async def webshot_handler(_, m: Message): 225 | if app.long(m) > 1: 226 | try: 227 | BASE = "https://render-asterix.appspot.com/screenshot/" 228 | url = m.command[1] 229 | path = "./downloads/screenshot.jpg" 230 | response = requests.get(BASE + url, stream=True) 231 | 232 | if response.status_code == 200: 233 | with open(path, "wb") as file: 234 | for chunk in response: 235 | file.write(chunk) 236 | await app.send_edit(m, "generating pic . . .", text_type=["mono"]) 237 | await app.send_document(m.chat.id, path, caption=url) 238 | await m.delete() 239 | os.remove(path) 240 | except Exception as e: 241 | await app.error(m, e) 242 | else: 243 | await app.send_edit(m, "Give me the link pro . . .", text_type=["mono"]) 244 | 245 | 246 | @app.on_message(gen("undlt", allow=["sudo"])) 247 | async def undlt_handler(_, m: Message): 248 | collect = [] 249 | collect.clear() 250 | 251 | if app.long(m) == 1: 252 | count = 5 253 | elif app.long(m) > 1: 254 | count = m.command[1] 255 | if count.isdigit(): 256 | count = int(count) 257 | else: 258 | count = 5 259 | try: 260 | async for x in app.iter_history(m.chat.id, limit=count): 261 | if x.text: 262 | collect.append(f"**Message:** `{x.text}`\n\n") 263 | await app.send_edit(m, "".join(collect)) 264 | except Exception as e: 265 | await app.error(m, e) 266 | -------------------------------------------------------------------------------- /asterix/modules/fun.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import random 3 | import time 4 | 5 | import requests 6 | from pyrogram.errors import FloodWait 7 | 8 | from asterix import app 9 | from asterix.helpers import gen 10 | 11 | app.CMD_HELP.update( 12 | { 13 | "fun": ( 14 | "fun", 15 | { 16 | "upcase [text]": "Convert texts into uppercase", 17 | "slap [reply to user]": "Slap your friends with amazing items.", 18 | "type [text]": "Retype words with animation, just try and understand, Don't Use too much.", 19 | "insult [reply to message]": "Use it to insult idiots & fools", 20 | "advice [reply to message]": "get a random advice for someone.", 21 | "wtd": "what to do when you are bored ?, finds a activity for you.", 22 | "mqt": "Finds some movie quotes for you.", 23 | "joke": "Get some daddy jokes.", 24 | }, 25 | ) 26 | } 27 | ) 28 | 29 | 30 | @app.on_message(gen("slap", allow=["sudo"])) 31 | async def slap_handler(_, m): 32 | if m.reply_to_message: 33 | try: 34 | m = await app.send_edit(m, ". . .") 35 | 36 | my_info = app.UserMention() 37 | user = m.reply_to_message.from_user 38 | user_info = user.mention 39 | TASK = ( 40 | f"{my_info} slaps {user_info} with a bunch of cardboards", 41 | f"{my_info} hits {user_info} in the face with cows", 42 | f"{my_info} ties {user_info} on a chair and rubs him with a sandpaper", 43 | f"{my_info} helped {user_info} swimming in lava", 44 | f"{my_info} starts slapping {user_info} with Titanic ship", 45 | f"{my_info} fills a book of physics in {user_info} mouth", 46 | f"{my_info} gives a cup of poison to {user_info} ", 47 | f"{my_info} slaps {user_info} with bunch of dead mosquito", 48 | f"{my_info} hits {user_info}'s face with rubber chicken", 49 | f"{my_info} starts puts {user_info} in water with phirana", 50 | f"{my_info} dumps {user_info} in a river", 51 | f"{my_info} pats {user_info} on head", 52 | f"{my_info} kicks {user_info} out of the conversation", 53 | ) 54 | await app.send_edit(m, f"{random.choice(TASK)}") 55 | 56 | except Exception as e: 57 | await app.error(m, e) 58 | else: 59 | await app.send_edit( 60 | m, 61 | "Reply to a friend to use harsh words to insult him", 62 | delme=2, 63 | text_type=["mono"], 64 | ) 65 | 66 | 67 | @app.on_message(gen(["upcase"], allow=["sudo"])) 68 | async def uppercase_handler(_, m): 69 | try: 70 | reply = m.reply_to_message 71 | if reply: 72 | text = reply.text.upper() 73 | await app.send_edit(m, text) 74 | elif not reply: 75 | if app.long(m) > 1: 76 | text = m.text.split(None, 1)[1].upper() 77 | await app.send_edit(m, text) 78 | elif app.long(m) == 1: 79 | await app.send_edit( 80 | m, 81 | "Please give me some text after command . . .", 82 | delme=2, 83 | text_type=["mono"], 84 | ) 85 | else: 86 | return await app.send_edit( 87 | m, "Something went wrong !", text_type=["mono"], delme=4 88 | ) 89 | except Exception as e: 90 | await app.error(m, e) 91 | 92 | 93 | @app.on_message(gen("type", allow=["sudo"])) 94 | async def type_handler(_, m): 95 | try: 96 | if app.long(m) > 1: 97 | text = [x for x in m.text.split(None, 1)[1]] 98 | else: 99 | return await app.send_edit( 100 | m, "Some text is required to show in typing animation", delme=2 101 | ) 102 | 103 | tbp = "" 104 | typing_symbol = "▒" 105 | for i in range(len(text)): 106 | try: 107 | await app.send_edit(m, tbp + typing_symbol) 108 | await asyncio.sleep(0.40) 109 | tbp = tbp + text[i] 110 | await app.send_edit(m, tbp) 111 | await asyncio.sleep(0.40) 112 | except FloodWait as e: 113 | time.sleep(e.x) # continue 114 | except Exception as e: 115 | await app.error(m, e) 116 | 117 | 118 | @app.on_message(gen("insult", allow=["sudo"])) 119 | async def insult_handler(_, m): 120 | reply = m.reply_to_message 121 | if not reply: 122 | await app.send_edit( 123 | m, 124 | "Please reply to someone, so that i can insult them . . .", 125 | delme=2, 126 | text_type=["mono"], 127 | ) 128 | elif reply: 129 | try: 130 | if app.long(m) == 1: 131 | lang = "en" 132 | elif app.long(m) > 1: 133 | lang = m.command[1] 134 | data = requests.get( 135 | f"https://evilinsult.com/generate_insult.php?lang={lang}&type=json" 136 | ) 137 | _data = data.json() 138 | 139 | m = await app.send_edit(m, "Insulting . . .", text_type=["mono"]) 140 | if _data: 141 | await app.send_edit(m, f"`{_data.get('insult')}`") 142 | else: 143 | await app.send_edit( 144 | m, "No insults found !", delme=4, text_type=["mono"] 145 | ) 146 | except Exception as e: 147 | await app.error(m, e) 148 | 149 | 150 | @app.on_message(gen("advice", allow=["sudo"])) 151 | async def advice_handler(_, m): 152 | reply = m.reply_to_message 153 | if not reply: 154 | await app.send_edit( 155 | m, 156 | "Please reply to someone, so that i can give them a advice . . .", 157 | delme=2, 158 | text_type=["mono"], 159 | ) 160 | elif reply: 161 | try: 162 | m = await app.send_edit( 163 | m, "Finding a good advice . . .", text_type=["mono"] 164 | ) 165 | data = requests.get(f"https://api.adviceslip.com/advice") 166 | _data = data.json().get("slip").get("advice") 167 | if _data: 168 | await app.send_edit(m, f"`{_data}`") 169 | else: 170 | await app.send_edit(m, "No advice found !", delme=2, text_type=["mono"]) 171 | except Exception as e: 172 | await app.error(m, e) 173 | 174 | 175 | @app.on_message(gen("qs", allow=["sudo"])) 176 | async def question_handler(_, m): 177 | reply = m.reply_to_message 178 | if not reply: 179 | await app.send_edit( 180 | m, 181 | "Please reply to someone, so that i can give them a question . . .", 182 | delme=2, 183 | text_type=["mono"], 184 | ) 185 | elif reply: 186 | try: 187 | m = await app.send_edit(m, "Finding a question . . .", text_type=["mono"]) 188 | data = requests.get(f"http://jservice.io/api/random") 189 | question = data.json()[0].get("question") 190 | answer = data.json()[0].get("answer") 191 | if question and answer: 192 | await app.send_edit(m, f"Question:\n\n`{question}`") 193 | await app.send_message( 194 | "me", f"Answer:\n\n`{answer}`" 195 | ) # answer in saved messages 196 | else: 197 | await app.send_edit( 198 | m, "No question found !", delme=2, text_type=["mono"] 199 | ) 200 | except Exception as e: 201 | await app.error(m, e) 202 | 203 | 204 | @app.on_message(gen("wtd", allow=["sudo"])) 205 | async def whattodo_handler(_, m): 206 | try: 207 | m = await app.send_edit(m, "Finding a activity . . .", text_type=["mono"]) 208 | data = requests.get(f"http://www.boredapi.com/api/activity/") 209 | act = data.json().get("activity") 210 | typ = data.json().get("type") 211 | if act: 212 | await app.send_edit(m, f"Activity: `{act}`\n\nType: `{typ}`") 213 | else: 214 | await app.send_edit(m, "No Activity found !", delme=2, text_type=["mono"]) 215 | except Exception as e: 216 | await app.error(m, e) 217 | 218 | 219 | @app.on_message(gen("mqt", allow=["sudo"])) 220 | async def moviequote_handler(_, m): 221 | try: 222 | m = await app.send_edit(m, "Finding a movie quote . . .", text_type=["mono"]) 223 | data = requests.get(f"https://movie-quote-api.herokuapp.com/v1/quote/") 224 | qt = data.json().get("quote") 225 | role = data.json().get("role") 226 | show = data.json().get("show") 227 | if qt and role and show: 228 | await app.send_edit( 229 | m, f"**Quote:**\n\n`{qt}`\n\nRole: `{role}`\n\nShow: `{show}`" 230 | ) 231 | else: 232 | await app.send_edit( 233 | m, "No movie quotes found !", delme=2, text_type=["mono"] 234 | ) 235 | except Exception as e: 236 | await app.error(m, e) 237 | 238 | 239 | @app.on_message(gen("joke", allow=["sudo"])) 240 | async def joke_handler(_, m): 241 | try: 242 | m = await app.send_edit(m, "Finding a joke . . .", text_type=["mono"]) 243 | data = requests.get(f"https://official-joke-api.appspot.com/random_joke") 244 | one = data.json().get("setup") 245 | two = data.json().get("punchline") 246 | if bool(data) is False: 247 | return app.send_edit( 248 | m, 249 | "Site is down, please try again later . . .", 250 | delme=2, 251 | text_type=["mono"], 252 | ) 253 | if one and two: 254 | await app.send_edit(m, f"Person: `{one}`\n\nMe: `{two}`") 255 | else: 256 | await app.send_edit(m, "No jokes found !", delme=2, text_type=["mono"]) 257 | except Exception as e: 258 | await app.send_edit( 259 | m, "Server error, try again later.", text_type=["mono"], delme=4 260 | ) 261 | await app.error(m, e) 262 | --------------------------------------------------------------------------------