def send_log(context: CallbackContext, log_chat_id: str, orig_chat_id: str, result: str): bot = context.bot try: bot.send_message( log_chat_id, result, parse_mode=ParseMode.HTML, disable_web_page_preview=True, ) except BadRequest as excp: if excp.message == "Chat not found": bot.send_message( orig_chat_id, "Este canal de registro ha sido eliminado - desarmando.", ) 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\nEl formateo se ha deshabilitado debido a un error inesperado.", )
def glog_action(update: Update, context: CallbackContext, *args, **kwargs): result = func(update, context, *args, **kwargs) chat = update.effective_chat message = update.effective_message if result: datetime_fmt = "%H:%M - %d-%m-%Y" result += "\n<b>Evento Registrado</b>: <code>{}</code>".format( datetime.utcnow().strftime(datetime_fmt)) if message.chat.type == chat.SUPERGROUP and message.chat.username: result += f'\n<b>Link:</b> <a href="https://t.me/{chat.username}/{message.message_id}">click acá</a>' log_chat = str(GLOBAL_LOGS) if log_chat: send_log(context, log_chat, chat.id, result) elif result == "" or not result: pass else: LOGGER.warning( "%s was set as loggable to gbanlogs, but had no return statement.", func, ) return result
def log_action( update: Update, context: CallbackContext, job_queue: JobQueue = None, *args, **kwargs, ): if not job_queue: result = func(update, context, *args, **kwargs) else: result = func(update, context, job_queue, *args, **kwargs) chat = update.effective_chat message = update.effective_message if result: datetime_fmt = "%H:%M - %d-%m-%Y" result += f"\n<b>Evento Registrado</b>: <code>{datetime.utcnow().strftime(datetime_fmt)}</code>" if message.chat.type == chat.SUPERGROUP and message.chat.username: result += f'\n<b>Link:</b> <a href="https://t.me/{chat.username}/{message.message_id}">Click acá</a>' log_chat = sql.get_chat_log_channel(chat.id) if log_chat: send_log(context, log_chat, chat.id, result) elif result == "" or not result: pass else: LOGGER.warning( "%s was set as loggable, but had no return statement.", func) return result
def get_exception(excp, filt, chat): if excp.message == "Protocolo de URL no admitido": return "Parece que intentas utilizar un protocolo de URL no compatible. Telegram no admite botones para algunos protocolos, como tg://. Por favor, inténtalo de nuevo" elif excp.message == "Reply message not found": return "noreply" else: 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)) return "Estos datos no se pudieron enviar porque están formateados incorrectamente."
def broadcast(update: Update, context: CallbackContext): to_send = update.effective_message.text.split(None, 1) if len(to_send) >= 2: to_group = False to_user = False if to_send[0] == "/broadcastgroups": to_group = True if to_send[0] == "/broadcastusers": to_user = True else: to_group = to_user = True chats = sql.get_all_chats() or [] users = get_all_users() failed = 0 failed_user = 0 if to_group: for chat in chats: try: context.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), ) if to_user: for user in users: try: context.bot.sendMessage(int(user.user_id), to_send[1]) sleep(0.1) except TelegramError: failed_user += 1 LOGGER.warning("Couldn't send broadcast to %s", str(user.user_id)) update.effective_message.reply_text( f"Transmisión completa. {failed} grupos no pudieron recibir el mensaje, probablemente debido a que fui expulsada. {failed_user} no pudieron recibir el mensaje, probablemente debido a que estaba bloqueada" )
def get(update, context, notename, show_none=True, no_format=False): bot = context.bot chat_id = update.effective_chat.id note = sql.get_note(chat_id, notename) message = update.effective_message # type: Optional[Message] if note: if MessageHandlerChecker.check_user(update.effective_user.id): return # If we're replying to a message, reply to that message (unless it's an error) if message.reply_to_message: reply_id = message.reply_to_message.message_id else: reply_id = message.message_id if note.is_reply: if JOIN_LOGGER: try: bot.forward_message(chat_id=chat_id, from_chat_id=JOIN_LOGGER, message_id=note.value) except BadRequest as excp: if excp.message == "Reply message not found": message.reply_text( "Parece que este mensaje se ha perdido; lo eliminaré " "de la lista de notas.") 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( "Parece que se ha eliminado el remitente original de esta nota " "su mensaje - ¡lo siento! Haga que su administrador de bot comience a usar un " "guardado de mensajes para evitar esto. Eliminaré esta nota de " "sus notas guardadas.") sql.rm_note(chat_id, notename) else: raise else: VALID_NOTE_FORMATTERS = [ "first", "last", "fullname", "username", "id", "chatname", "mention", ] valid_format = escape_invalid_curly_brackets( note.value, VALID_NOTE_FORMATTERS) if valid_format: text = valid_format.format( first=escape_markdown(message.from_user.first_name), last=escape_markdown(message.from_user.last_name or message.from_user.first_name), fullname=escape_markdown( " ".join([ message.from_user.first_name, message.from_user. last_name ] if message.from_user.last_name else [message.from_user.first_name])), username="******" + message.from_user.username if message.from_user.username else mention_markdown( message.from_user.id, message.from_user.first_name), mention=mention_markdown(message.from_user.id, message.from_user.first_name), chatname=escape_markdown( message.chat.title if message.chat.type != "private" else message.from_user.first_name), id=message.from_user.id, ) else: text = "" keyb = [] parseMode = ParseMode.MARKDOWN buttons = sql.get_buttons(chat_id, notename) if no_format: parseMode = None text += revert_buttons(buttons) else: keyb = build_keyboard(buttons) keyboard = InlineKeyboardMarkup(keyb) try: if note.msgtype in (sql.Types.BUTTON_TEXT, sql.Types.TEXT): bot.send_message( chat_id, text, reply_to_message_id=reply_id, parse_mode=parseMode, disable_web_page_preview=True, reply_markup=keyboard, ) else: ENUM_FUNC_MAP[note.msgtype]( chat_id, note.file, caption=text, reply_to_message_id=reply_id, parse_mode=parseMode, reply_markup=keyboard, ) except BadRequest as excp: if excp.message == "Entity_mention_user_invalid": message.reply_text( "Parece que trataste de mencionar a alguien a quien nunca había visto antes. Si tú realmente " "quieres mencionarlos, reenviarme uno de sus mensajes y podré " "etiquetarlo!") elif FILE_MATCHER.match(note.value): message.reply_text( "Esta nota era un archivo importado incorrectamente de otro bot; no puedo usar " "eso. Si realmente lo necesita, tendrá que guardarlo nuevamente. Mientras" "tanto, lo eliminaré de tu lista de notas.") sql.rm_note(chat_id, notename) else: message.reply_text( "Esta nota no se pudo enviar porque tiene un formato incorrecto. Entra a " f"@{SUPPORT_CHAT} si no puedes entender por qué!") 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("Esta nota no existe")
def reply_filter(update, context): chat = update.effective_chat # type: Optional[Chat] message = update.effective_message # type: Optional[Message] if not update.effective_user or update.effective_user.id == 777000: return 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.reply == "there is should be a new reply": buttons = sql.get_buttons(chat.id, filt.keyword) keyb = build_keyboard_parser(context.bot, chat.id, buttons) keyboard = InlineKeyboardMarkup(keyb) VALID_WELCOME_FORMATTERS = [ "first", "last", "fullname", "username", "id", "chatname", "mention", "user1", "user2", ] if filt.reply_text: valid_format = escape_invalid_curly_brackets( filt.reply_text, VALID_WELCOME_FORMATTERS) if valid_format: filtext = valid_format.format( first=escape(message.from_user.first_name), last=escape(message.from_user.last_name or message.from_user.first_name), fullname=" ".join( [ escape(message.from_user.first_name), escape(message.from_user.last_name), ] if message.from_user.last_name else [escape(message.from_user.first_name)]), username="******" + escape(message.from_user.username) if message.from_user.username else mention_html( message.from_user.id, message.from_user.first_name), mention=mention_html(message.from_user.id, message.from_user.first_name), chatname=escape(message.chat.title) if message.chat.type != "private" else escape( message.from_user.first_name), id=message.from_user.id, ) else: filtext = "" else: filtext = "" if filt.file_type in (sql.Types.BUTTON_TEXT, sql.Types.TEXT): try: context.bot.send_message( chat.id, markdown_to_html(filtext), reply_to_message_id=message.message_id, parse_mode=ParseMode.HTML, disable_web_page_preview=True, reply_markup=keyboard, ) except BadRequest as excp: error_catch = get_exception(excp, filt, chat) if error_catch == "noreply": try: context.bot.send_message( chat.id, markdown_to_html(filtext), parse_mode=ParseMode.HTML, disable_web_page_preview=True, reply_markup=keyboard, ) except BadRequest as excp: LOGGER.exception("Error in filters: " + excp.message) send_message( update.effective_message, get_exception(excp, filt, chat), ) else: try: send_message( update.effective_message, get_exception(excp, filt, chat), ) except BadRequest as excp: LOGGER.exception("Failed to send message: " + excp.message) pass else: if ENUM_FUNC_MAP[ filt.file_type] == dispatcher.bot.send_sticker: ENUM_FUNC_MAP[filt.file_type]( chat.id, filt.file_id, reply_to_message_id=message.message_id, reply_markup=keyboard, ) else: ENUM_FUNC_MAP[filt.file_type]( chat.id, filt.file_id, caption=markdown_to_html(filtext), reply_to_message_id=message.message_id, parse_mode=ParseMode.HTML, reply_markup=keyboard, ) break else: 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_parser(context.bot, chat.id, buttons) keyboard = InlineKeyboardMarkup(keyb) try: send_message( update.effective_message, filt.reply, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True, reply_markup=keyboard, ) except BadRequest as excp: if excp.message == "Protocolo de URL no admitido": try: send_message( update.effective_message, "Parece que intentas utilizar un protocolo de URL no compatible. Telegram " "no admite botones para algunos protocolos, como tg://. Por favor, inténtalo " f"de nuevo, o pregunta en {SUPPORT_CHAT} por ayuda.", ) except BadRequest as excp: LOGGER.exception("Error in filters: " + excp.message) pass elif excp.message == "Reply message not found": try: context.bot.send_message( chat.id, filt.reply, parse_mode=ParseMode.MARKDOWN, disable_web_page_preview=True, reply_markup=keyboard, ) except BadRequest as excp: LOGGER.exception("Error in filters: " + excp.message) pass else: try: send_message( update.effective_message, "Este mensaje no se pudo enviar porque tiene un formato incorrecto.", ) except BadRequest as excp: LOGGER.exception("Error in filters: " + excp.message) pass 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. try: send_message(update.effective_message, filt.reply) except BadRequest as excp: LOGGER.exception("Error in filters: " + excp.message) pass break
def ban(update: Update, context: CallbackContext) -> str: chat = update.effective_chat user = update.effective_user message = update.effective_message log_message = "" bot = context.bot args = context.args user_id, reason = extract_user_and_text(message, args) if not user_id: message.reply_text("Dudo que sea un usuario.") return log_message try: member = chat.get_member(user_id) except BadRequest as excp: if excp.message == "Usuario no encontrado": message.reply_text("Parece que no puedo encontrar a esta persona.") return log_message else: raise if user_id == bot.id: message.reply_text("Oh sí, banéame, noob!") return log_message if is_user_ban_protected(chat, user_id, member) and user not in DEV_USERS: if user_id == OWNER_ID: message.reply_text( "Tratando de ponerme en contra de mi creador, eh?") return log_message elif user_id in DEV_USERS: message.reply_text("¿Estás loco?") return log_message elif user_id in SUDO_USERS: message.reply_text( "Usaría toda la magia existente para hacerlo volar, pero no valdría la pena..." ) return log_message elif user_id in SUPPORT_USERS: message.reply_text( "Lo haría explotar pero es mi soporte ¿Qué hago si me quedo sin magia?" ) return log_message elif user_id in FROG_USERS: message.reply_text( "Lo haría explotar pero es inmune a las explosiones ¿De qué estará hecho?" ) return log_message elif user_id in WHITELIST_USERS: message.reply_text( "Lo haría explotar pero es inmune a las explosiones ¿De qué estará hecho?" ) return log_message else: message.reply_text("Este usuario es inmune, no puedo banearlo..") return log_message log = ( f"<b>{html.escape(chat.title)}:</b>\n" f"#Baneado\n" f"<b>Administrador:</b> {mention_html(user.id, user.first_name)}\n" f"<b>Usuario:</b> {mention_html(member.user.id, member.user.first_name)}" ) if reason: log += "\n<b>Razón:</b> {}".format(reason) try: chat.kick_member(user_id) # bot.send_sticker(chat.id, BAN_STICKER) # banhammer marie sticker bot.sendMessage( chat.id, f"{mention_html(member.user.id, member.user.first_name)} [<code>{member.user.id}</code>] Baneado.", parse_mode=ParseMode.HTML, ) return log except BadRequest as excp: if excp.message == "Mensaje de respuesta no funciona": # Do not reply message.reply_text("Baneado!", quote=False) return log else: LOGGER.warning(update) LOGGER.exception( "ERROR baneando al usuario %s en el chat %s (% s) debido a %s", user_id, chat.title, chat.id, excp.message, ) message.reply_text("Uhm ... eso no funcionó...") return log_message
def temp_ban(update: Update, context: CallbackContext) -> str: chat = update.effective_chat user = update.effective_user message = update.effective_message log_message = "" bot, args = context.bot, context.args user_id, reason = extract_user_and_text(message, args) if not user_id: message.reply_text("Dudo que sea un usuario.") return log_message try: member = chat.get_member(user_id) except BadRequest as excp: if excp.message == "Usuario no encontrado": message.reply_text("Parece que no puedo encontrar a este usuario.") return log_message else: raise if user_id == bot.id: message.reply_text("Yo no voy a BANEAR ¿¿Estás loco??") return log_message if is_user_ban_protected(chat, user_id, member): message.reply_text("No me apetece.") return log_message if not reason: message.reply_text( "No has especificado el tiempo para banear a este usuario!") return log_message split_reason = reason.split(None, 1) time_val = split_reason[0].lower() if len(split_reason) > 1: reason = split_reason[1] else: reason = "" bantime = extract_time(message, time_val) if not bantime: return log_message log = ( f"<b>{html.escape(chat.title)}:</b>\n" "#BaneoTemporal\n" f"<b>Administrador:</b> {mention_html(user.id, user.first_name)}\n" f"<b>Usuario:</b> {mention_html(member.user.id, member.user.first_name)}\n" f"<b>Tiempo:</b> {time_val}") if reason: log += "\n<b>Razón:</b> {}".format(reason) try: chat.kick_member(user_id, until_date=bantime) # bot.send_sticker(chat.id, BAN_STICKER) # banhammer marie sticker bot.sendMessage( chat.id, f"Baneado! {mention_html(member.user.id, member.user.first_name)} " f"será baneado por {time_val}.", parse_mode=ParseMode.HTML, ) return log except BadRequest as excp: if excp.message == "Mensaje de respuesta no encontrado": # Do not reply message.reply_text( f"Baneado! El usuario será baneado por {time_val}.", quote=False) return log else: LOGGER.warning(update) LOGGER.exception( "ERROR baneando al usuario %s en el chat %s (% s) debido a %s", user_id, chat.title, chat.id, excp.message, ) message.reply_text("No puedo banear a ese usuario.") return log_message
def temp_mute(update: Update, context: CallbackContext) -> str: bot, args = context.bot, context.args chat = update.effective_chat user = update.effective_user message = update.effective_message user_id, reason = extract_user_and_text(message, args) reply = check_user(user_id, bot, chat) if reply: message.reply_text(reply) return "" member = chat.get_member(user_id) if not reason: message.reply_text( "No has especificado un tiempo para silenciar a este usuario.!") return "" split_reason = reason.split(None, 1) time_val = split_reason[0].lower() if len(split_reason) > 1: reason = split_reason[1] else: reason = "" mutetime = extract_time(message, time_val) if not mutetime: return "" log = ( f"<b>{html.escape(chat.title)}:</b>\n" f"#SilenciadoTemporal\n" f"<b>Administrador:</b> {mention_html(user.id, user.first_name)}\n" f"<b>Usuario:</b> {mention_html(member.user.id, member.user.first_name)}\n" f"<b>Tiemppo:</b> {time_val}") if reason: log += f"\n<b>Razón:</b> {reason}" try: if member.can_send_messages is None or member.can_send_messages: chat_permissions = ChatPermissions(can_send_messages=False) bot.restrict_chat_member(chat.id, user_id, chat_permissions, until_date=mutetime) bot.sendMessage( chat.id, f"<b>{html.escape(member.user.first_name)}</b> silenciado por {time_val}!", parse_mode=ParseMode.HTML, ) return log else: message.reply_text("Este usuario ya está silenciado.") except BadRequest as excp: if excp.message == "Reply message not found": # Do not reply message.reply_text(f"Silenciado por {time_val}!", quote=False) return log else: LOGGER.warning(update) LOGGER.exception( "ERROR muting user %s in chat %s (%s) due to %s", user_id, chat.title, chat.id, excp.message, ) message.reply_text( "Bueno maldita sea, no puedo silenciar a ese usuario.") return ""
def send(update, message, keyboard, backup_message): chat = update.effective_chat cleanserv = sql.clean_service(chat.id) reply = update.message.message_id # Clean service welcome if cleanserv: try: dispatcher.bot.delete_message(chat.id, update.message.message_id) except BadRequest: pass reply = False try: msg = update.effective_message.reply_text( message, parse_mode=ParseMode.MARKDOWN, reply_markup=keyboard, reply_to_message_id=reply, ) except BadRequest as excp: if excp.message == "Reply message not found": msg = update.effective_message.reply_text( message, parse_mode=ParseMode.MARKDOWN, reply_markup=keyboard, quote=False, ) elif excp.message == "Button_url_invalid": msg = update.effective_message.reply_text( markdown_parser( backup_message + "\nNota: El mensaje actual tiene una URL no válida " "en uno de sus botones. Por favor actualice."), parse_mode=ParseMode.MARKDOWN, reply_to_message_id=reply, ) elif excp.message == "Unsupported url protocol": msg = update.effective_message.reply_text( markdown_parser( backup_message + "\nNota: el mensaje actual tiene botones que " "utilizan protocolos de URL que no son compatibles con " "Telegram. Por favor actualice."), parse_mode=ParseMode.MARKDOWN, reply_to_message_id=reply, ) elif excp.message == "Wrong url host": msg = update.effective_message.reply_text( markdown_parser( backup_message + "\nNota: el mensaje actual tiene algunas URL incorrectas. " "Por favor actualice."), parse_mode=ParseMode.MARKDOWN, reply_to_message_id=reply, ) LOGGER.warning(message) LOGGER.warning(keyboard) LOGGER.exception( "No se pudo analizar! obtuve errores de host de URL no válidas" ) else: msg = update.effective_message.reply_text( markdown_parser(backup_message + "\nNota: Se produjo un error al enviar el " "mensaje personalizado. Por favor actualice."), parse_mode=ParseMode.MARKDOWN, reply_to_message_id=reply, ) LOGGER.exception() return msg