def disapprove(update, context): message = update.effective_message chat_title = message.chat.title chat = update.effective_chat args = context.args user = update.effective_user user_id = extract_user(message, args) if not user_id: message.reply_text( "I don't know who you're talking about, you're going to need to specify a user!" ) return "" try: member = chat.get_member(user_id) except BadRequest: return "" if member.status == "administrator" or member.status == "creator": message.reply_text("This user is an admin, they can't be unapproved.") return "" if not sql.is_approved(message.chat_id, user_id): message.reply_text(f"{member.user['first_name']} isn't approved yet!") return "" sql.disapprove(message.chat_id, user_id) message.reply_text( f"{member.user['first_name']} is no longer approved in {chat_title}.") log_message = ( f"<b>{html.escape(chat.title)}:</b>\n" f"#UNAPPROVED\n" f"<b>Admin:</b> {mention_html(user.id, user.first_name)}\n" f"<b>User:</b> {mention_html(member.user.id, member.user.first_name)}") return log_message
def del_blacklist(update: Update, context: CallbackContext): chat = update.effective_chat user = update.effective_user message = update.effective_message to_match = extract_text(message) msg = update.effective_message if not to_match: return if is_approved(chat.id, user.id): return chat_filters = sql.get_chat_blacklist(chat.id) for trigger in chat_filters: pattern = r"( |^|[^\w])" + trigger + r"( |$|[^\w])" match = regex_searcher(pattern, to_match) if not match: # Skip to next item in blacklist continue if match: try: message.delete() except BadRequest as excp: if excp.message == "Message to delete not found": pass else: LOGGER.exception("Error while deleting blacklist message.") break
def reply_filter(update: Update, context: CallbackContext) -> str: chat: Optional[Chat] = update.effective_chat message: Optional[Message] = update.effective_message user = update.effective_user chat_warn_filters = sql.get_chat_warn_triggers(chat.id) to_match = extract_text(message) if not to_match: return "" if is_approved(chat.id, user.id): return for keyword in chat_warn_filters: pattern = r"( |^|[^\w])" + re.escape(keyword) + r"( |$|[^\w])" if re.search(pattern, to_match, flags=re.IGNORECASE): user: Optional[User] = update.effective_user warn_filter = sql.get_warn_filter(chat.id, keyword) return warn(user, chat, warn_filter.reply, message) return ""
def approval(update, context): message = update.effective_message chat = update.effective_chat args = context.args user_id = extract_user(message, args) member = chat.get_member(int(user_id)) if not user_id: message.reply_text( "I don't know who you're talking about, you're going to need to specify a user!" ) return "" if sql.is_approved(message.chat_id, user_id): message.reply_text( f"{member.user['first_name']} is an approved user. Locks, antiflood, and blocklists won't apply to them." ) else: message.reply_text( f"{member.user['first_name']} is not an approved user. They are affected by normal commands." )
def approve(update, context): message = update.effective_message chat_title = message.chat.title chat = update.effective_chat args = context.args user = update.effective_user user_id = extract_user(message, args) if not user_id: message.reply_text( "I don't know who you're talking about, you're going to need to specify a user!" ) return "" try: member = chat.get_member(user_id) except BadRequest: return "" if member.status == "administrator" or member.status == "creator": message.reply_text( "User is already admin - locks, blocklists, and antiflood already don't apply to them." ) return "" if sql.is_approved(message.chat_id, user_id): message.reply_text( f"[{member.user['first_name']}](tg://user?id={member.user['id']}) is already approved in {chat_title}", parse_mode=ParseMode.MARKDOWN, ) return "" sql.approve(message.chat_id, user_id) message.reply_text( f"[{member.user['first_name']}](tg://user?id={member.user['id']}) has been approved in {chat_title}! They will now be ignored by automated admin actions like locks, blocklists, and antiflood.", parse_mode=ParseMode.MARKDOWN, ) log_message = ( f"<b>{html.escape(chat.title)}:</b>\n" f"#APPROVED\n" f"<b>Admin:</b> {mention_html(user.id, user.first_name)}\n" f"<b>User:</b> {mention_html(member.user.id, member.user.first_name)}") return log_message
def del_lockables(update: Update, context: CallbackContext): bot = context.bot chat = update.effective_chat message = update.effective_message user = update.effective_user # filter() expects Update object when filters are merged, otherwise Message object chk = message if is_approved(chat.id, user.id): return for lockable, filter in LOCK_TYPES.items(): if lockable in ("gif", "url"): chk = update if (filter(update) and sql.is_locked(chat.id, lockable) and can_delete(chat, bot.id)): if lockable == "bots": new_members = update.effective_message.new_chat_members for new_mem in new_members: if new_mem.is_bot: if not is_bot_admin(chat, bot.id): message.reply_text( "I see a bot, and I've been told to stop them joining... " "but I'm not admin!") return chat.kick_member(new_mem.id) message.reply_text( "Only admins are allowed to add bots to this chat! Behave or I'll punch you." ) else: try: message.delete() except BadRequest as excp: if excp.message == "Message to delete not found": pass else: LOGGER.exception("ERROR in lockables") break
def check_flood(update, context) -> str: user = update.effective_user # type: Optional[User] chat = update.effective_chat # type: Optional[Chat] msg = update.effective_message # type: Optional[Message] if not user: # ignore channels return "" # ignore admins and whitelists if (is_user_admin(chat, user.id) or user.id in WHITELIST_USERS or user.id in TIGER_USERS): sql.update_flood(chat.id, None) return "" # ignore approved users if is_approved(chat.id, user.id): sql.update_flood(chat.id, None) return "" should_ban = sql.update_flood(chat.id, user.id) if not should_ban: return "" try: getmode, getvalue = sql.get_flood_setting(chat.id) if getmode == 1: chat.kick_member(user.id) execstrings = "Banned" tag = "BANNED" elif getmode == 2: chat.kick_member(user.id) chat.unban_member(user.id) execstrings = "Kicked" tag = "KICKED" elif getmode == 3: context.bot.restrict_chat_member( chat.id, user.id, permissions=ChatPermissions(can_send_messages=False)) execstrings = "Muted" tag = "MUTED" elif getmode == 4: bantime = extract_time(msg, getvalue) chat.kick_member(user.id, until_date=bantime) execstrings = "Banned for {}".format(getvalue) tag = "TBAN" elif getmode == 5: mutetime = extract_time(msg, getvalue) context.bot.restrict_chat_member( chat.id, user.id, until_date=mutetime, permissions=ChatPermissions(can_send_messages=False), ) execstrings = "Muted for {}".format(getvalue) tag = "TMUTE" send_message( update.effective_message, "Wonderful, I like to leave flooding to only yuiimembers but you, " "you were just a disappointment {}!".format(execstrings), ) return ("<b>{}:</b>" "\n#{}" "\n<b>User:</b> {}" "\nFlooded the group.".format( tag, html.escape(chat.title), mention_html(user.id, user.first_name))) except BadRequest: msg.reply_text( "I can't restrict people here, give me permissions first! Until then, I'll disable anti-flood." ) sql.set_flood(chat.id, 0) return ( "<b>{}:</b>" "\n#INFO" "\nDon't have enough permission to restrict users so automatically disabled anti-flood" .format(chat.title))