Example #1
0
def enforce_gmute(update: Update, context: CallbackContext):
    # Not using @restrict handler to avoid spamming - just ignore if cant gmute.
    if sql.does_chat_gmute(update.effective_chat.id) and update.effective_chat.get_member(context.bot.id).can_restrict_members:
        user = update.effective_user  # type: Optional[User]
        chat = update.effective_chat  # type: Optional[Chat]
        msg = update.effective_message  # type: Optional[Message]
        gmute_alert = sql.get_gmute_alert(chat.id)
        new_members = update.effective_message.new_chat_members

        if user and not is_user_admin(chat, user.id):
            check_and_mute(update, context, user.id)
            
        if msg.text:
            if user and not is_user_admin(chat, user.id):
                check_and_mute(update, context, user.id)
                
                if gmute_alert:
                    gmute_notification(update, context, user.id,
                                  should_message=True)
                
        elif msg.new_chat_members:
            for mem in new_members:
                welcome_gmute(update, context, mem.id)
                if gmute_alert:
                    gmute_notification(update, context, mem.id,
                                  should_message=True)
                    
        elif new_members:
            for mem in new_members:
                welcome_gmute(update, context, mem.id)
                if gmute_alert:
                    gmute_notification(update, context, user.id,
                                  should_message=True)
Example #2
0
    def check_update(self, update: Update):
        if isinstance(update, Update) and update.effective_message:
            message = update.effective_message

            if message.text:
                sql_result = (sql.is_restr_locked(update.effective_chat.id,
                                                  'messages')
                              and not is_user_admin(update.effective_chat,
                                                    update.effective_user.id))
                text_list = message.text.split()
                if text_list[0].split("@")[0].lower() in self.command and len(
                        text_list[0].split("@")) > 1 and text_list[0].split(
                            "@")[1] == message.bot.username:
                    filter_result = self.filters(update)
                    if filter_result:
                        return text_list[1:], filter_result and not sql_result
                    else:
                        return False and not sql_result
                else:
                    if text_list[0].lower() not in self.command:
                        return None
                    filter_result = self.filters(update)
                    if filter_result:
                        return text_list[1:], filter_result and not sql_result
                    else:
                        return False and not sql_result
Example #3
0
def user_button(update: Update, context: CallbackContext):
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    query = update.callback_query  # type: Optional[CallbackQuery]
    match = re.match(r"user_join_\((.+?)\)", query.data)
    message = update.effective_message  # type: Optional[Message]
    db_checks = sql.set_human_checks(user.id, chat.id)
    join_user =  int(match.group(1))
    
    if join_user == user.id:
        query.answer(text="Yus! You're a human, Unmuted!")
        context.bot.restrict_chat_member(chat.id, user.id, USER_PERMISSIONS_UNMUTE)
        context.bot.deleteMessage(chat.id, message.message_id)
        db_checks
    
    
    member = chat.get_member(int(user.id))
    admin = update.effective_user
    id_join =  int(match.group(1))
    if member:
        if is_user_admin(chat, user.id, member=member):
            query.answer(text="User has been unmuted!")
            update.effective_message.edit_text(
                    "User has been unmuted by {}".format(admin.first_name))
            sql.set_human_checks(id_join, chat.id)
            context.bot.restrict_chat_member(chat.id, id_join, USER_PERMISSIONS_UNMUTE)
            time.sleep(60)
            context.bot.deleteMessage(chat.id, message.message_id)
        else:
            query.answer(text="You're not allowed to do this!")
    else:
        query.answer(text="You're not allowed to do this!")
Example #4
0
def button(update: Update, context: CallbackContext) -> str:
    query = update.callback_query  # type: Optional[CallbackQuery]
    user = update.effective_user  # type: Optional[User]
    match = re.match(r"rm_warn\((.+?)\)", query.data)
    if match:
        user_id = match.group(1)
        chat = update.effective_chat  # type: Optional[Chat]
        res = sql.remove_warn(user_id, chat.id)

        if not is_user_admin(chat, int(user.id)):
            query.answer(text="You need to be an admin to do this.")
            return ""

        if res:
            update.effective_message.edit_text("Warn removed by {}.".format(
                mention_html(user.id, user.first_name)),
                                               parse_mode=ParseMode.HTML)
            user_member = chat.get_member(user_id)
            return "<b>{}:</b>" \
                   "\n#UNWARN" \
                   "\n<b>• Admin:</b> {}" \
                   "\n<b>• User:</b> {}".format(html.escape(chat.title),
                                              mention_html(user.id, user.first_name),
                                              mention_html(user_member.user.id, user_member.user.first_name))
        else:
            update.effective_message.edit_text(
                "User {} has already has no warns.".format(
                    mention_html(user.id, user.first_name)),
                parse_mode=ParseMode.HTML)

    return ""
Example #5
0
def kickme(update: Update, context: CallbackContext):
    user_id = update.effective_message.from_user.id
    if is_user_admin(update.effective_chat, user_id):
        update.effective_message.reply_text(
            "I wish I could... but you're an admin.")
        return

    res = update.effective_chat.unban_member(
        user_id)  # unban on current user = kick
    if res:
        update.effective_message.reply_text("No problem.")
    else:
        update.effective_message.reply_text("Huh? I can't :/")
Example #6
0
def mute(update: Update, context: CallbackContext) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    message = update.effective_message  # type: Optional[Message]
    args = message.text.split(" ")

    user_id, reason = extract_user_and_text(message, args)
    if not user_id:
        message.reply_text(
            "You'll need to either give me a username to mute, or reply to someone to be muted."
        )
        return ""

    if user_id == context.bot.id:
        message.reply_text("I'm not muting myself!")
        return ""

    member = chat.get_member(int(user_id))

    if member:
        if is_user_admin(chat, user_id, member=member):
            message.reply_text("Afraid I can't stop an admin from talking!")

        elif member.can_send_messages is None or member.can_send_messages:
            log = "<b>{}:</b>" \
                   "\n#MUTE" \
                   "\n<b>• Admin:</b> {}" \
                   "\n<b>• User:</b> {}" \
                   "\n<b>• ID:</b> <code>{}</code>".format(html.escape(chat.title),
                                              mention_html(user.id, user.first_name),
                                              mention_html(member.user.id, member.user.first_name), user_id)
            reply = "Shh!\n{} is muted!".format(
                mention_html(member.user.id, member.user.first_name))
            if reason:
                log += "\n<b>• Reason:</b> {}".format(reason)
                reply += "\n<b>Reason:</b> <i>{}</i>".format(reason)
            context.bot.restrict_chat_member(chat.id, user_id,
                                             MUTE_PERMISSIONS)

            message.reply_text(reply, parse_mode=ParseMode.HTML)

            return log

        else:
            message.reply_text("This user is already muted!")
    else:
        message.reply_text("This user isn't in the chat!")

    return ""
Example #7
0
def start(update: Update, context: CallbackContext):
    args = update.effective_message.text.split(" ")
    if update.effective_chat.type == "private":
        if len(args) > 1:
            if args[1].lower() == "help":
                send_help(update.effective_chat.id, HELP_STRINGS)

            elif args[1].lower().startswith("stngs_"):
                match = re.match("stngs_(.*)", args[1].lower())
                try:
                    chat = dispatcher.bot.getChat(match.group(1))
                    if chat and is_user_admin(chat, update.effective_user.id):
                        send_settings(match.group(1), update.effective_user.id,
                                      False)
                    else:
                        send_settings(match.group(1), update.effective_user.id,
                                      True)
                except:
                    context.bot.send_message(update.effective_chat.id,
                                             "Add a chat id after stngs_",
                                             parse_mode=ParseMode.HTML)

            elif args[1][1:].isdigit() and "rules" in IMPORTED:
                IMPORTED["rules"].send_rules(update, args[1], from_pm=True)

        else:
            first_name = update.effective_user.first_name
            keyboard = [[
                InlineKeyboardButton(text="Add me to group",
                                     url="t.me/{}?startgroup=true".format(
                                         context.bot.username))
            ]]
            keyboard += [[
                InlineKeyboardButton(text="Help & Commands",
                                     callback_data="help_back")
            ]]

            update.effective_message.reply_text(
                PM_START_TEXT.format(escape_markdown(first_name),
                                     escape_markdown(context.bot.first_name),
                                     OWNER_ID),
                parse_mode=ParseMode.MARKDOWN,
                reply_markup=InlineKeyboardMarkup(keyboard))
    else:
        update.effective_message.reply_text(
            "Hey there, PM me if you have any questions on how to use me!")
Example #8
0
def nomedia(update: Update, context: CallbackContext) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    message = update.effective_message  # type: Optional[Message]
    args = message.text.split(" ")

    user_id = extract_user(message, args)
    if not user_id:
        message.reply_text(
            "You'll need to either give me a username to restrict, or reply to someone to be restricted."
        )
        return ""

    if user_id == context.bot.id:
        message.reply_text("I'm not restricting myself!")
        return ""

    member = chat.get_member(int(user_id))

    if member:
        if is_user_admin(chat, user_id, member=member):
            message.reply_text("Afraid I can't restrict admins!")

        elif member.can_send_messages is None or member.can_send_messages:
            context.bot.restrict_chat_member(chat.id, user_id,
                                             NOMEDIA_PERMISSIONS)

            reply = "{} is restricted from sending media!".format(
                mention_html(member.user.id, member.user.first_name))
            message.reply_text(reply, parse_mode=ParseMode.HTML)
            return "<b>{}:</b>" \
                   "\n#RESTRICTED" \
                   "\n<b>• Admin:</b> {}" \
                   "\n<b>• User:</b> {}" \
                   "\n<b>• ID:</b> <code>{}</code>".format(html.escape(chat.title),
                                              mention_html(user.id, user.first_name),
                                              mention_html(member.user.id, member.user.first_name), user_id)

        else:
            message.reply_text("This user is already restricted!")
    else:
        message.reply_text("This user isn't in the chat!")

    return ""
Example #9
0
        def check_update(self, update: Update):
            chat = update.effective_chat  # type: Optional[Chat]
            user = update.effective_user  # type: Optional[User]

            if super().check_update(update):
                # Should be safe since check_update passed.
                command = update.effective_message.text_html.split(
                    None, 1)[0][1:].split('@')[0]

                # disabled, admincmd, user admin
                if sql.is_command_disabled(chat.id, command.lower()):
                    return command in ADMIN_CMDS and is_user_admin(
                        chat, user.id)

                # not disabled
                else:
                    return True

            return False
Example #10
0
def banme(update: Update, context: CallbackContext):
    user_id = update.effective_message.from_user.id
    chat = update.effective_chat
    user = update.effective_user
    if is_user_admin(update.effective_chat, user_id):
        update.effective_message.reply_text(
            "I wish I could... but you're an admin.")
        return

    res = update.effective_chat.kick_member(user_id)
    if res:
        update.effective_message.reply_text("No problem, banned.")
        log = "<b>{}:</b>" \
              "\n#BANME" \
              "\n<b>User:</b> {}" \
              "\n<b>ID:</b> <code>{}</code>".format(html.escape(chat.title),
                                                    mention_html(user.id, user.first_name), user_id)
        return log

    else:
        update.effective_message.reply_text("Huh? I can't :/")
Example #11
0
def get_settings(update: Update, context: CallbackContext):
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    msg = update.effective_message  # type: Optional[Message]
    args = msg.text.split(None, 1)

    # ONLY send settings in PM
    if chat.type != chat.PRIVATE:
        if is_user_admin(chat, user.id):
            text = "Click here to get this chat's settings, as well as yours."
            msg.reply_text(text,
                           reply_markup=InlineKeyboardMarkup([[
                               InlineKeyboardButton(
                                   text="Settings",
                                   url="t.me/{}?start=stngs_{}".format(
                                       context.bot.username, chat.id))
                           ]]))
        else:
            text = "Click here to check your settings."

    else:
        send_settings(chat.id, user.id, True)
Example #12
0
def smute(update: Update, context: CallbackContext) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    message = update.effective_message  # type: Optional[Message]
    args = message.text.split(" ")

    update.effective_message.delete()
    user_id, reason = extract_user_and_text(message, args)
    if not user_id:
        return ""

    if user_id == context.bot.id:
        message.reply_text("Really?! You're not supposed silent mute me!")
        return ""

    member = chat.get_member(int(user_id))

    if member:
        if is_user_admin(chat, user_id, member=member):
            return ""

        elif member.can_send_messages is None or member.can_send_messages:
            context.bot.restrict_chat_member(chat.id, user_id,
                                             MUTE_PERMISSIONS)
            log = "<b>{}:</b>" \
                   "\n#SILENT_MUTE" \
                   "\n<b>• Admin:</b> {}" \
                   "\n<b>• User:</b> {}" \
                   "\n<b>• ID:</b> <code>{}</code>".format(html.escape(chat.title),
                                              mention_html(user.id, user.first_name),
                                              mention_html(member.user.id, member.user.first_name), user_id)
            if reason:
                log += "\n<b>• Reason:</b> {}".format(reason)
            return log

    return ""
Example #13
0
def temp_nomedia(update: Update, context: CallbackContext) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    message = update.effective_message  # type: Optional[Message]
    args = message.text.split(" ")

    user_id, reason = extract_user_and_text(message, args)

    if not user_id:
        message.reply_text("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("I can't seem to find this user")
            return ""
        else:
            raise

    if is_user_admin(chat, user_id, member):
        message.reply_text("I really wish I could restrict admins...")
        return ""

    if user_id == context.bot.id:
        message.reply_text("I'm not gonna RESTRICT myself, are you crazy?")
        return ""

    if not reason:
        message.reply_text(
            "You haven't specified a time to restrict this user for!")
        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 = "<b>{}:</b>" \
          "\n#TEMP RESTRICTED" \
          "\n<b>• Admin:</b> {}" \
          "\n<b>• User:</b> {}" \
          "\n<b>• ID:</b> <code>{}</code>" \
          "\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), user_id, time_val)
    if reason:
        log += "\n<b>• Reason:</b> {}".format(reason)

    try:
        if member.can_send_messages is None or member.can_send_messages:
            context.bot.restrict_chat_member(chat.id,
                                             user_id,
                                             NOMEDIA_PERMISSIONS,
                                             until_date=mutetime)
            message.reply_text(
                "{} restricted from sending media for {}!".format(
                    mention_html(member.user.id, member.user.first_name),
                    time_val),
                parse_mode=ParseMode.HTML)
            return log
        else:
            message.reply_text("This user is already restricted.")

    except BadRequest as excp:
        if excp.message == "Reply message not found":
            # Do not reply
            message.reply_text(
                "{} restricted from sending media for {}!".format(
                    mention_html(member.user.id, member.user.first_name),
                    time_val),
                parse_mode=ParseMode.HTML,
                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("Well damn, I can't restrict that user.")

    return ""
Example #14
0
def unlock(update: Update, context: CallbackContext) -> str:
    chat = update.effective_chat  # type: Optional[Chat]
    user = update.effective_user  # type: Optional[User]
    message = update.effective_message  # type: Optional[Message]
    args = message.text.split(" ")

    if is_user_admin(chat, message.from_user.id):
        if len(args) >= 2:
            if args[1] in LOCK_TYPES:
                sql.update_lock(chat.id, args[1], locked=False)
                message.reply_text("Unlocked {} for everyone!".format(args[1]))
                return "<b>{}:</b>" \
                       "\n#UNLOCK" \
                       "\n<b>• Admin:</b> {}" \
                       "\nUnlocked <code>{}</code>.".format(html.escape(chat.title),
                                                            mention_html(user.id, user.first_name), args[1])

            elif args[1] in "all":
                context.bot.set_chat_permissions(update.message.chat.id,
                                                 UNLOCK_PERMISSIONS)
                sql.update_restriction(chat.id, args[1], locked=False)
                message.reply_text("Unlocked all for everyone!".format(
                    args[1]))
                context.bot.send_message(chat.id,
                                         "***Chat is unmuted.***",
                                         parse_mode=ParseMode.MARKDOWN)

                return "<b>{}:</b>" \
                       "\n#UNLOCK" \
                       "\n<b>• Admin:</b> {}" \
                       "\nUnlocked <code>{}</code>.".format(html.escape(chat.title),
                                                          mention_html(user.id, user.first_name), args[1])

            elif args[1] in RESTRICTION_TYPES:
                sql.update_restriction(chat.id, args[1], locked=False)
                """
                members = users_sql.get_chat_members(chat.id)
                if args[1] == "messages":
                    unrestr_members(context.bot, chat.id, members, media=False, other=False, previews=False)

                elif args[1] == "media":
                    unrestr_members(context.bot, chat.id, members, other=False, previews=False)

                elif args[1] == "other":
                    unrestr_members(context.bot, chat.id, members, previews=False)

                elif args[1] == "previews":
                    unrestr_members(context.bot, chat.id, members)

                elif args[1] == "all":
                    unrestr_members(context.bot, chat.id, members, True, True, True, True)
                """
                message.reply_text("Unlocked {} for everyone!".format(args[1]))

                return "<b>{}:</b>" \
                       "\n#UNLOCK" \
                       "\n<b>Admin:</b> {}" \
                       "\nUnlocked <code>{}</code>.".format(html.escape(chat.title),
                                                            mention_html(user.id, user.first_name), args[1])
            else:
                message.reply_text(
                    "What are you trying to unlock...? Try /locktypes for the list of lockables"
                )

        else:
            context.bot.sendMessage(chat.id,
                                    "What are you trying to unlock...?")

    return ""
Example #15
0
def check_flood(update: Update, context: CallbackContext) -> str:
    user = update.effective_user  # type: Optional[User]
    chat = update.effective_chat  # type: Optional[Chat]
    msg = update.effective_message  # type: Optional[Message]
    limit = sql.get_flood_limit(chat.id)
    flood_time = sql.get_flood_time(chat.id)

    if not user:  # ignore channels
        return ""

    # ignore admins
    if is_user_admin(chat, user.id):
        sql.update_flood(chat.id, None)
        return ""

    should_ban = sql.update_flood(chat.id, user.id)
    if not should_ban:
        return ""

    soft_flood = sql.get_flood_strength(chat.id)
    if soft_flood:  # mute
        if flood_time[:1] == "0":
            reply_perm = "I don't like the flooding, Remain quiet!" \
                    "\n{} has been muted!".format(mention_html(user.id, user.first_name))
            context.bot.restrict_chat_member(chat.id, user.id, permissions)
            msg.reply_text(reply_perm, parse_mode=ParseMode.HTML)
            msg.delete()
        else:
            mutetime = extract_time(update.effective_message, flood_time)
            reply_temp = "I don't like the flooding, Remain quiet for {}!" \
                     "\n{} has been muted!".format(flood_time, mention_html(user.id, user.first_name))
            context.bot.restrict_chat_member(chat.id,
                                             user.id,
                                             permissions,
                                             until_date=mutetime)
            msg.reply_text(reply_temp, parse_mode=ParseMode.HTML)
            msg.delete()

    else:  # ban
        chat.kick_member(user.id)
        reply_ban = "Frankly, I like to leave the flooding to natural disasters." \
                    "\n{} has been banned!".format(mention_html(user.id, user.first_name))
        msg.reply_text(reply_ban, parse_mode=ParseMode.HTML)
        msg.delete()
    try:
        log = "<b>{}:</b>" \
              "\n#FLOOD_CONTROL" \
              "\n<b>• User:</b> {}" \
              "\n<b>• ID:</b> <code>{}</code>".format(html.escape(chat.title), mention_html(user.id, user.first_name), user.id)

        if soft_flood:
            log += "\n<b>• Action:</b> muted"
            log += "\n<b>• Time:</b> {}".format(flood_time)

            if flood_time[:1] == "0":
                log += "\n<b>• Time:</b> permanently"

        else:
            log += "\n<b>• Action:</b> banned"

        log += "\n<b>• Reason:</b> Exceeded flood limit of {} consecutive messages.".format(
            limit)

        return log

    except BadRequest:
        msg.reply_text(
            "I can't kick 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 kick permissions, so automatically disabled anti-flood.".format(chat.title)
Example #16
0
def warn(user: User,
         chat: Chat,
         reason: str,
         message: Message,
         warner: User = None) -> str:
    if is_user_admin(chat, user.id):  #ignore for admins
        #         message.reply_text("Damn admins, can't even be warned!")
        return ""

    if warner:
        warner_tag = mention_html(warner.id, warner.first_name)

    else:
        warner_tag = "Automated warn filter."

    keyboard = InlineKeyboardMarkup([[
        InlineKeyboardButton("Remove warn (admin only)",
                             callback_data="rm_warn({})".format(user.id))
    ]])

    limit, soft_warn, warn_mode = sql.get_warn_setting(chat.id)
    num_warns, reasons = sql.warn_user(user.id, chat.id, reason)
    num = 1
    warn_time = sql.get_warn_time(chat.id)
    if num_warns >= limit:
        sql.reset_warns(user.id, chat.id)
        if not soft_warn:
            if not warn_mode:
                chat.kick_member(user.id)
                reply = "{} warnings, {} has been banned!".format(
                    limit, mention_html(user.id, user.first_name))

            elif warn_mode == 1:
                chat.kick_member(user.id)
                reply = "{} warnings, {} has been banned!".format(
                    limit, mention_html(user.id, user.first_name))

            elif warn_mode == 2:
                chat.unban_member(user.id)
                reply = "{} warnings, {} has been kicked!".format(
                    limit, mention_html(user.id, user.first_name))

            elif warn_mode == 3:
                message.bot.restrict_chat_member(chat.id,
                                                 user.id,
                                                 can_send_messages=False)
                reply = "{} warnings, {} has been muted!".format(
                    limit, mention_html(user.id, user.first_name))

            elif warn_mode == 4:
                warn_time = sql.get_warn_time(chat.id)
                mutetime = extract_time(message, warn_time)
                message.bot.restrict_chat_member(chat.id,
                                                 user.id,
                                                 until_date=mutetime,
                                                 can_send_messages=False)
                reply = "{} warnings, {} has been temporarily muted for {}!".format(
                    limit, mention_html(user.id, user.first_name), warn_time)
            elif warn_mode == 5:
                warn_time = sql.get_warn_time(chat.id)
                tbantime = extract_time(message, warn_time)
                chat.kick_member(user.id, until_date=tbantime)
                reply = "{} warnings, {} has been temporarily banned for {}!".format(
                    limit, mention_html(user.id, user.first_name), warn_time)
        else:
            chat.kick_member(user.id)
            reply = "{} warnings, {} has been banned!".format(
                limit, mention_html(user.id, user.first_name))

        for warn_reason in reasons:
            reply += "\n {}. {}".format(num, html.escape(warn_reason))
            num += 1

        message.bot.send_sticker(chat.id,
                                 BAN_STICKER)  # banhammer natalie sticker

        log_reason = "<b>{}:</b>" \
                     "\n#WARN_ACTION" \
                     "\n<b>• Admin:</b> {}" \
                     "\n<b>• User:</b> {}" \
                     "\n<b>• ID:</b> <code>{}</code>".format(html.escape(chat.title),
                                                            warner_tag,
                                                            mention_html(user.id, user.first_name), user.id)
        if not warn_mode:
            log_reason += "\n<b>• Action:</b> banned"

        elif warn_mode == 1:
            log_reason += "\n<b>• Action:</b> banned"

        elif warn_mode == 2:
            log_reason += "\n<b>• Action:</b> kicked"

        elif warn_mode == 3:
            log_reason += "\n<b>• Action:</b> muted"

        elif warn_mode == 4:
            log_reason += "\n<b>• Action:</b> tmuted" \
                          "\n<b>• Time:</b> {}".format(warn_time)

        elif warn_mode == 5:
            log_reason += "\n<b>• Action:</b> tbanned" \
                          "\n<b>• Time:</b> {}".format(warn_time)

        log_reason += "\n<b>• Counts:</b> <code>{}/{}</code>".format(
            num_warns, limit)

        if reason:
            log_reason += "\n<b>• Reason:</b> {}".format(reason)

    else:
        keyboard = InlineKeyboardMarkup([[
            InlineKeyboardButton("Remove warn (admin only)",
                                 callback_data="rm_warn({})".format(user.id))
        ]])

        if num_warns + 1 == limit:
            if not warn_mode:
                action_mode = "banned"
            elif warn_mode == 1:
                action_mode = "banned"
            elif warn_mode == 2:
                action_mode = "kicked"
            elif warn_mode == 3:
                action_mode = "muted"
            elif warn_mode == 4:
                action_mode = "temporarily muted"
            elif warn_mode == 5:
                action_mode = "temporarily banned"
            reply = "{} has {}/{} warnings... watch out, you'll be {} in the last warn!".format(
                mention_html(user.id, user.first_name), num_warns, limit,
                action_mode)
        else:
            reply = "{} has {}/{} warnings... watch out!".format(
                mention_html(user.id, user.first_name), num_warns, limit)
        if reason:
            reply += "\nReason for last warn:\n{}".format(html.escape(reason))

        log_reason = "<b>{}:</b>" \
                     "\n#WARN" \
                     "\n<b>• Admin:</b> {}" \
                     "\n<b>• User:</b> {}" \
                     "\n<b>• ID:</b> <code>{}</code>" \
                     "\n<b>• Counts:</b> <code>{}/{}</code>".format(html.escape(chat.title),
                                                                    warner_tag,
                                                                    mention_html(user.id, user.first_name), user.id,
                                                                    num_warns, limit)
        if reason:
            log_reason += "\n<b>• Reason:</b> {}".format(reason)

    try:
        message.reply_text(reply,
                           reply_markup=keyboard,
                           parse_mode=ParseMode.HTML)
    except BadRequest as excp:
        if excp.message == "Reply message not found":
            # Do not reply
            message.reply_text(reply,
                               reply_markup=keyboard,
                               parse_mode=ParseMode.HTML,
                               quote=False)
        else:
            raise
    return log_reason