async def setup_redis(): """Start redis client.""" global redis_client redis_client = await create_redis_pool( address=(REDIS_HOST, REDIS_PORT), db=REDIS_DB, password=REDIS_PASS, ) try: await redis_client.ping() return redis_client except BaseException as ef: LOGGER.error(f"Cannot connect to redis\nError: {ef}") return False
async def start(self): await super().start() me = await self.get_me() # Get bot info from pyrogram client LOGGER.info("Starting bot...") """Redis Content Setup!""" await self.get_admins() # Load admins in cache set_key("SUPPORT_STAFF", SUPPORT_STAFF) # Load SUPPORT_STAFF in cache set_key("BOT_ID", int(me.id)) # Save Bot ID in Redis! """Redis Content Setup!""" # Show in Log that bot has started LOGGER.info( f"Pyrogram v{__version__}\n(Layer - {layer}) started on @{me.username}" ) LOGGER.info(load_cmds(ALL_PLUGINS)) LOGGER.info(f"Redis Keys Loaded: {allkeys()}") # 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>Bot started on Pyrogram v{__version__} (Layer - {layer})</i></b>\n\n" "<b>Loaded Plugins:</b>\n" f"<i>{list(HELP_COMMANDS.keys())}</i>\n" "<b>Redis Keys Loaded:</b>\n" f"<i>{allkeys()}</i>" ), )
def __load_pins_chats(): global PINS_CACHE start = time() db = Pins() all_chats = db.load_chats_from_db() PINS_CACHE["antichannelpin"] = { i["_id"] for i in all_chats if i["antichannelpin"] } PINS_CACHE["cleanlinked"] = { i["_id"] for i in all_chats if i["cleanlinked"] } LOGGER.info(f"Loaded Pins Cache - {round((time()-start),3)}s")
async def owner_check(m: Message or CallbackQuery) -> bool: """Checks if user is owner or not.""" if isinstance(m, Message): user_id = m.from_user.id if isinstance(m, CallbackQuery): user_id = m.message.from_user.id m = m.message try: if user_id in SUDO_LEVEL: return True except Exception as ef: LOGGER.info(ef, m) LOGGER.error(format_exc()) user = await m.chat.get_member(user_id) if user.status != "creator": if user.status == "administrator": reply = "Stay in your limits, or lose adminship too." else: reply = "You ain't even admin, what are you trying to do?" try: await m.edit_text(reply) except Exception as ef: await m.reply_text(reply) LOGGER.error(ef) LOGGER.error(format_exc()) return False return True
def __ensure_in_db(self): chat_data = self.find_one({"_id": self.chat_id}) if not chat_data: new_data = new_data = { "_id": self.chat_id, "triggers": [], "action": "none", "reason": "Automated blacklisted word: {{}}", } self.insert_one(new_data) LOGGER.info( f"Initialized Blacklist Document for chat {self.chat_id}") return new_data return chat_data
async def clearallnotes_callback(_, q: CallbackQuery): user_id = q.data.split(".")[-2] name = q.data.split(".")[-1] user_status = (await q.message.chat.get_member(user_id)).status if user_status != "creator": await q.message.edit(( f"You're an admin {await mention_html(name, user_id)}, not owner!\n" "Stay in your limits!"), ) return db.rm_all_notes(q.message.chat.id) LOGGER.info(f"{user_id} removed all notes in {q.message.chat.id}") await q.message.delete() await q.answer("Cleared all notes!", show_alert=True) return
async def migrate_chat(old_chat, new_chat): LOGGER.info(f"Migrating from {old_chat} to {new_chat}...") userdb.migrate_chat(old_chat, new_chat) langdb.migrate_chat(old_chat, new_chat) ruledb.migrate_chat(old_chat, new_chat) bldb.migrate_chat(old_chat, new_chat) notedb.migrate_chat(old_chat, new_chat) flooddb.migrate_chat(old_chat, new_chat) approvedb.migrate_chat(old_chat, new_chat) reportdb.migrate_chat(old_chat, new_chat) notes_settings.migrate_chat(old_chat, new_chat) pins_db.migrate_chat(old_chat, new_chat) fldb.migrate_chat(old_chat, new_chat) LOGGER.info(f"Successfully migrated from {old_chat} to {new_chat}!")
async def bl_chats_watcher(c: Alita, m: Message): from alita import SUPPORT_GROUP await c.send_message( m.chat.id, ( "This is a blacklisted group!\n" f"For Support, Join @{SUPPORT_GROUP}\n" "Now, I'm outta here!" ), ) await c.leave_chat(m.chat.id) LOGGER.info(f"Joined and Left blacklisted chat {m.chat.id}") return
async def start(_, m: Message): if m.chat.type == "private": try: await m.reply_text( tlang(m, "start.private"), reply_markup=(await gen_start_kb(m)), reply_to_message_id=m.message_id, ) except UserIsBlocked: LOGGER.warning(f"Bot blocked by {m.from_user.id}") else: await m.reply_text(tlang(m, "start.group"), reply_to_message_id=m.message_id) return
async def id_info(c: Alita, m: Message): LOGGER.info(f"{m.from_user.id} used id cmd in {m.chat.id}") if m.chat.type == "supergroup" and not m.reply_to_message: await m.reply_text((tlang(m, "utils.id.group_id")).format(group_id=m.chat.id)) return if m.chat.type == "private" and not m.reply_to_message: await m.reply_text((tlang(m, "utils.id.my_id")).format(my_id=m.chat.id)) return user_id = (await extract_user(c, m))[0] if user_id: if m.reply_to_message and m.reply_to_message.forward_from: user1 = m.reply_to_m.from_user user2 = m.reply_to_m.forward_from await m.reply_text( (tlang(m, "utils.id.id_main")).format( orig_sender=(await mention_html(user2.first_name, user2.id)), orig_id=f"<code>{user2.id}</code>", fwd_sender=(await mention_html(user1.first_name, user1.id)), fwd_id=f"<code>{user1.id}</code>", ), parse_mode="HTML", ) else: try: user = await c.get_users(user_id) except PeerIdInvalid: await m.reply_text(tlang(m, "utils.no_user_db")) return await m.reply_text( f"{(await mention_html(user.first_name, user.id))}'s ID is <code>{user.id}</code>.", parse_mode="HTML", ) else: if m.chat.type == "private": await m.reply_text( (tlang(m, "utils.id.my_id")).format( my_id=f"<code>{m.chat.id}</code>", ), ) else: await m.reply_text( (tlang(m, "utils.id.group_id")).format( group_id=f"<code>{m.chat.id}</code>", ), ) return
async def disapprove_user(c: Alita, m: Message): chat_title = m.chat.title chat_id = m.chat.id user_id, user_first_name, _ = await extract_user(c, m) already_approved = db.check_approve(chat_id, user_id) 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: if already_approved: # If user is approved and not in chat, unapprove them. db.remove_approve(chat_id, user_id) LOGGER.info( f"{user_id} disapproved in {m.chat.id} as UserNotParticipant") await m.reply_text("This user is not in this chat, unapproved them.") 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("This user is an admin, they can't be disapproved.") return if not already_approved: await m.reply_text( f"{(await mention_html(user_first_name, user_id))} isn't approved yet!", ) return db.remove_approve(chat_id, user_id) LOGGER.info(f"{user_id} disapproved by {m.from_user.id} in {m.chat.id}") # Set permission same as of current user by fetching them from chat! await m.chat.restrict_member( user_id=user_id, permissions=m.chat.permissions, ) await m.reply_text( f"{(await mention_html(user_first_name, user_id))} is no longer approved in {chat_title}.", ) return
async def promote_usr(_, m: Message): user_id, user_first_name = await extract_user(m) 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, ) await m.reply_text( tlang(m, "admin.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=f"<b>{m.chat.title}</b>", ), ) # ----- Add admin to redis cache! ----- adminlist = (await get_key("ADMINDICT"))[ str(m.chat.id) ] # Load ADMINDICT from string u = m.chat.get_member(user_id) adminlist.append( [ u.user.id, f"@{u.user.username}" if u.user.username else u.user.first_name, ], ) ADMINDICT = await get_key("ADMINDICT") ADMINDICT[str(m.chat.id)] = adminlist await set_key("ADMINDICT", ADMINDICT) except ChatAdminRequired: await m.reply_text(tlang(m, "admin.not_admin")) except RightForbidden: await m.reply_text(tlang(m, "admin.bot_no_promote_right")) except RPCError as ef: await m.reply_text( tlang(m, "general.some_error").format( SUPPORT_GROUP=f"@{SUPPORT_GROUP}", ef=f"<code>{ef}</code>", ), ) LOGGER.error(ef) return
async def unpin_message(c: Alita, m: Message): res = await admin_check(c, m) if not res: return try: await m.chat.unpin_chat_message(m.chat.id) except errors.ChatAdminRequired: await m.reply_text(_("admin.notadmin")) except Exception as ef: await m.reply_text( _("admin.somerror").format(SUPPORT_GROUP=SUPPORT_GROUP, ef=ef)) LOGGER.error(ef) return
def load_caches(): # Load local cache dictionaries start = time() LOGGER.info("Starting to load Local Caches!") __load_all_langs() __load_chats_cache() __load_antispam_users() __load_users_cache() __load_filters_cache() __load_all_rules() __load_approve_cache() __load_pins_chats() __load_all_reporting_settings() __load_group_blacklist() LOGGER.info(f"Succefully loaded Local Caches in {round((time()-start),3)}s\n")
async def clear_note(_, m: Message): if len(m.text.split()) <= 1: await m.reply_text("What do you want to clear?") return note = m.text.split()[1] getnote = db.rm_note(m.chat.id, note) LOGGER.info(f"{m.from_user.id} cleared note ({note}) in {m.chat.id}") if not getnote: await m.reply_text("This note does not exist!") return await m.reply_text(f"Note '`{note}`' deleted!") return
def get_all_filters(self, chat_id: int): with INSERTION_LOCK: try: return [i["keyword"] for i in FILTER_CACHE[chat_id]] except KeyError: pass except Exception as ef: LOGGER.error(ef) LOGGER.error(format_exc()) curr = self.collection.find_all({"chat_id": chat_id}) if curr: filter_list = {i["keyword"] for i in curr} return list(filter_list) return []
async def pin_message(_, m: Message): pin_args = m.text.split(None, 1) if m.reply_to_message: try: disable_notification = True if len(pin_args) >= 2 and pin_args[1] in [ "alert", "notify", "loud" ]: disable_notification = False await m.reply_to_message.pin( disable_notification=disable_notification, ) LOGGER.info( f"{m.from_user.id} pinned msgid-{m.reply_to_message.message_id} in {m.chat.id}", ) if m.chat.username: # If chat has a username, use this format link_chat_id = m.chat.username message_link = ( f"https://t.me/{link_chat_id}/{m.reply_to_message.message_id}" ) elif (str(m.chat.id)).startswith("-100"): # If chat does not have a username, use this link_chat_id = (str(m.chat.id)).replace("-100", "") message_link = ( f"https://t.me/c/{link_chat_id}/{m.reply_to_message.message_id}" ) await m.reply_text( tlang(m, "pin.pinned_msg").format(message_link=message_link), disable_web_page_preview=True, ) except ChatAdminRequired: await m.reply_text(tlang(m, "admin.not_admin")) except RightForbidden: await m.reply_text(tlang(m, "pin.no_rights_pin")) except RPCError as ef: await m.reply_text((tlang(m, "general.some_error")).format( SUPPORT_GROUP=SUPPORT_GROUP, ef=ef, ), ) LOGGER.error(ef) else: await m.reply_text("Reply to a message to pin it!") 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=ikb(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=ikb( [[("Help", f"t.me/{BOT_USERNAME}?start={help_option}", "url")]], ), ) else: if m.chat.type == "private": keyboard = ikb( [ *(await gen_cmds_kb(m)), [(f"« {(tlang(m, 'general.back_btn'))}", "start_back")], ], ) msg = tlang(m, "general.commands_available") else: keyboard = ikb([[("Help", f"t.me/{BOT_USERNAME}?start=help", "url")]]) msg = tlang(m, "start.pm_for_help") await m.reply_text( msg, reply_markup=keyboard, ) return
async def set_rules(_, m: Message): chat_id = m.chat.id if m.reply_to_message and m.reply_to_message.text: rules = m.reply_to_message.text elif (not m.reply_to_message) and len(m.text.split()) >= 2: rules = m.text.split(None, 1)[1] if len(rules) > 4000: rules = rules[0:3949] # Split Rules if len > 4000 chars await m.reply_text("Rules truncated to 3950 characters!") db.set_rules(chat_id, rules) LOGGER.info(f"{m.from_user.id} set rules in {m.chat.id}") await m.reply_text(tlang(m, "rules.set_rules")) return
def __load_filters_cache(): global FILTER_CACHE start = time() db = Filters() all_filters = db.load_from_db() chat_ids = {i["chat_id"] for i in all_filters} for i in all_filters: del i["_id"] FILTER_CACHE = { chat: [filt for filt in all_filters if filt["chat_id"] == chat] for chat in chat_ids } LOGGER.info(f"Loaded Filters Cache - {round((time()-start),3)}s")
async def perma_pin(_, m: Message): if m.reply_to_message or len(m.text.split()) > 1: LOGGER.info(f"{m.from_user.id} used permampin in {m.chat.id}") if m.reply_to_message: text = m.reply_to_message.text elif len(m.text.split()) > 1: text = m.text.split(None, 1)[1] teks, button = await parse_button(text) button = await build_keyboard(button) button = ikb(button) if button else None z = await m.reply_text(teks, reply_markup=button) await z.pin() else: await m.reply_text("Reply to a message or enter text to pin it.") await m.delete() return
def snipe(bot: Bot, update: Update, args: List[str]): try: chat_id = str(args[0]) del args[0] except TypeError as excp: update.effective_message.reply_text( "Please give me a chat to echo to!") to_send = " ".join(args) if len(to_send) >= 2: try: bot.sendMessage(int(chat_id), str(to_send)) except TelegramError: LOGGER.warning("Couldn't send to group %s", str(chat_id)) update.effective_message.reply_text( "Couldn't send the message. Perhaps I'm not part of that group?" )
def repair_db(collection): all_data = collection.find_all() keys = { "triggers": [], "action": "none", "reason": "Automated blacklisted word: {{}}", } for data in all_data: for key, val in keys.items(): try: _ = data[key] except KeyError: LOGGER.warning( f"Repairing Blacklist Database - setting '{key}:{val}' for {data['_id']}", ) collection.update({"_id": data["_id"]}, {key: val})
async def sban_usr(c: Alita, m: Message): if len(m.text.split()) == 1 and not m.reply_to_message: await m.reply_text(tlang(m, "admin.ban.no_target")) await m.stop_propagation() try: user_id, _, _ = await extract_user(c, m) except Exception: return if not user_id: await m.reply_text("Cannot find user to ban") return if user_id == BOT_ID: await m.reply_text("Huh, why would I ban myself?") await m.stop_propagation() 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 sban {user_id} (SUPPORT_STAFF) in {m.chat.id}", ) await m.stop_propagation() try: admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]} except KeyError: admins_group = await admin_cache_reload(m, "ban") if user_id in admins_group: await m.reply_text(tlang(m, "admin.ban.admin_cannot_ban")) await m.stop_propagation() try: LOGGER.info(f"{m.from_user.id} sbanned {user_id} in {m.chat.id}") await m.chat.kick_member(user_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 PeerIdInvalid: await m.reply_text( "I have not seen this user yet...!\nMind forwarding one of their message so I can recognize them?", ) except UserAdminInvalid: await m.reply_text(tlang(m, "admin.user_admin_invalid")) except RightForbidden: await m.reply_text(tlang(m, tlang(m, "admin.ban.bot_no_right"))) 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 promote_usr(c: Alita, m: Message): res = await admin_check(c, m) if not res: return from_user = await m.chat.get_member(m.from_user.id) # If user does not have permission to promote other users, return if from_user.can_promote_members or from_user.status == "creator": user_id, user_first_name = await extract_user(c, m) 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, ) await m.reply_text( _("admin.promoted").format( promoter=mention_html(m.from_user.first_name, m.from_user.id), promoted=mention_html(user_first_name, user_id), chat_title=m.chat.title, )) # ----- Add admin to redis cache! ----- ADMINDICT = get_key("ADMINDICT") # Load ADMINDICT from string adminlist = [] async for i in m.chat.iter_members(filter="administrators"): adminlist.append(i.user.id) ADMINDICT[str(m.chat.id)] = adminlist set_key("ADMINDICT", ADMINDICT) except errors.ChatAdminRequired: await m.reply_text(_("admin.notadmin")) except Exception as ef: await m.reply_text(_("admin.useadmincache")) LOGGER.error(ef) return await m.reply_text(_("admin.nopromoteperm")) return
async def unban_usr(c: Alita, m: Message): if len(m.text.split()) == 1 and not m.reply_to_message: await m.reply_text(tlang(m, "admin.unban.no_target")) await m.stop_propagation() if m.reply_to_message and not m.reply_to_message.from_user: user_id, user_first_name = ( m.reply_to_message.sender_chat.id, m.reply_to_message.sender_chat.title, ) else: try: user_id, user_first_name, _ = await extract_user(c, m) except Exception: 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: reason = None try: await m.chat.unban_member(user_id) txt = (tlang(m, "admin.unban.unbanned_user")).format( admin=m.from_user.mention, unbanned=(await mention_html(user_first_name, user_id)), chat_title=m.chat.title, ) txt += f"\n<b>Reason</b>: {reason}" if reason else "" await m.reply_text(txt) except ChatAdminRequired: await m.reply_text(tlang(m, "admin.not_admin")) except RightForbidden: await m.reply_text(tlang(m, tlang(m, "admin.unban.bot_no_right"))) 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 get_rules(_, m: Message): db = Rules(m.chat.id) msg_id = m.reply_to_message.message_id if m.reply_to_message else m.message_id rules = db.get_rules() LOGGER.info(f"{m.from_user.id} fetched rules in {m.chat.id}") if m and not m.from_user: return if not rules: await m.reply_text( (tlang(m, "rules.no_rules")), quote=True, ) return priv_rules_status = db.get_privrules() if priv_rules_status: pm_kb = ikb([ [ ( "Rules", f"https://t.me/{Config.BOT_USERNAME}?start=rules_{m.chat.id}", "url", ), ], ], ) await m.reply_text( (tlang(m, "rules.pm_me")), quote=True, reply_markup=pm_kb, reply_to_message_id=msg_id, ) return formated = rules await m.reply_text( (tlang(m, "rules.get_rules")).format( chat=f"<b>{m.chat.title}</b>", rules=formated, ), disable_web_page_preview=True, reply_to_message_id=msg_id, ) return
async def leave_chat(c: Alita, m: Message): if len(m.text.split()) != 2: await m.reply_text("Supply a chat id which I should leave!", quoet=True) return chat_id = m.text.split(None, 1)[1] replymsg = await m.reply_text(f"Trying to leave chat {chat_id}...", quote=True) try: await c.leave_chat(chat_id) await replymsg.edit_text(f"Left <code>{chat_id}</code>.") except PeerIdInvalid: await replymsg.edit_text("Haven't seen this group in this session!") except RPCError as ef: LOGGER.error(ef) await replymsg.edit_text(f"Failed to leave chat!\nError: <code>{ef}</code>.") return
async def remove_warn(c: Alita, m: Message): if not len(m.command) > 1 and not m.reply_to_message: await m.reply_text( "I can't remove warns of nothing! Tell me user whose warn should be removed!", ) return user_id, user_first_name, _ = await extract_user(c, m) if user_id == Config.BOT_ID: await m.reply_text("Huh, why would I warn myself?") return if user_id in SUPPORT_STAFF: await m.reply_text("This user has no warns!") LOGGER.info( f"{m.from_user.id} trying to remove warns of {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, "rmwarn"))} if user_id in admins_group: await m.reply_text( "This user is admin in this chat, they don't have any warns!", ) return warn_db = Warns(m.chat.id) warns, _ = warn_db.get_warns(user_id) if not warns: await m.reply_text("This user has no warnings!") return _, num_warns = warn_db.remove_warn(user_id) await m.reply_text( ( f"{(await mention_html(user_first_name,user_id))} now has <b>{num_warns}</b> warnings!\n" "Their last warn was removed." ), ) return
def user_join_fed(bot: Bot, update: Update, args: List[str]): chat = update.effective_chat user = update.effective_user msg = update.effective_message fed_id = sql.get_fed_id(chat.id) if is_user_fed_owner(fed_id, user.id): user_id = extract_user(msg, args) if user_id: user = bot.get_chat(user_id) elif not msg.reply_to_message and not args: user = msg.from_user elif not msg.reply_to_message and ( not args or (len(args) >= 1 and not args[0].startswith("@") and not args[0].isdigit() and not msg.parse_entities([MessageEntity.TEXT_MENTION]))): msg.reply_text(tld(chat.id, "common_err_no_user")) return else: LOGGER.warning('error') getuser = sql.search_user_in_fed(fed_id, user_id) fed_id = sql.get_fed_id(chat.id) info = sql.get_fed_info(fed_id) get_owner = eval(info['fusers'])['owner'] get_owner = bot.get_chat(get_owner).id if user_id == get_owner: update.effective_message.reply_text( tld(chat.id, "feds_promote_owner")) return if getuser: update.effective_message.reply_text( tld(chat.id, "feds_promote_owner")) return if user_id == bot.id: update.effective_message.reply_text( tld(chat.id, "feds_promote_bot")) return res = sql.user_join_fed(fed_id, user_id) if res: update.effective_message.reply_text( tld(chat.id, "feds_promote_success")) else: update.effective_message.reply_text("") else: update.effective_message.reply_text(tld(chat.id, "feds_owner_only"))