Beispiel #1
0
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
Beispiel #3
0
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?")
Beispiel #4
0
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)
Beispiel #5
0
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))
Beispiel #6
0
    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."
                )
Beispiel #7
0
        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
Beispiel #8
0
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"))
Beispiel #9
0
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 ""
Beispiel #10
0
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.")