async def stmute_usr(c: Alita, m: Message): if len(m.text.split()) == 1 and not m.reply_to_message: await m.reply_text("Я не могу никого замьютить!") return try: user_id, _, _ = await extract_user(c, m) except Exception: return if not user_id: await m.reply_text("Cannot find user to mute !") return if user_id == Config.BOT_ID: await m.reply_text("Huh, why would I mute myself?") return if user_id in SUPPORT_STAFF: LOGGER.info( f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", ) await m.reply_text(tlang(m, "admin.support_cannot_restrict")) return try: admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]} except KeyError: admins_group = await admin_cache_reload(m, "mute") if user_id in admins_group: await m.reply_text(tlang(m, "admin.mute.admin_cannot_mute")) return if m.reply_to_message and len(m.text.split()) >= 2: reason = m.text.split(None, 2)[1] elif not m.reply_to_message and len(m.text.split()) >= 3: reason = m.text.split(None, 2)[2] else: await m.reply_text("Read /help !!") return if not reason: await m.reply_text( "You haven't specified a time to mute this user for!") return split_reason = reason.split(None, 1) time_val = split_reason[0].lower() reason = split_reason[1] if len(split_reason) > 1 else "" mutetime = await extract_time(m, time_val) if not mutetime: return try: await m.chat.restrict_member( user_id, ChatPermissions(), mutetime, ) LOGGER.info(f"{m.from_user.id} stmuted {user_id} in {m.chat.id}") await m.delete() if m.reply_to_message: await m.reply_to_message.delete() except ChatAdminRequired: await m.reply_text(tlang(m, "admin.not_admin")) except RightForbidden: await m.reply_text(tlang(m, "admin.mute.bot_no_right")) except UserNotParticipant: await m.reply_text( "How can I mute a user who is not a part of this chat?") except RPCError as ef: await m.reply_text((tlang(m, "general.some_error")).format( SUPPORT_GROUP=SUPPORT_GROUP, ef=ef, ), ) LOGGER.error(ef) return
async def get_note_func(c: Alita, m: Message, note_name, priv_notes_status): """Get the note in normal mode, with parsing enabled.""" reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text reply_msg_id = m.reply_to_message.message_id if m.reply_to_message else m.message_id if priv_notes_status: from alita import BOT_USERNAME note_hash = [ i[1] for i in db.get_all_notes(m.chat.id) if i[0] == note_name ][0] await reply_text( f"Click on the button to get the note <code>{note_name}</code>", reply_markup=InlineKeyboardMarkup([ [ InlineKeyboardButton( "Click Me!", url= f"https://t.me/{BOT_USERNAME}?start=note_{m.chat.id}_{note_hash}", ), ], ], ), ) return getnotes = db.get_note(m.chat.id, note_name) msgtype = getnotes["msgtype"] if not msgtype: await reply_text("<b>Error:</b> Cannot find a type for this note!!") return try: # support for random notes texts splitter = "%%%" note_reply = getnotes["note_value"].split(splitter) note_reply = choice(note_reply) except KeyError: note_reply = "" parse_words = [ "first", "last", "fullname", "username", "id", "chatname", "mention", ] text = await escape_mentions_using_curly_brackets(m, note_reply, parse_words) if msgtype == Types.TEXT: teks, button = await parse_button(text) button = await build_keyboard(button) button = InlineKeyboardMarkup(button) if button else None if button: try: await reply_text( teks, reply_markup=button, disable_web_page_preview=True, quote=True, ) return except RPCError as ef: await reply_text( "An error has occured! Cannot parse note.", quote=True, ) LOGGER.error(ef) LOGGER.error(format_exc()) return else: await reply_text(teks, quote=True, disable_web_page_preview=True) return elif msgtype in ( Types.STICKER, Types.VIDEO_NOTE, Types.CONTACT, Types.ANIMATED_STICKER, ): await (await send_cmd(c, msgtype))( m.chat.id, getnotes["fileid"], reply_to_message_id=reply_msg_id, ) else: if getnotes["note_value"]: teks, button = await parse_button(text) button = await build_keyboard(button) button = InlineKeyboardMarkup(button) if button else None else: teks = "" button = None if button: try: await (await send_cmd(c, msgtype))( m.chat.id, getnotes["fileid"], caption=teks, reply_markup=button, reply_to_message_id=reply_msg_id, ) return except RPCError as ef: await m.reply_text( teks, reply_markup=button, disable_web_page_preview=True, reply_to_message_id=reply_msg_id, ) LOGGER.error(ef) LOGGER.error(format_exc()) return else: await (await send_cmd(c, msgtype))( m.chat.id, getnotes["fileid"], caption=teks, ) LOGGER.info( f"{m.from_user.id} fetched note {note_name} (type - {getnotes}) in {m.chat.id}", ) return
async def gban(c: Alita, m: Message): if len(m.text.split()) == 1: await m.reply_text(tlang(m, "antispam.gban.how_to")) return if len(m.text.split()) == 2 and not m.reply_to_message: await m.reply_text(tlang(m, "antispam.gban.enter_reason")) return user_id, user_first_name, _ = await extract_user(c, m) if m.reply_to_message: gban_reason = m.text.split(None, 1)[1] else: gban_reason = m.text.split(None, 2)[2] if user_id in SUPPORT_STAFF: await m.reply_text(tlang(m, "antispam.part_of_support")) return if user_id == BOT_ID: await m.reply_text(tlang(m, "antispam.gban.not_self")) return if db.check_gban(user_id): db.update_gban_reason(user_id, gban_reason) await m.reply_text( (tlang(m, "antispam.gban.updated_reason")).format( gban_reason=gban_reason, ), ) return db.add_gban(user_id, gban_reason, m.from_user.id) await m.reply_text( (tlang(m, "antispam.gban.added_to_watch")).format( first_name=user_first_name, ), ) LOGGER.info(f"{m.from_user.id} gbanned {user_id} from {m.chat.id}") log_msg = (tlang(m, "antispam.gban.log_msg")).format( chat_id=m.chat.id, ban_admin=(await mention_html(m.from_user.first_name, m.from_user.id)), gbanned_user=(await mention_html(user_first_name, user_id)), gban_user_id=user_id, time=(datetime.utcnow().strftime("%H:%M - %d-%m-%Y")), ) await c.send_message(MESSAGE_DUMP, log_msg) try: # Send message to user telling that he's gbanned await c.send_message( user_id, (tlang(m, "antispam.gban.user_added_to_watch")).format( gban_reason=gban_reason, SUPPORT_GROUP=SUPPORT_GROUP, ), ) except UserIsBlocked: LOGGER.error("Could not send PM Message, user blocked bot") except PeerIdInvalid: LOGGER.error( "Haven't seen this user anywhere, mind forwarding one of their messages to me?", ) except Exception as ef: # TO DO: Improve Error Detection LOGGER.error(ef) LOGGER.error(format_exc()) return
async def warn(c: Alita, m: Message): from alita import BOT_ID, BOT_USERNAME if m.reply_to_message: r_id = m.reply_to_message.message_id if len(m.text.split()) >= 2: reason = m.text.split(None, 1)[1] else: reason = None elif not m.reply_to_message: r_id = m.message_id if len(m.text.split()) >= 3: reason = m.text.split(None, 2)[2] else: reason = None else: reason = None if not len(m.command) > 1 and not m.reply_to_message: await m.reply_text( "I can't warn nothing! Tell me user whom I should warn") return user_id, user_first_name, _ = await extract_user(c, m) if user_id == BOT_ID: await m.reply_text("Huh, why would I warn myself?") return if user_id in SUPPORT_STAFF: await m.reply_text(tlang(m, "admin.support_cannot_restrict")) LOGGER.info( f"{m.from_user.id} trying to warn {user_id} (SUPPORT_STAFF) in {m.chat.id}", ) return try: admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]} except KeyError: admins_group = { i[0] for i in (await admin_cache_reload(m, "warn_user")) } if user_id in admins_group: await m.reply_text( "This user is admin in this chat, I can't warn them!") return warn_db = Warns(m.chat.id) warn_settings_db = WarnSettings(m.chat.id) _, num = warn_db.warn_user(user_id, reason) warn_settings = warn_settings_db.get_warnings_settings() if num >= warn_settings["warn_limit"]: if warn_settings["warn_mode"] == "kick": await m.chat.kick_member(user_id, until_date=int(time() + 45)) action = "kicked" elif warn_settings["warn_mode"] == "ban": await m.chat.kick_member(user_id) action = "banned" elif warn_settings["warn_mode"] == "mute": await m.chat.restrict_member(user_id, ChatPermissions()) action = "muted" await m.reply_text( (f"Warnings {num}/{warn_settings['warn_limit']}!" f"\n<b>Reason for last warn</b>:\n{reason}" if reason else "\n" f"{(await mention_html(user_first_name, user_id))} has been <b>{action}!</b>" ), reply_to_message_id=r_id, ) await m.stop_propagation() rules = Rules(m.chat.id).get_rules() if rules: kb = InlineKeyboardButton( "Rules 📋", url=f"https://t.me/{BOT_USERNAME}?start=rules_{m.chat.id}", ) else: kb = InlineKeyboardButton( "Kick ⚠️", callback_data=f"warn.kick.{user_id}", ) if m.text.split()[0] == "/swarn": await m.delete() await m.stop_propagation() if m.text.split()[0] == "/dwarn": if not m.reply_to_message: await m.reply_text( "Reply to a message to delete it and ban the user!") await m.stop_propagation() await m.reply_to_message.delete() txt = f"{(await mention_html(user_first_name, user_id))} has {num}/{warn_settings['warn_limit']} warnings!" txt += f"\n<b>Reason for last warn</b>:\n{reason}" if reason else "" await m.reply_text( txt, reply_markup=InlineKeyboardMarkup([ [ InlineKeyboardButton( "Remove Warn ❌", callback_data=f"warn.remove.{user_id}", ), ] + [kb], ], ), reply_to_message_id=r_id, ) await m.stop_propagation()
async def unlock_perm(c: Alita, m: Message): ( umsg, umedia, ustickers, uanimations, ugames, uinlinebots, uwebprev, uinfo, upolls, uinvite, upin, uperm, ) = ("", "", "", "", "", "", "", "", "", "", "", "") if len(m.text.split()) < 2: await m.reply_text("Please enter a permission to unlock!") return unlock_type = m.text.split(None, 1)[1] chat_id = m.chat.id if not unlock_type: await m.reply_text(tlang(m, "locks.unlocks_perm_sp")) return get_uperm = m.chat.permissions umsg = get_uperm.can_send_messages umedia = get_uperm.can_send_media_messages ustickers = get_uperm.can_send_stickers uanimations = get_uperm.can_send_animations ugames = get_uperm.can_send_games uinlinebots = get_uperm.can_use_inline_bots uwebprev = get_uperm.can_add_web_page_previews upolls = get_uperm.can_send_polls uinfo = get_uperm.can_change_info uinvite = get_uperm.can_invite_users upin = get_uperm.can_pin_messages if unlock_type == "all": try: await c.set_chat_permissions( chat_id, ChatPermissions( can_send_messages=True, can_send_media_messages=True, can_send_stickers=True, can_send_animations=True, can_send_games=True, can_use_inline_bots=True, can_send_polls=True, can_change_info=True, can_invite_users=True, can_pin_messages=True, can_add_web_page_previews=True, ), ) LOGGER.info( f"{m.from_user.id} unlocked all permissions in {m.chat.id}") await prevent_approved( m) # Don't lock permissions for approved users! await m.reply_text("🔓 " + (tlang(m, "locks.unlock_all"))) except ChatAdminRequired: await m.reply_text(tlang(m, "general.no_perm_admin")) return if unlock_type == "msg": umsg = True uperm = "messages" elif unlock_type == "media": umedia = True uperm = "audios, documents, photos, videos, video notes, voice notes" elif unlock_type == "stickers": ustickers = True uperm = "stickers" elif unlock_type == "animations": uanimations = True uperm = "animations" elif unlock_type == "games": ugames = True uperm = "games" elif unlock_type in ("inlinebots", "inline"): uinlinebots = True uperm = "inline bots" elif unlock_type == "webprev": uwebprev = True uperm = "web page previews" elif unlock_type == "polls": upolls = True uperm = "polls" elif unlock_type == "info": uinfo = True uperm = "info" elif unlock_type == "invite": uinvite = True uperm = "invite" elif unlock_type == "pin": upin = True uperm = "pin" else: await m.reply_text(tlang(m, "locks.invalid_lock")) return try: LOGGER.info( f"{m.from_user.id} unlocked selected permissions in {m.chat.id}") await c.set_chat_permissions( chat_id, ChatPermissions( can_send_messages=umsg, can_send_media_messages=umedia, can_send_stickers=ustickers, can_send_animations=uanimations, can_send_games=ugames, can_use_inline_bots=uinlinebots, can_add_web_page_previews=uwebprev, can_send_polls=upolls, can_change_info=uinfo, can_invite_users=uinvite, can_pin_messages=upin, ), ) await prevent_approved(m) # Don't lock permissions for approved users! await m.reply_text( "🔓 " + (tlang(m, "locks.unlocked_perm").format(uperm=uperm)), ) except ChatAdminRequired: await m.reply_text(tlang(m, "general.no_perm_admin")) return
async def my_info(c: Alita, m: Message): try: user_id, name, user_name = await extract_user(c, m) except PeerIdInvalid: await m.reply_text(tlang(m, "utils.user_info.peer_id_error")) return except ValueError as ef: if "Peer id invalid" in str(ef): await m.reply_text(tlang(m, "utils.user_info.id_not_found")) return try: user = Users.get_user_info(int(user_id)) name = user["name"] user_name = user["username"] user_id = user["_id"] except KeyError: LOGGER.warning(f"Calling api to fetch info about user {user_id}") user = await c.get_users(user_id) name = (escape(user["first_name"] + " " + user["last_name"]) if user["last_name"] else user["first_name"]) user_name = user["username"] user_id = user["id"] except PeerIdInvalid: await m.reply_text(tlang(m, "utils.no_user_db")) return except (RPCError, Exception) as ef: await m.reply_text((tlang(m, "general.some_error")).format( SUPPORT_GROUP=SUPPORT_GROUP, ef=ef, ), ) return gbanned, reason_gban = gban_db.get_gban(user_id) LOGGER.info(f"{m.from_user.id} used info cmd for {user_id} in {m.chat.id}") text = (tlang(m, "utils.user_info.info_text.main")).format( user_id=user_id, user_name=name, ) if user_name: text += (tlang(m, "utils.user_info.info_text.username")).format( username=user_name, ) text += (tlang(m, "utils.user_info.info_text.perma_link")).format( perma_link=(await mention_html("Click Here", user_id)), ) if gbanned: text += f"\nThis user is Globally banned beacuse: {reason_gban}\n" if user_id == OWNER_ID: text += tlang(m, "utils.user_info.support_user.owner") elif user_id in DEV_USERS: text += tlang(m, "utils.user_info.support_user.dev") elif user_id in SUDO_USERS: text += tlang(m, "utils.user_info.support_user.sudo") elif user_id in WHITELIST_USERS: text += tlang(m, "utils.user_info.support_user.whitelist") await m.reply_text(text, parse_mode="html", disable_web_page_preview=True) return
async def demote_usr(c: Alita, m: Message): from alita import BOT_ID global ADMIN_CACHE if len(m.text.split()) == 1 and not m.reply_to_message: await m.reply_text(tlang(m, "admin.demote.no_target")) return user_id, user_first_name, _ = await extract_user(c, m) if user_id == BOT_ID: await m.reply_text("Get an admin to demote me!") return # If user not alreay admin try: admin_list = {i[0] for i in ADMIN_CACHE[m.chat.id]} except KeyError: admin_list = { i[0] for i in (await admin_cache_reload(m, "demote_cache_update")) } if user_id not in admin_list: await m.reply_text( "This user is not an admin, how am I supposed to re-demote them?", ) return try: await m.chat.promote_member( user_id=user_id, can_change_info=False, can_delete_messages=False, can_restrict_members=False, can_invite_users=False, can_pin_messages=False, can_manage_voice_chats=False, ) LOGGER.info(f"{m.from_user.id} demoted {user_id} in {m.chat.id}") # ----- Remove admin from cache ----- try: admin_list = ADMIN_CACHE[m.chat.id] user = next(user for user in admin_list if user[0] == user_id) admin_list.remove(user) ADMIN_CACHE[m.chat.id] = admin_list except (KeyError, StopIteration): await admin_cache_reload(m, "demote_key_stopiter_error") await m.reply_text( (tlang(m, "admin.demote.demoted_user")).format( demoter=(await mention_html(m.from_user.first_name, m.from_user.id)), demoted=(await mention_html(user_first_name, user_id)), chat_title=m.chat.title, ), ) except ChatAdminRequired: await m.reply_text(tlang(m, "admin.not_admin")) except RightForbidden: await m.reply_text(tlang(m, "admin.demote.bot_no_right")) except UserAdminInvalid: await m.reply_text(tlang(m, "admin.user_admin_invalid")) except RPCError as ef: await m.reply_text( (tlang(m, "general.some_error")).format( SUPPORT_GROUP=SUPPORT_GROUP, ef=ef, ), ) LOGGER.error(ef) LOGGER.error(format_exc()) return
# This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from pymongo import MongoClient from alita import DB_NAME, DB_URI, LOGGER # Client to connect to mongodb mongodb_client = MongoClient(DB_URI) if mongodb_client: LOGGER.info("Established connection to MongoDB!") db = mongodb_client[DB_NAME] if db: LOGGER.info(f"Connected to '{DB_NAME}' database") class MongoDB: """Class for interacting with Bot database.""" def __init__(self, collection) -> None: self.collection = db[collection] # Insert one entry into collection def insert_one(self, document): result = self.collection.insert_one(document) return repr(result.inserted_id)
def __connect_first(): _ = MongoDB("test") LOGGER.info("Initialized Database!\n")
def __pre_req_chats(): start = time() LOGGER.info("Starting Chats Database Repair...") collection = MongoDB(Chats.db_name) Chats.repair_db(collection) LOGGER.info(f"Done in {round((time() - start), 3)}s!")
async def report_watcher(c: Alita, m: Message): if m.chat.type != "supergroup": return if not m.from_user: return me = await c.get_me() db = Reporting(m.chat.id) if (m.chat and m.reply_to_message) and (db.get_settings()): reported_msg_id = m.reply_to_message.message_id reported_user = m.reply_to_message.from_user chat_name = m.chat.title or m.chat.username admin_list = await c.get_chat_members(m.chat.id, filter="administrators") if reported_user.id == me.id: await m.reply_text("Nice try.") return if reported_user.id in SUPPORT_STAFF: await m.reply_text("Uh? You reporting my support team?") return if m.chat.username: msg = ( f"<b>⚠️ Report: </b>{m.chat.title}\n" f"<b> • Report by:</b> {(await mention_html(m.from_user.first_name, m.from_user.id))} (<code>{m.from_user.id}</code>)\n" f"<b> • Reported user:</b> {(await mention_html(reported_user.first_name, reported_user.id))} (<code>{reported_user.id}</code>)\n" ) else: msg = f"{(await mention_html(m.from_user.first_name, m.from_user.id))} is calling for admins in '{chat_name}'!\n" link_chat_id = str(m.chat.id).replace("-100", "") link = f"https://t.me/c/{link_chat_id}/{reported_msg_id}" # message link reply_markup = ikb( [ [("➡ Message", link, "url")], [ ( "⚠ Kick", f"report_{m.chat.id}=kick={reported_user.id}={reported_msg_id}", ), ( "⛔️ Ban", f"report_{m.chat.id}=ban={reported_user.id}={reported_msg_id}", ), ], [ ( "❎ Delete Message", f"report_{m.chat.id}=del={reported_user.id}={reported_msg_id}", ), ], ], ) LOGGER.info( f"{m.from_user.id} reported msgid-{m.reply_to_message.message_id} to admins in {m.chat.id}", ) await m.reply_text( ( f"{(await mention_html(m.from_user.first_name, m.from_user.id))} " "reported the message to the admins." ), quote=True, ) for admin in admin_list: if ( admin.user.is_bot or admin.user.is_deleted ): # can't message bots or deleted accounts continue if Reporting(admin.user.id).get_settings(): try: await c.send_message( admin.user.id, msg, reply_markup=reply_markup, disable_web_page_preview=True, ) try: await m.reply_to_message.forward(admin.user.id) if len(m.text.split()) > 1: await m.forward(admin.user.id) except Exception: pass except Exception: pass except RPCError as ef: LOGGER.error(ef) LOGGER.error(format_exc()) return ""
async def start(self): """Start the bot.""" await super().start() meh = await get_self(self) # Get bot info from pyrogram client LOGGER.info("Starting bot...") startmsg = await self.send_message(MESSAGE_DUMP, "<i>Starting Bot...</i>") # Load Languages lang_status = len(lang_dict) >= 1 LOGGER.info(f"Loading Languages: {lang_status}\n") # Show in Log that bot has started LOGGER.info( f"Pyrogram v{__version__} (Layer - {layer}) started on {meh.username}", ) LOGGER.info(f"Python Version: {python_version()}\n") # Get cmds and keys cmd_list = await load_cmds(await all_plugins()) LOGGER.info(f"Plugins Loaded: {cmd_list}") # Send a message to MESSAGE_DUMP telling that the # bot has started and has loaded all plugins! await startmsg.edit_text(( f"<b><i>@{meh.username} started on Pyrogram v{__version__} (Layer - {layer})</i></b>\n" f"\n<b>Python:</b> <u>{python_version()}</u>\n" "\n<b>Loaded Plugins:</b>\n" f"<i>{cmd_list}</i>\n"), ) LOGGER.info("Bot Started Successfully!\n")
async def dmute_usr(c: Alita, m: Message): if len(m.text.split()) == 1 and not m.reply_to_message: await m.reply_text("Я не могу никого замьютить!") return if not m.reply_to_message: return await m.reply_text( "No replied message and user to delete and mute!") reason = None if m.reply_to_message: if len(m.text.split()) >= 2: reason = m.text.split(None, 1)[1] else: if len(m.text.split()) >= 3: reason = m.text.split(None, 2)[2] user_id = m.reply_to_message.from_user.id user_first_name = m.reply_to_message.from_user.first_name if not user_id: await m.reply_text("Cannot find user to mute") return if user_id == Config.BOT_ID: await m.reply_text("Huh, why would I mute myself?") return if user_id in SUPPORT_STAFF: LOGGER.info( f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", ) await m.reply_text(tlang(m, "admin.support_cannot_restrict")) return try: admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]} except KeyError: admins_group = await admin_cache_reload(m, "mute") if user_id in admins_group: await m.reply_text(tlang(m, "admin.mute.admin_cannot_mute")) return try: await m.chat.restrict_member( user_id, ChatPermissions(), ) LOGGER.info(f"{m.from_user.id} dmuted {user_id} in {m.chat.id}") await m.reply_to_message.delete() txt = (tlang(m, "admin.mute.muted_user")).format( admin=(await mention_html(m.from_user.first_name, m.from_user.id)), muted=(await mention_html(user_first_name, user_id)), ) if reason: txt += f"\n<b>Reason</b>: {reason}" keyboard = InlineKeyboardMarkup([ [ InlineKeyboardButton( "Unmute", callback_data=f"unmute_={user_id}", ), ], ], ) await c.send_message(m.chat.id, txt, reply_markup=keyboard) except ChatAdminRequired: await m.reply_text(tlang(m, "admin.not_admin")) except RightForbidden: await m.reply_text(tlang(m, "admin.mute.bot_no_right")) except UserNotParticipant: await m.reply_text( "How can I mute a user who is not a part of this chat?") except RPCError as ef: await m.reply_text((tlang(m, "general.some_error")).format( SUPPORT_GROUP=SUPPORT_GROUP, ef=ef, ), ) LOGGER.error(ef) return
async def tmute_usr(c: Alita, m: Message): if len(m.text.split()) == 1 and not m.reply_to_message: await m.reply_text("Я не могу никого замьютить!") return try: user_id, user_first_name, _ = await extract_user(c, m) except Exception: return if not user_id: await m.reply_text("Cannot find user to mute !") return if user_id == Config.BOT_ID: await m.reply_text("Huh, why would I mute myself?") return if user_id in SUPPORT_STAFF: LOGGER.info( f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}", ) await m.reply_text(tlang(m, "admin.support_cannot_restrict")) return try: admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]} except KeyError: admins_group = await admin_cache_reload(m, "mute") if user_id in admins_group: await m.reply_text(tlang(m, "admin.mute.admin_cannot_mute")) return r_id = m.reply_to_message.message_id if m.reply_to_message else m.message_id if m.reply_to_message and len(m.text.split()) >= 2: reason = m.text.split(None, 2)[1] elif not m.reply_to_message and len(m.text.split()) >= 3: reason = m.text.split(None, 2)[2] else: await m.reply_text("Read /help !!") return if not reason: await m.reply_text( "You haven't specified a time to mute this user for!") return split_reason = reason.split(None, 1) time_val = split_reason[0].lower() reason = split_reason[1] if len(split_reason) > 1 else "" mutetime = await extract_time(m, time_val) if not mutetime: return try: await m.chat.restrict_member( user_id, ChatPermissions(), mutetime, ) LOGGER.info(f"{m.from_user.id} tmuted {user_id} in {m.chat.id}") txt = (tlang(m, "admin.mute.muted_user")).format( admin=(await mention_html(m.from_user.first_name, m.from_user.id)), muted=(await mention_html(user_first_name, user_id)), ) if reason: txt += f"\n<b>Reason</b>: {reason}" keyboard = InlineKeyboardMarkup([ [ InlineKeyboardButton( "Снять мут", callback_data=f"unmute_={user_id}", ), ], ], ) await m.reply_text(txt, reply_markup=keyboard, reply_to_message_id=r_id) except ChatAdminRequired: await m.reply_text(tlang(m, "admin.not_admin")) except RightForbidden: await m.reply_text(tlang(m, "admin.mute.bot_no_right")) except UserNotParticipant: await m.reply_text( "How can I mute a user who is not a part of this chat?") except RPCError as ef: await m.reply_text((tlang(m, "general.some_error")).format( SUPPORT_GROUP=SUPPORT_GROUP, ef=ef, ), ) LOGGER.error(ef) return
async def help_menu(_, m: Message): from alita import BOT_USERNAME if len(m.text.split()) >= 2: help_option = (m.text.split(None, 1)[1]).lower() help_msg, help_kb = await get_help_msg(m, help_option) if not help_msg: LOGGER.error( f"No help_msg found for help_option - {help_option}!!") return LOGGER.info( f"{m.from_user.id} fetched help for '{help_option}' text in {m.chat.id}", ) if m.chat.type == "private": await m.reply_text( help_msg, parse_mode="markdown", reply_markup=InlineKeyboardMarkup(help_kb), quote=True, disable_web_page_preview=True, ) else: await m.reply_text( (tlang(m, "start.public_help").format(help_option=help_option)), reply_markup=InlineKeyboardMarkup([ [ InlineKeyboardButton( "Help", url=f"t.me/{BOT_USERNAME}?start={help_option}", ), ], ], ), ) else: if m.chat.type == "private": keyboard = InlineKeyboardMarkup([ *(await gen_cmds_kb(m)), [ InlineKeyboardButton( f"« {(tlang(m, 'general.back_btn'))}", callback_data="start_back", ), ], ], ) msg = tlang(m, "general.commands_available") else: keyboard = InlineKeyboardMarkup([ [ InlineKeyboardButton( text="Help", url=f"t.me/{BOT_USERNAME}?start=help", ), ], ], ) msg = tlang(m, "start.pm_for_help") await m.reply_text( msg, reply_markup=keyboard, ) return
async def start(self): """Start the bot.""" await super().start() meh = await get_self(self) # Get bot info from pyrogram client LOGGER.info("Starting bot...") await self.send_message(MESSAGE_DUMP, "<i>Starting Bot...</i>") # Load Languages lang_status = len(lang_dict) >= 1 LOGGER.info(f"Loading Languages: {lang_status}") # Redis Content Setup! redis_client = await setup_redis() if redis_client: LOGGER.info("Connected to redis!") await self.get_admins() # Load admins in cache await set_key("BOT_ID", meh.id) await set_key("BOT_USERNAME", meh.username) await set_key("BOT_NAME", meh.first_name) await set_key("SUPPORT_STAFF", SUPPORT_STAFF) # Load SUPPORT_STAFF in cache else: LOGGER.error("Redis not connected!") # Redis Content Setup! # Show in Log that bot has started LOGGER.info( f"Pyrogram v{__version__}\n(Layer - {layer}) started on {BOT_USERNAME}\n" f"Python Version: {python_version()}", ) cmd_list = await load_cmds(await all_plugins()) redis_keys = ", ".join(await allkeys()) LOGGER.info(f"Plugins Loaded: {cmd_list}") LOGGER.info(f"Redis Keys Loaded: {redis_keys}") # Send a message to MESSAGE_DUMP telling that the # bot has started and has loaded all plugins! await self.send_message( MESSAGE_DUMP, ( f"<b><i>@{meh.username} started on Pyrogram v{__version__} (Layer - {layer})</i></b>\n" f"\n<b>Python:</b> <u>{python_version()}</u>\n" "\n<b>Loaded Plugins:</b>\n" f"<i>{cmd_list}</i>\n" "\n<b>Redis Keys Loaded:</b>\n" f"<i>{redis_keys}</i>" ), ) LOGGER.info("Bot Started Successfully!")
async def donate(_, m: Message): LOGGER.info(f"{m.from_user.id} fetched donation text in {m.chat.id}") await m.reply_text(tlang(m, "general.donate_owner")) return
async def fun_roll(_, m: Message): reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text await reply_text(choice(range(1, 7))) LOGGER.info(f"{m.from_user.id} roll in {m.chat.id}") return
async def promote_usr(c: Alita, m: Message): from alita import BOT_ID global ADMIN_CACHE if len(m.text.split()) == 1 and not m.reply_to_message: await m.reply_text(tlang(m, "admin.promote.no_target")) return user_id, user_first_name, user_name = await extract_user(c, m) if user_id == BOT_ID: await m.reply_text("Huh, how can I even promote myself?") return # If user is alreay admin try: admin_list = {i[0] for i in ADMIN_CACHE[m.chat.id]} except KeyError: admin_list = { i[0] for i in (await admin_cache_reload(m, "promote_cache_update")) } if user_id in admin_list: await m.reply_text( "This user is already an admin, how am I supposed to re-promote them?", ) return try: await m.chat.promote_member( user_id=user_id, can_change_info=False, can_delete_messages=True, can_restrict_members=True, can_invite_users=True, can_pin_messages=True, can_manage_voice_chats=False, ) LOGGER.info(f"{m.from_user.id} promoted {user_id} in {m.chat.id}") await m.reply_text( (tlang(m, "admin.promote.promoted_user")).format( promoter=(await mention_html(m.from_user.first_name, m.from_user.id)), promoted=(await mention_html(user_first_name, user_id)), chat_title=m.chat.title, ), ) if len(m.text.split()) == 3 and not m.reply_to_message: await c.set_administrator_title(m.chat.id, user_id, m.text.split()[2]) elif len(m.text.split()) == 2 and m.reply_to_message: await c.set_administrator_title(m.chat.id, user_id, m.text.split()[1]) # If user is approved, disapprove them as they willbe promoted and get even more rights if app_db.check_approve(m.chat.id, user_id): app_db.remove_approve(m.chat.id, user_id) # ----- Add admin to temp cache ----- try: inp1 = user_name if user_name else user_first_name admins_group = ADMIN_CACHE[m.chat.id] admins_group.append((user_id, inp1)) ADMIN_CACHE[m.chat.id] = admins_group except KeyError: await admin_cache_reload(m, "promote_key_error") except ChatAdminRequired: await m.reply_text(tlang(m, "admin.not_admin")) except RightForbidden: await m.reply_text(tlang(m, "admin.promote.bot_no_right")) except UserAdminInvalid: await m.reply_text(tlang(m, "admin.user_admin_invalid")) except RPCError as ef: await m.reply_text( (tlang(m, "general.some_error")).format( SUPPORT_GROUP=SUPPORT_GROUP, ef=ef, ), ) LOGGER.error(ef) LOGGER.error(format_exc()) return
async def fun_toss(_, m: Message): reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text await reply_text(choice(fun_strings.TOSS)) LOGGER.info(f"{m.from_user.id} tossed in {m.chat.id}") return
async def clearrules_callback(_, q: CallbackQuery): Rules(q.message.chat.id).clear_rules() await q.message.edit_text(tlang(q, "rules.cleared")) LOGGER.info(f"{q.from_user.id} cleared rules in {q.message.chat.id}") await q.answer("Rules for the chat have been cleared!", show_alert=True) return
async def fun_shrug(_, m: Message): reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text await reply_text(r"¯\_(ツ)_/¯") LOGGER.info(f"{m.from_user.id} shruged in {m.chat.id}") return
async def approve_user(c: Alita, m: Message): db = Approve(m.chat.id) chat_title = m.chat.title try: user_id, user_first_name, _ = await extract_user(c, m) except Exception: return if not user_id: await m.reply_text( "I don't know who you're talking about, you're going to need to specify a user!", ) return try: member = await m.chat.get_member(user_id) except UserNotParticipant: await m.reply_text("This user is not in this chat!") return except RPCError as ef: await m.reply_text( f"<b>Error</b>: <code>{ef}</code>\nReport it to @{SUPPORT_GROUP}", ) return if member.status in ("administrator", "creator"): await m.reply_text( "User is already admin - blacklists and locks already don't apply to them.", ) return already_approved = db.check_approve(user_id) if already_approved: await m.reply_text( f"{(await mention_html(user_first_name, user_id))} is already approved in {chat_title}", ) return db.add_approve(user_id, user_first_name) LOGGER.info(f"{user_id} approved by {m.from_user.id} in {m.chat.id}") # Allow all permissions await m.chat.restrict_member( user_id=user_id, permissions=ChatPermissions( can_send_messages=True, can_send_media_messages=True, can_send_stickers=True, can_send_animations=True, can_send_games=True, can_use_inline_bots=True, can_add_web_page_previews=True, can_send_polls=True, can_change_info=True, can_invite_users=True, can_pin_messages=True, ), ) await m.reply_text(( f"{(await mention_html(user_first_name, user_id))} has been approved in {chat_title}!\n" "They will now be ignored by blacklists, locks and antiflood!"), ) return
async def fun_decide(_, m: Message): reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text await reply_text(choice(fun_strings.DECIDE)) LOGGER.info(f"{m.from_user.id} decided in {m.chat.id}") return
async def lock_perm(c: Alita, m: Message): msg = "" media = "" stickers = "" animations = "" games = "" inlinebots = "" webprev = "" polls = "" info = "" invite = "" pin = "" perm = "" if len(m.text.split()) < 2: await m.reply_text("Please enter a permission to lock!") return lock_type = m.text.split(None, 1)[1] chat_id = m.chat.id if not lock_type: await m.reply_text(tlang(m, "locks.locks_perm_sp")) return get_perm = m.chat.permissions msg = get_perm.can_send_messages media = get_perm.can_send_media_messages stickers = get_perm.can_send_stickers animations = get_perm.can_send_animations games = get_perm.can_send_games inlinebots = get_perm.can_use_inline_bots webprev = get_perm.can_add_web_page_previews polls = get_perm.can_send_polls info = get_perm.can_change_info invite = get_perm.can_invite_users pin = get_perm.can_pin_messages if lock_type == "all": try: await c.set_chat_permissions(chat_id, ChatPermissions()) LOGGER.info( f"{m.from_user.id} locked all permissions in {m.chat.id}") await prevent_approved( m) # Don't lock permissions for approved users! await m.reply_text("🔒 " + (tlang(m, "locks.lock_all"))) except ChatAdminRequired: await m.reply_text(tlang(m, "general.no_perm_admin")) return if lock_type == "msg": msg = False perm = "messages" elif lock_type == "media": media = False perm = "audios, documents, photos, videos, video notes, voice notes" elif lock_type == "stickers": stickers = False perm = "stickers" elif lock_type == "animations": animations = False perm = "animations" elif lock_type == "games": games = False perm = "games" elif lock_type in ("inlinebots", "inline"): inlinebots = False perm = "inline bots" elif lock_type == "webprev": webprev = False perm = "web page previews" elif lock_type == "polls": polls = False perm = "polls" elif lock_type == "info": info = False perm = "info" elif lock_type == "invite": invite = False perm = "invite" elif lock_type == "pin": pin = False perm = "pin" else: await m.reply_text(tlang(m, "locks.invalid_lock")) return try: await c.set_chat_permissions( chat_id, ChatPermissions( can_send_messages=msg, can_send_media_messages=media, can_send_stickers=stickers, can_send_animations=animations, can_send_games=games, can_use_inline_bots=inlinebots, can_add_web_page_previews=webprev, can_send_polls=polls, can_change_info=info, can_invite_users=invite, can_pin_messages=pin, ), ) LOGGER.info( f"{m.from_user.id} locked selected permissions in {m.chat.id}") await prevent_approved(m) # Don't lock permissions for approved users! await m.reply_text( "🔒 " + (tlang(m, "locks.locked_perm").format(perm=perm)), ) except ChatAdminRequired: await m.reply_text(tlang(m, "general.no_perm_admin")) return
async def fun_table(_, m: Message): reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text await reply_text(choice(fun_strings.REACTIONS)) LOGGER.info(f"{m.from_user.id} reacted in {m.chat.id}") return
async def gban_count(_, m: Message): await m.reply_text( (tlang(m, "antispam.num_gbans")).format(count=(db.count_gbans())), ) LOGGER.info(f"{m.from_user.id} counting gbans in {m.chat.id}") return
async def fun_run(_, m: Message): await m.reply_text(choice(fun_strings.RUN_STRINGS)) LOGGER.info(f"{m.from_user.id} runed in {m.chat.id}") return
async def promote_usr(c: Alita, m: Message): from alita import BOT_ID global ADMIN_CACHE if len(m.text.split()) == 1 and not m.reply_to_message: await m.reply_text(tlang(m, "admin.promote.no_target")) return try: user_id, user_first_name, user_name = await extract_user(c, m) except Exception: return bot = await c.get_chat_member(m.chat.id, BOT_ID) if user_id == BOT_ID: await m.reply_text("Huh, how can I even promote myself?") return if not bot.can_promote_members: return await m.reply_text("I don't have enough permissions", ) # This should be here # If user is alreay admin try: admin_list = {i[0] for i in ADMIN_CACHE[m.chat.id]} except KeyError: admin_list = { i[0] for i in (await admin_cache_reload(m, "promote_cache_update")) } if user_id in admin_list: await m.reply_text( "This user is already an admin, how am I supposed to re-promote them?", ) return try: await m.chat.promote_member( user_id=user_id, can_change_info=bot.can_change_info, can_invite_users=bot.can_invite_users, can_delete_messages=bot.can_delete_messages, can_restrict_members=bot.can_restrict_members, can_pin_messages=bot.can_pin_messages, # can_promote_members=bot.can_promote_members, can_manage_chat=bot.can_manage_chat, can_manage_voice_chats=bot.can_manage_voice_chats, ) title = "" # Deafult title if len(m.text.split()) == 3 and not m.reply_to_message: title = m.text.split()[2] elif len(m.text.split()) == 2 and m.reply_to_message: title = m.text.split()[1] if len(title) > 16: title = title[0:16] # trim title to 16 characters try: await c.set_administrator_title(m.chat.id, user_id, title) except Exception as e: LOGGER.error(e) LOGGER.info( f"{m.from_user.id} promoted {user_id} in {m.chat.id} with title '{title}'", ) await m.reply_text((tlang(m, "admin.promote.promoted_user")).format( promoter=(await mention_html( m.from_user.first_name, m.from_user.id, )), promoted=(await mention_html(user_first_name, user_id)), chat_title=m.chat.title + f"\nTitle set to {title}" if title != "Admin" else "Default Admin!", ), ) # If user is approved, disapprove them as they willbe promoted and get even more rights if Approve(m.chat.id).check_approve(user_id): Approve(m.chat.id).remove_approve(user_id) # ----- Add admin to temp cache ----- try: inp1 = user_name or user_first_name admins_group = ADMIN_CACHE[m.chat.id] admins_group.append((user_id, inp1)) ADMIN_CACHE[m.chat.id] = admins_group except KeyError: await admin_cache_reload(m, "promote_key_error") except ChatAdminRequired: await m.reply_text(tlang(m, "admin.not_admin")) except RightForbidden: await m.reply_text(tlang(m, "admin.promote.bot_no_right")) except UserAdminInvalid: await m.reply_text(tlang(m, "admin.user_admin_invalid")) except RPCError as ef: await m.reply_text((tlang(m, "general.some_error")).format( SUPPORT_GROUP=SUPPORT_GROUP, ef=ef, ), ) except Exception as e: await m.reply_text((tlang(m, "general.some_error")).format( SUPPORT_GROUP=SUPPORT_GROUP, ef=e, ), ) LOGGER.error(e) LOGGER.error(format_exc()) return
async def get_private_note(c: Alita, m: Message, help_option: str): """Get the note in pm of user, with parsing enabled.""" from alita import BOT_USERNAME help_lst = help_option.split("_") if len(help_lst) == 2: chat_id = int(help_lst[1]) all_notes = notes_db.get_all_notes(chat_id) chat_title = Chats.get_chat_info(chat_id)["chat_name"] rply = f"Notes in {chat_title}:\n\n" note_list = [ f"- [{note[0]}](https://t.me/{BOT_USERNAME}?start=note_{chat_id}_{note[1]})" for note in all_notes ] rply = "\n".join(note_list) rply += "You can retrieve these notes by tapping on the notename." await m.reply_text(rply, disable_web_page_preview=True, quote=True) return if len(help_lst) != 3: return note_hash = help_option.split("_")[2] getnotes = notes_db.get_note_by_hash(note_hash) if not getnotes: await m.reply_text("Note does not exist", quote=True) return msgtype = getnotes["msgtype"] if not msgtype: await m.reply_text( "<b>Error:</b> Cannot find a type for this note!!", quote=True, ) return try: # support for random notes texts splitter = "%%%" note_reply = getnotes["note_value"].split(splitter) note_reply = choice(note_reply) except KeyError: note_reply = "" parse_words = [ "first", "last", "fullname", "username", "id", "chatname", "mention", ] text = await escape_mentions_using_curly_brackets(m, note_reply, parse_words) if msgtype == Types.TEXT: teks, button = await parse_button(text) button = await build_keyboard(button) button = ikb(button) if button else None if button: try: await m.reply_text( teks, reply_markup=button, disable_web_page_preview=True, quote=True, ) return except RPCError as ef: await m.reply_text( "An error has occured! Cannot parse note.", quote=True, ) LOGGER.error(ef) LOGGER.error(format_exc()) return else: await m.reply_text(teks, quote=True, disable_web_page_preview=True) return elif msgtype in ( Types.STICKER, Types.VIDEO_NOTE, Types.CONTACT, Types.ANIMATED_STICKER, ): await (await send_cmd(c, msgtype))(m.chat.id, getnotes["fileid"]) else: if getnotes["note_value"]: teks, button = await parse_button(getnotes["note_value"]) button = await build_keyboard(button) button = ikb(button) if button else None else: teks = "" button = None if button: try: await (await send_cmd(c, msgtype))( m.chat.id, getnotes["fileid"], caption=teks, reply_markup=button, ) return except RPCError as ef: await m.reply_text( teks, quote=True, reply_markup=button, disable_web_page_preview=True, ) LOGGER.error(ef) LOGGER.error(format_exc()) return else: await (await send_cmd(c, msgtype))( m.chat.id, getnotes["fileid"], caption=teks, ) LOGGER.info( f"{m.from_user.id} fetched privatenote {note_hash} (type - {getnotes}) in {m.chat.id}", ) return