def ban(bot: Bot, update: Update, args: List[str]) -> str: chat = update.effective_chat # type: Optional[Chat] user = update.effective_user # type: Optional[User] message = update.effective_message # type: Optional[Message] user_id, reason = extract_user_and_text(message, args) if not user_id: message.reply_text( tld(chat.id, "You don't seem to be referring to a user.")) return "" try: member = chat.get_member(user_id) except BadRequest as excp: if excp.message == "User not found": message.reply_text(tld(chat.id, "I can't seem to find this user")) return "" else: raise if is_user_ban_protected(chat, user_id, member): message.reply_text(tld(chat.id, "I really wish I could ban admins...")) return "" if user_id == bot.id: update.effective_message.reply_text( tld(chat.id, "I'm not gonna BAN myself, are you crazy?")) return "" log = "<b>{}:</b>" \ "\n#BANNED" \ "\n<b>Admin:</b> {}" \ "\n<b>User:</b> {}".format(html.escape(chat.title), mention_html(user.id, user.first_name), mention_html(member.user.id, member.user.first_name)) if reason: log += "\n<b>Reason:</b> {}".format(reason) try: update.effective_chat.kick_member(user_id) bot.send_sticker(update.effective_chat.id, BAN_STICKER) # banhammer marie sticker message.reply_text(tld(chat.id, "Banned!")) return log except BadRequest as excp: if excp.message == "Reply message not found": # Do not reply message.reply_text('Banned!', quote=False) return log else: LOGGER.warning(update) LOGGER.exception("ERROR banning user %s in chat %s (%s) due to %s", user_id, chat.title, chat.id, excp.message) message.reply_text( tld(chat.id, "Well damn, I can't ban that user.")) return ""
def reply_filter(bot: Bot, update: Update): chat = update.effective_chat # type: Optional[Chat] message = update.effective_message # type: Optional[Message] to_match = extract_text(message) if not to_match: return chat_filters = sql.get_chat_triggers(chat.id) for keyword in chat_filters: pattern = r"( |^|[^\w])" + re.escape(keyword) + r"( |$|[^\w])" if re.search(pattern, to_match, flags=re.IGNORECASE): filt = sql.get_filter(chat.id, keyword) if filt.is_sticker: message.reply_sticker(filt.reply) elif filt.is_document: message.reply_document(filt.reply) elif filt.is_image: message.reply_photo(filt.reply) elif filt.is_audio: message.reply_audio(filt.reply) elif filt.is_voice: message.reply_voice(filt.reply) elif filt.is_video: message.reply_video(filt.reply) elif filt.has_markdown: buttons = sql.get_buttons(chat.id, filt.keyword) keyb = build_keyboard(buttons) keyboard = InlineKeyboardMarkup(keyb) try: message.reply_text(filt.reply, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True, reply_markup=keyboard) except BadRequest as excp: if excp.message == "Unsupported url protocol": message.reply_text(tld(chat.id, "You seem to be trying to use an unsupported url protocol. Telegram " "doesn't support buttons for some protocols, such as tg://. Please try " "again, or ask in @MarieSupport for help.")) elif excp.message == "Reply message not found": bot.send_message(chat.id, filt.reply, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True, reply_markup=keyboard) else: message.reply_text(tld(chat.id, "This note could not be sent, as it is incorrectly formatted. Ask in " "@MarieSupport if you can't figure out why!")) LOGGER.warning("Message %s could not be parsed", str(filt.reply)) LOGGER.exception("Could not parse filter %s in chat %s", str(filt.keyword), str(chat.id)) else: # LEGACY - all new filters will have has_markdown set to True. message.reply_text(filt.reply) break
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 sed(bot: Bot, update: Update): sed_result = separate_sed(update.effective_message.text) if sed_result and update.effective_message.reply_to_message: if update.effective_message.reply_to_message.text: to_fix = update.effective_message.reply_to_message.text elif update.effective_message.reply_to_message.caption: to_fix = update.effective_message.reply_to_message.caption else: return repl, repl_with, flags = sed_result if not repl: update.effective_message.reply_to_message.reply_text( "You're trying to replace... " "nothing with something?") return try: check = re.match(repl, to_fix, flags=re.IGNORECASE) if check and check.group(0).lower() == to_fix.lower(): update.effective_message.reply_to_message.reply_text( "Hey everyone, {} is trying to make " "me say stuff I don't wanna " "say!".format(update.effective_user.first_name)) return if 'i' in flags and 'g' in flags: text = re.sub(repl, repl_with, to_fix, flags=re.I).strip() elif 'i' in flags: text = re.sub(repl, repl_with, to_fix, count=1, flags=re.I).strip() elif 'g' in flags: text = re.sub(repl, repl_with, to_fix).strip() else: text = re.sub(repl, repl_with, to_fix, count=1).strip() except sre_constants.error: LOGGER.warning(update.effective_message.text) LOGGER.exception("SRE constant error") update.effective_message.reply_text( "Do you even sed? Apparently not.") return # empty string errors -_- if len(text) >= telegram.MAX_MESSAGE_LENGTH: update.effective_message.reply_text( "The result of the sed command was too long for \ telegram!") elif text: update.effective_message.reply_to_message.reply_text(text)
def broadcast(bot: Bot, update: Update): to_send = update.effective_message.text.split(None, 1) if len(to_send) >= 2: chats = sql.get_all_chats() or [] failed = 0 for chat in chats: try: bot.sendMessage(int(chat.chat_id), to_send[1]) sleep(0.1) except TelegramError: failed += 1 LOGGER.warning("Couldn't send broadcast to %s, group name %s", str(chat.chat_id), str(chat.chat_name)) update.effective_message.reply_text( "Broadcast complete. {} groups failed to receive the message, probably " "due to being kicked.".format(failed))
def send_log(bot: Bot, log_chat_id: str, orig_chat_id: str, result: str): try: bot.send_message(log_chat_id, result, parse_mode=ParseMode.HTML) except BadRequest as excp: if excp.message == "Chat not found": bot.send_message( orig_chat_id, "This log channel has been deleted - unsetting.") sql.stop_chat_logging(orig_chat_id) else: LOGGER.warning(excp.message) LOGGER.warning(result) LOGGER.exception("Could not parse") bot.send_message( log_chat_id, result + "\n\nFormatting has been disabled due to an unexpected error." )
def log_action(bot: Bot, update: Update, *args, **kwargs): result = func(bot, update, *args, **kwargs) chat = update.effective_chat # type: Optional[Chat] message = update.effective_message # type: Optional[Message] if result: if chat.type == chat.SUPERGROUP and chat.username: result += "\n<b>Link:</b> " \ "<a href=\"http://telegram.me/{}/{}\">click here</a>".format(chat.username, message.message_id) log_chat = sql.get_chat_log_channel(chat.id) if log_chat: send_log(bot, log_chat, chat.id, result) elif result == "": pass else: LOGGER.warning( "%s was set as loggable, but had no return statement.", func) return result
def get(bot, update, notename, show_none=True): chat_id = update.effective_chat.id note = sql.get_note(chat_id, notename) message = update.effective_message # type: Optional[Message] if note: # If not is replying to a message, reply to that message (unless its an error) if message.reply_to_message: reply_text = message.reply_to_message.reply_text else: reply_text = message.reply_text if note.is_reply: if MESSAGE_DUMP: try: bot.forward_message(chat_id=chat_id, from_chat_id=MESSAGE_DUMP, message_id=note.value) except BadRequest as excp: if excp.message == "Message to forward not found": message.reply_text( tld( chat_id, "This message seems to have been lost - I'll remove it " "from your notes list.")) sql.rm_note(chat_id, notename) else: raise else: try: bot.forward_message(chat_id=chat_id, from_chat_id=chat_id, message_id=note.value) except BadRequest as excp: if excp.message == "Message to forward not found": message.reply_text( tld( chat_id, "Looks like the original sender of this note has deleted " "their message - sorry! Get your bot admin to start using a " "message dump to avoid this. I'll remove this note from " "your saved notes.")) sql.rm_note(chat_id, notename) else: raise else: keyb = [] if note.has_buttons: buttons = sql.get_buttons(chat_id, notename) keyb = build_keyboard(buttons) keyboard = InlineKeyboardMarkup(keyb) try: reply_text(note.value, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True, reply_markup=keyboard) except BadRequest as excp: if excp.message == "Entity_mention_user_invalid": message.reply_text( tld( chat_id, "Looks like you tried to mention someone I've never seen before. If you really " "want to mention them, forward one of their messages to me, and I'll be able " "to tag them!")) elif FILE_MATCHER.match(note.value): message.reply_text( tld( chat_id, "This note was an incorrectly imported file from another bot - I can't use " "it. If you really need it, you'll have to save it again. In " "the meantime, I'll remove it from your notes list." )) sql.rm_note(chat_id, notename) else: message.reply_text( tld( chat_id, "This note could not be sent, as it is incorrectly formatted. Ask in " "@MarieSupport if you can't figure out why!")) LOGGER.exception("Could not parse message #%s in chat %s", notename, str(chat_id)) LOGGER.warning("Message was: %s", str(note.value)) return elif show_none: message.reply_text(tld(chat_id, "This note doesn't exist"))
def temp_ban(bot: Bot, update: Update, args: List[str]) -> str: chat = update.effective_chat # type: Optional[Chat] user = update.effective_user # type: Optional[User] message = update.effective_message # type: Optional[Message] user_id, reason = extract_user_and_text(message, args) if not user_id: message.reply_text( tld(chat.id, "You don't seem to be referring to a user.")) return "" try: member = chat.get_member(user_id) except BadRequest as excp: if excp.message == "User not found": message.reply_text(tld(chat.id, "I can't seem to find this user")) return "" else: raise if is_user_ban_protected(chat, user_id, member): message.reply_text(tld(chat.id, "I really wish I could ban admins...")) return "" if user_id == bot.id: update.effective_message.reply_text( tld(chat.id, "I'm not gonna BAN myself, are you crazy?")) return "" split_reason = reason.split(None, 1) if not reason: message.reply_text( tld(chat.id, "You haven't specified a time to ban this user for!")) return "" else: time_val = split_reason[0].lower() if len(split_reason) > 1: reason = split_reason[1] else: reason = "" if any(time_val.endswith(unit) for unit in ('m', 'h', 'd')): unit = time_val[-1] time_num = time_val[:-1] # type: str if not time_num.isdigit(): message.reply_text(tld(chat.id, "Invalid time amount specified.")) return "" if unit == 'm': bantime = int(time.time() + int(time_num) * 60) elif unit == 'h': bantime = int(time.time() + int(time_num) * 60 * 60) elif unit == 'd': bantime = int(time.time() + int(time_num) * 24 * 60 * 60) else: # how even...? return "" else: message.reply_text( tld(chat.id, "Invalid time type specified. Expected m,h, or d, got: {}"). format(time_val[-1])) return "" log = "<b>{}:</b>" \ "\n#TEMP BANNED" \ "\n<b>Admin:</b> {}" \ "\n<b>User:</b> {}" \ "\n<b>Time:</b> {}".format(html.escape(chat.title), mention_html(user.id, user.first_name), mention_html(member.user.id, member.user.first_name), time_val) if reason: log += "\n<b>Reason:</b> {}".format(reason) try: update.effective_chat.kick_member(user_id, until_date=bantime) bot.send_sticker(update.effective_chat.id, BAN_STICKER) # banhammer marie sticker message.reply_text( tld(chat.id, "Banned! User will be banned for {}.").format(time_val)) return log except BadRequest as excp: if excp.message == "Reply message not found": # Do not reply message.reply_text( tld(chat.id, "Banned!User will be banned for {}.").format(time_val), quote=False) return log else: LOGGER.warning(update) LOGGER.exception("ERROR banning user %s in chat %s (%s) due to %s", user_id, chat.title, chat.id, excp.message) message.reply_text( tld(chat.id, "Well damn, I can't ban that user.")) return ""
def rban(bot: Bot, update: Update, args: List[str]): message = update.effective_message if not args: message.reply_text( tld(chat.id, "You don't seem to be referring to a chat/user.")) return user_id, chat_id = extract_user_and_text(message, args) if not user_id: message.reply_text( tld(chat.id, "You don't seem to be referring to a user.")) return elif not chat_id: message.reply_text( tld(chat.id, "You don't seem to be referring to a chat.")) return try: chat = bot.get_chat(chat_id) except BadRequest as excp: if excp.message == "Chat not found": message.reply_text( tld( chat.id, "Chat not found! Make sure you entered a valid chat ID and I'm part of that chat." )) return else: raise if chat.type == 'private': message.reply_text( tld(chat.id, "I'm sorry, but that's a private chat!")) return if not is_bot_admin(chat, bot.id) and not chat.get_member( bot.id).can_restrict_members: message.reply_text( tld( chat.id, "I can't restrict people there! Make sure I'm admin and can ban users." )) return try: member = chat.get_member(user_id) except BadRequest as excp: if excp.message == "User not found": message.reply_text(tld(chat.id, "I can't seem to find this user")) return else: raise if is_user_ban_protected(chat, user_id, member): message.reply_text(tld(chat.id, "I really wish I could ban admins...")) return if user_id == bot.id: message.reply_text( tld(chat.id, "I'm not gonna BAN myself, are you crazy?")) return try: chat.kick_member(user_id) message.reply_text(tld(chat.id, "Banned!")) except BadRequest as excp: if excp.message == "Reply message not found": # Do not reply message.reply_text('Banned!', quote=False) elif excp.message == "User_not_participant": message.reply_text("This user is not a participant of the chat!") elif excp.message == "Group chat was deactivated": message.reply_text("This group chat was deactivated!") elif excp.message == "Need to be inviter of a user to kick it from a basic group": message.reply_text(excp.message) elif excp.message == "Only the creator of a basic group can kick group administrators": message.reply_text(excp.message) elif excp.message == "Peer_id_invalid": message.reply_text( "Could not ban user. Perhaps the group has been suspended by Telegram." ) else: LOGGER.warning(update) LOGGER.exception("ERROR banning user %s in chat %s (%s) due to %s", user_id, chat.title, chat.id, excp.message) message.reply_text("Well damn, I can't ban that user.")