Загрузка...

Чат менеджер | Основа бота

Тема в разделе Python создана пользователем Эксфадор 4 мар 2025. (поднята 11 май 2025) 739 просмотров

Загрузка...
  1. Эксфадор
    Эксфадор Автор темы 4 мар 2025 ПЛАГИНЫ ДЛЯ FPC - t.me/coxerhub 1747 30 авг 2023
    Чат-менеджер бот
    Создан для управления вашим Telegram-чатом

    О боте
    Этот бот разработан для автоматизации управления Telegram-группами и супергруппами. Он предоставляет широкий набор функций, таких как приветствия новых участников, установка правил, управление триггерами, статистика активности, а также модерация (мут, бан, кик и предупреждения). Бот поддерживает систему рангов и ролей, что позволяет гибко настраивать права доступа для пользователей.

    Основные возможности:
    • Настраиваемые приветствия для новых участников
    • Установка правил чата
    • Триггеры с пользовательскими ответами
    • Статистика и топ участников
    • Модерация: мут, кик, бан, предупреждения
    • Система рангов: от "Гостя" до "Владельца"
    • ⚙ Настройки: включение/отключение приветствий и кика за ссылки

    Команды:
    • /start — Запуск бота
    • /help — Список команд
    • /rules — Показать правила
    • /stats — Статистика активности
    • /top — Топ 5 участников
    • /setgreeting — Установить приветствие (Модератор+)
    • /mute username [время] — Замутить пользователя (Младший модератор+)
    • /ban usernameЗабанить пользователя (Старший админ+)
    • /rank username [роль] — Установить ранг (Владелец)

    Исходный код бота
    Python
    import asyncio
    import logging
    from datetime import timedelta
    from aiogram import Bot, Dispatcher, types
    from aiogram.filters import Command, CommandStart
    from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
    from aiogram import F
    from aiogram.enums import ParseMode, ChatMemberStatus, ChatType
    from aiogram.client.default import DefaultBotProperties
    import aiosqlite
    import random
    import re

    logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
    logger = logging.getLogger(__name__)

    API_TOKEN = ""
    bot = Bot(token=API_TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))
    dp = Dispatcher()
    DB_PATH = "chat_manager.db"

    link_pattern = re.compile(r'(https?://\S+|www\.\S+|\S+\.(com|org|ru|net|io|me|info|biz|gov|edu|рф|укр|kz|by))\b', re.IGNORECASE)

    async def init_db():
    async with aiosqlite.connect(DB_PATH) as db:
    await db.execute('''CREATE TABLE IF NOT EXISTS settings
    (chat_id INTEGER PRIMARY KEY, greeting TEXT, rules TEXT, welcome_enabled INTEGER DEFAULT 1, kick_links INTEGER DEFAULT 0)''')
    await db.execute('''CREATE TABLE IF NOT EXISTS stats
    (chat_id INTEGER, user_id INTEGER, message_count INTEGER, date TEXT,
    PRIMARY KEY (chat_id, user_id, date))''')
    await db.execute('''CREATE TABLE IF NOT EXISTS triggers
    (chat_id INTEGER, trigger TEXT, response TEXT,
    PRIMARY KEY (chat_id, trigger))''')
    await db.execute('''CREATE TABLE IF NOT EXISTS ranks
    (chat_id INTEGER, user_id INTEGER, rank TEXT,
    PRIMARY KEY (chat_id, user_id))''')
    await db.execute('''CREATE TABLE IF NOT EXISTS warns
    (chat_id INTEGER, user_id INTEGER, warn_count INTEGER,
    PRIMARY KEY (chat_id, user_id))''')
    await db.execute('''CREATE TABLE IF NOT EXISTS role_names
    (chat_id INTEGER, rank_key TEXT, rank_name TEXT,
    PRIMARY KEY (chat_id, rank_key))''')
    await db.commit()

    async def get_role_name(chat_id: int, rank_key: str) -> str:
    async with aiosqlite.connect(DB_PATH) as db:
    async with db.execute("SELECT rank_name FROM role_names WHERE chat_id = ? AND rank_key = ?",
    (chat_id, rank_key)) as cursor:
    result = await cursor.fetchone()
    default_roles = {
    "guest": "Гость",
    "junior_moderator": "Младший модератор",
    "moderator": "Модератор",
    "junior_admin": "Младший админ",
    "senior_admin": "Старший админ",
    "owner": "Владелец"
    }
    return result[0] if result else default_roles.get(rank_key, rank_key)

    async def get_user_rank(chat_id: int, user_id: int) -> str:
    async with aiosqlite.connect(DB_PATH) as db:
    async with db.execute("SELECT rank FROM ranks WHERE chat_id = ? AND user_id = ?",
    (chat_id, user_id)) as cursor:
    result = await cursor.fetchone()
    member = await bot.get_chat_member(chat_id, user_id)
    if member.status == ChatMemberStatus.CREATOR:
    return "owner"
    elif member.status == ChatMemberStatus.ADMINISTRATOR:
    return "moderator" if not result else result[0]
    return result[0] if result else "guest"

    def get_rank_level(rank: str) -> int:
    rank_levels = {
    "guest": 0,
    "junior_moderator": 1,
    "moderator": 2,
    "junior_admin": 3,
    "senior_admin": 4,
    "owner": 5
    }
    return rank_levels.get(rank, 0)

    async def has_permission(chat_id: int, user_id: int, min_level: int) -> bool:
    rank = await get_user_rank(chat_id, user_id)
    return get_rank_level(rank) >= min_level

    async def get_user_id(message: Message) -> int | None:
    if message.reply_to_message:
    return message.reply_to_message.from_user.id
    parts = message.text.split()
    if len(parts) > 1 and parts[1].startswith('@'):
    return await get_user_id_from_mention(parts[1], message.chat.id)
    return None

    async def get_user_id_from_mention(mention: str, chat_id: int) -> int | None:
    mention = mention.lstrip("@")
    try:
    member = await bot.get_chat_member(chat_id, mention)
    return member.user.id
    except:
    return None

    @dp.message(CommandStart(), F.chat.type == ChatType.PRIVATE)
    async def cmd_start_private(message: Message):
    keyboard = InlineKeyboardMarkup(inline_keyboard=[
    [InlineKeyboardButton(text="Лучшие чаты за сутки", callback_data="top_day")],
    [InlineKeyboardButton(text="Лучшие чаты за месяц", callback_data="top_month")],
    [InlineKeyboardButton(text="Лучшие чаты за всё время", callback_data="top_all")]
    ])
    await message.answer(" Выберите период для просмотра лучших чатов:", reply_markup=keyboard)

    @dp.callback_query(F.data.in_({"top_day", "top_month", "top_all"}))
    async def process_top_chats(callback: types.CallbackQuery):
    period = callback.data.split("_")[1]
    if period == "day":
    time_frame = "AND date >= date('now', '-1 day')"
    elif period == "month":
    time_frame = "AND date >= date('now', '-1 month')"
    else:
    time_frame = ""
    async with aiosqlite.connect(DB_PATH) as db:
    query = f"""
    SELECT chat_id, SUM(message_count) as total_messages
    FROM stats
    WHERE 1=1 {time_frame}
    GROUP BY chat_id
    ORDER BY total_messages DESC
    LIMIT 5
    """
    async with db.execute(query) as cursor:
    top_chats = await cursor.fetchall()
    if not top_chats:
    await callback.answer(" Нет данных за этот период.", show_alert=True)
    return
    response = f" <b>Топ 5 чатов за {'сутки' if period == 'day' else 'месяц' if period == 'month' else 'всё время'}</b> \n\n"
    for i, (chat_id, total_messages) in enumerate(top_chats, 1):
    try:
    chat = await bot.get_chat(chat_id)
    chat_title = chat.title or "Чат без названия"
    response += f"{i}. {chat_title} — <b>{total_messages}</b> сообщений\n"
    except Exception as e:
    logger.error(f"Ошибка при получении чата {chat_id}: {e}")
    response += f"{i}. Чат {chat_id} — <b>{total_messages}</b> сообщений\n"
    await callback.message.edit_text(response)
    await callback.answer()

    @dp.message(CommandStart(), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_start(message: Message):
    await message.answer(" <b>Привет!</b> Я твой чат-менеджер! Используй /help для списка команд.")

    @dp.message(Command("help"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_help(message: Message):
    help_text = (
    """
    <b>Список команд чат-менеджера</b>

    <b><i>Для всех:</i></b>
    /start — Запустить бота
    /help — Показать это меню
    /rules — Правила чата
    /staff — Список команды
    /stats — Статистика активности
    /top — Топ 5 участников

    ⚙ <b><i>Настройки чата (Модератор+):</i></b>
    /setgreeting [текст] — Установить приветствие
    /setrules [текст] — Установить правила
    /addtrigger [слово] [ответ] — Добавить триггер
    /removetrigger [слово] — Удалить триггер

    <b><i>Управление (по уровням):</i></b>
    /mute @username [время] — Замутить (1+)
    /unmute @username — Размутить (2+)
    /kick @username — Кикнуть (2+)
    /warn @username — Выдать предупреждение (2+)
    /ban @username — Забанить (4+)
    /unban @username — Разбанить (4+)

    <b><i>Администрирование:</i></b>
    /rank @username [роль] — Установить ранг (5+)
    /setrole [роль] [название] — Название роли (5+)
    /config — Настройки бота (4+)

    <b>Роли:</b> guest (0), junior_moderator (1), moderator (2), junior_admin (3), senior_admin (4), owner (5)
    <i>Уровень прав указан в скобках.</i>
    """
    )
    await message.answer(help_text)

    @dp.message(Command("rules"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_show_rules(message: Message):
    async with aiosqlite.connect(DB_PATH) as db:
    async with db.execute("SELECT rules FROM settings WHERE chat_id = ?",
    (message.chat.id,)) as cursor:
    result = await cursor.fetchone()
    if result and result[0]:
    await message.reply(f" <b>Правила чата:</b>\n{result[0]}")
    else:
    await message.reply(" <i>Правила пока не установлены.</i>")

    @dp.message(Command("staff"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_staff(message: Message):
    chat_admins = await bot.get_chat_administrators(message.chat.id)
    staff_list = []
    for admin in chat_admins:
    if admin.user.is_bot:
    continue
    rank = await get_user_rank(message.chat.id, admin.user.id)
    if get_rank_level(rank) >= 1:
    role_name = await get_role_name(message.chat.id, rank)
    username = admin.user.username or admin.user.first_name
    staff_list.append((get_rank_level(rank), f"@{username}", role_name))
    async with aiosqlite.connect(DB_PATH) as db:
    async with db.execute("SELECT user_id, rank FROM ranks WHERE chat_id = ? AND rank IN ('junior_moderator', 'moderator', 'junior_admin', 'senior_admin', 'owner')",
    (message.chat.id,)) as cursor:
    custom_mods = await cursor.fetchall()
    for user_id, rank in custom_mods:
    if not any(admin.user.id == user_id for admin in chat_admins if not admin.user.is_bot):
    try:
    user = await bot.get_chat_member(message.chat.id, user_id)
    if user.user.is_bot:
    continue
    role_name = await get_role_name(message.chat.id, rank)
    username = user.user.username or user.user.first_name
    staff_list.append((get_rank_level(rank), f"@{username}", f"{role_name} (назначен вручную)"))
    except Exception as e:
    logger.error(f"Ошибка при получении данных пользователя {user_id}: {e}")
    staff_list.sort(key=lambda x: x[0], reverse=True)
    response = " <b>Команда чата</b> \n\n"
    if staff_list:
    for level, username, role_name in staff_list:
    if level == 5:
    response += f" {username} — <b>{role_name}</b>\n"
    elif level == 4:
    response += f" {username} — <b>{role_name}</b>\n"
    elif level == 3:
    response += f"⚔ {username} — {role_name}\n"
    elif level == 2:
    response += f" {username} — {role_name}\n"
    elif level == 1:
    response += f" {username} — {role_name}\n"
    else:
    response += "⚡ <i>В чате пока нет модераторов.</i>\n"
    response += "\n <i>От высшего ранга к низшему.</i>"
    await message.reply(response)

    @dp.message(Command("setrole"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_setrole(message: Message):
    if not await has_permission(message.chat.id, message.from_user.id, 5):
    await message.reply(" Только <b>владелец</b> может менять названия ролей!")
    return
    parts = message.text.split(maxsplit=2)
    if len(parts) < 3:
    await message.reply("⚠ Укажи роль и название! Пример: /setrole moderator Модератор")
    return
    rank_key = parts[1].lower()
    valid_ranks = ["guest", "junior_moderator", "moderator", "junior_admin", "senior_admin", "owner"]
    if rank_key not in valid_ranks:
    await message.reply(f"❌ Роль должна быть: {', '.join(valid_ranks)}!")
    return
    rank_name = parts[2]
    async with aiosqlite.connect(DB_PATH) as db:
    await db.execute("INSERT OR REPLACE INTO role_names (chat_id, rank_key, rank_name) VALUES (?, ?, ?)",
    (message.chat.id, rank_key, rank_name))
    await db.commit()
    await message.reply(f"✅ Название роли '{rank_key}' изменено на: <b>{rank_name}</b>")

    @dp.message(Command("setgreeting"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def set_greeting(message: Message):
    if not await has_permission(message.chat.id, message.from_user.id, 2):
    await message.reply(" Недостаточно прав!")
    return
    text = message.text[11:].strip()
    if not text:
    await message.reply("⚠ Укажи текст приветствия!")
    return
    async with aiosqlite.connect(DB_PATH) as db:
    await db.execute("INSERT OR REPLACE INTO settings (chat_id, greeting) VALUES (?, ?)",
    (message.chat.id, text))
    await db.commit()
    await message.reply(f" <b>Новое приветствие:</b>\n{text}")

    @dp.message(Command("setrules"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def set_rules(message: Message):
    if not await has_permission(message.chat.id, message.from_user.id, 2):
    await message.reply(" Недостаточно прав!")
    return
    text = message.text[9:].strip()
    if not text:
    await message.reply("⚠ Укажи текст правил!")
    return
    async with aiosqlite.connect(DB_PATH) as db:
    await db.execute("INSERT OR REPLACE INTO settings (chat_id, rules) VALUES (?, ?)",
    (message.chat.id, text))
    await db.commit()
    await message.reply(f" <b>Новые правила:</b>\n{text}")


    @dp.message(Command("addtrigger"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def add_trigger(message: Message):
    if not await has_permission(message.chat.id, message.from_user.id, 2):
    await message.reply(" Недостаточно прав!")
    return
    parts = message.text[10:].strip().split(maxsplit=1)
    if len(parts) < 2:
    await message.reply("⚠ Укажи триггер и ответ! Пример: /addtrigger привет Привет!")
    return
    trigger, response = parts[0], parts[1]
    async with aiosqlite.connect(DB_PATH) as db:
    await db.execute("INSERT OR REPLACE INTO triggers (chat_id, trigger, response) VALUES (?, ?, ?)",
    (message.chat.id, trigger.lower(), response))
    await db.commit()
    await message.reply(f" Триггер '<b>{trigger}</b>' добавлен: {response}")

    @dp.message(Command("removetrigger"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def remove_trigger(message: Message):
    if not await has_permission(message.chat.id, message.from_user.id, 2):
    await message.reply(" Недостаточно прав!")
    return
    trigger = message.text[13:].strip()
    if not trigger:
    await message.reply("⚠ Укажи триггер для удаления!")
    return
    async with aiosqlite.connect(DB_PATH) as db:
    await db.execute("DELETE FROM triggers WHERE chat_id = ? AND trigger = ?",
    (message.chat.id, trigger.lower()))
    await db.commit()
    await message.reply(f"❌ Триггер '<b>{trigger}</b>' удалён.")

    @dp.message(Command("stats"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_stats(message: Message):
    async with aiosqlite.connect(DB_PATH) as db:
    async with db.execute("SELECT user_id, SUM(message_count) as total FROM stats WHERE chat_id = ? GROUP BY user_id ORDER BY total DESC LIMIT 10",
    (message.chat.id,)) as cursor:
    stats = await cursor.fetchall()
    if not stats:
    await message.reply(" <i>Статистика пуста.</i>")
    return
    max_messages = max(count for _, count in stats)
    response = " <b>Топ 10 по активности</b> \n\n"
    for user_id, count in stats:
    try:
    user = await bot.get_chat_member(message.chat.id, user_id)
    rank = await get_user_rank(message.chat.id, user_id)
    role_name = await get_role_name(message.chat.id, rank)
    bar_length = int((count / max_messages) * 20) if max_messages > 0 else 0
    bar = "*" * bar_length + "░" * (20 - bar_length)
    username = user.user.username or user.user.first_name
    response += f"@{username} ({role_name})\n{bar} <b>{count}</b>\n"
    except Exception as e:
    logger.error(f"Ошибка при получении пользователя {user_id}: {e}")
    await message.reply(response)

    @dp.message(Command("top"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_top(message: Message):
    async with aiosqlite.connect(DB_PATH) as db:
    async with db.execute("SELECT user_id, SUM(message_count) as total FROM stats WHERE chat_id = ? GROUP BY user_id ORDER BY total DESC LIMIT 5",
    (message.chat.id,)) as cursor:
    top_users = await cursor.fetchall()
    if not top_users:
    await message.reply(" <i>Топ пуст.</i>")
    return
    response = " <b>Топ 5 участников</b> \n\n"
    for i, (user_id, count) in enumerate(top_users, 1):
    try:
    user = await bot.get_chat_member(message.chat.id, user_id)
    rank = await get_user_rank(message.chat.id, user_id)
    role_name = await get_role_name(message.chat.id, rank)
    response += f"{i}. @{user.user.username or user.user.first_name} ({role_name}) — <b>{count}</b> сообщений\n"
    except Exception as e:
    logger.error(f"Ошибка при получении пользователя {user_id}: {e}")
    await message.reply(response)

    @dp.message(Command("kick"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_kick(message: Message):
    if not await has_permission(message.chat.id, message.from_user.id, 2):
    await message.reply(" Требуется уровень 2+ (<b>Модератор</b>)!")
    return
    user_id = await get_user_id(message)
    if not user_id:
    await message.reply("⚠ Укажи пользователя (@username или ответ)!")
    return
    try:
    await bot.ban_chat_member(message.chat.id, user_id)
    await bot.unban_chat_member(message.chat.id, user_id)
    await message.reply(f" Пользователь кикнут.")
    except Exception as e:
    logger.error(f"Ошибка при кике пользователя {user_id}: {e}")
    await message.reply("❌ Не удалось кикнуть пользователя.")

    @dp.message(Command("mute"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_mute(message: Message):
    if not await has_permission(message.chat.id, message.from_user.id, 1):
    await message.reply(" Требуется уровень 1+ (<b>Младший модератор</b>)!")
    return
    user_id = await get_user_id(message)
    if not user_id:
    await message.reply("⚠ Укажи пользователя (@username или ответ)!")
    return
    parts = message.text.split()
    if len(parts) < 2 or (len(parts) == 2 and message.reply_to_message is None):
    await message.reply("⚠ Укажи время мута (например, 1y 2mo 3w 4h 5m или 60)!")
    return
    time_parts = parts[2:] if len(parts) > 2 else parts[1:]
    if not time_parts:
    await message.reply("⚠ Укажи время мута!")
    return
    total_minutes = 0
    try:
    for part in time_parts:
    if part.endswith("y"):
    total_minutes += int(part[:-1]) * 365 * 24 * 60
    elif part.endswith("mo"):
    total_minutes += int(part[:-2]) * 30 * 24 * 60
    elif part.endswith("w"):
    total_minutes += int(part[:-1]) * 7 * 24 * 60
    elif part.endswith("h"):
    total_minutes += int(part[:-1]) * 60
    elif part.endswith("m"):
    total_minutes += int(part[:-1])
    elif part.isdigit():
    total_minutes += int(part)
    else:
    await message.reply("❌ Неверный формат! Используй: 1y, 2mo, 3w, 4h, 5m или число минут.")
    return
    if total_minutes <= 0:
    await message.reply("⚠ Время должно быть больше 0!")
    return
    except ValueError:
    await message.reply("❌ Ошибка в формате времени!")
    return
    until_date = message.date + timedelta(minutes=total_minutes)
    years = total_minutes // (365 * 24 * 60)
    remaining_minutes = total_minutes % (365 * 24 * 60)
    months = remaining_minutes // (30 * 24 * 60)
    remaining_minutes %= (30 * 24 * 60)
    weeks = remaining_minutes // (7 * 24 * 60)
    remaining_minutes %= (7 * 24 * 60)
    hours = remaining_minutes // 60
    minutes = remaining_minutes % 60
    time_desc_parts = []
    if years > 0:
    time_desc_parts.append(f"{years}г")
    if months > 0:
    time_desc_parts.append(f"{months}мес")
    if weeks > 0:
    time_desc_parts.append(f"{weeks}н")
    if hours > 0:
    time_desc_parts.append(f"{hours}ч")
    if minutes > 0:
    time_desc_parts.append(f"{minutes}м")
    time_desc = " ".join(time_desc_parts) or "0м"
    try:
    if message.chat.type == ChatType.SUPERGROUP:
    await bot.restrict_chat_member(
    message.chat.id,
    user_id,
    permissions=types.ChatPermissions(can_send_messages=False),
    until_date=until_date
    )
    await message.reply(f" Пользователь замучен на <b>{time_desc}</b>.")
    else:
    await bot.ban_chat_member(message.chat.id, user_id)
    await message.reply(f" Замучен на <b>{time_desc}</b> (временный кик).")
    await asyncio.sleep(total_minutes * 60)
    await bot.unban_chat_member(message.chat.id, user_id)
    logger.info(f"Пользователь {user_id} разбанен после мута.")
    except Exception as e:
    logger.error(f"Ошибка при муте {user_id}: {e}")
    await message.reply(f"❌ Ошибка: {str(e)}")


    @dp.message(Command("unmute"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_unmute(message: Message):
    if not await has_permission(message.chat.id, message.from_user.id, 2):
    await message.reply(" Требуется уровень 2+ (<b>Модератор</b>)!")
    return
    user_id = await get_user_id(message)
    if not user_id:
    await message.reply("⚠ Укажи пользователя (@username или ответ)!")
    return
    try:
    if message.chat.type == ChatType.SUPERGROUP:
    await bot.restrict_chat_member(
    message.chat.id,
    user_id,
    permissions=types.ChatPermissions(
    can_send_messages=True,
    can_send_media_messages=True,
    can_send_polls=True,
    can_send_other_messages=True,
    can_add_web_page_previews=True,
    can_change_info=True,
    can_invite_users=True,
    can_pin_messages=True
    )
    )
    await message.reply(" Пользователь размучен.")
    else:
    await bot.unban_chat_member(message.chat.id, user_id)
    await message.reply(" Пользователь размучен (разбанен).")
    except Exception as e:
    logger.error(f"Ошибка при размуте {user_id}: {e}")
    await message.reply(f"❌ Ошибка: {str(e)}")


    @dp.message(Command("ban"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_ban(message: Message):
    if not await has_permission(message.chat.id, message.from_user.id, 4):
    await message.reply(" Требуется уровень 4+ (<b>Старший админ</b>)!")
    return
    user_id = await get_user_id(message)
    if not user_id:
    await message.reply("⚠ Укажи пользователя (@username или ответ)!")
    return
    try:
    await bot.ban_chat_member(message.chat.id, user_id)
    await message.reply(f" Пользователь забанен.")
    except Exception as e:
    logger.error(f"Ошибка при бане {user_id}: {e}")
    await message.reply("❌ Не удалось забанить.")


    @dp.message(Command("unban"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_unban(message: Message):
    if not await has_permission(message.chat.id, message.from_user.id, 4):
    await message.reply(" Требуется уровень 4+ (<b>Старший админ</b>)!")
    return
    user_id = await get_user_id(message)
    if not user_id:
    await message.reply("⚠ Укажи пользователя (@username или ответ)!")
    return
    try:
    await bot.unban_chat_member(message.chat.id, user_id)
    await message.reply(f"✅ Пользователь разбанен.")
    except Exception as e:
    logger.error(f"Ошибка при разбане {user_id}: {e}")
    await message.reply("❌ Не удалось разбанить.")


    @dp.message(Command("warn"), F.chat.type.in_({ChatType.GROUP, ChatType.SUPERGROUP}))
    async def cmd_warn(message: Message):
    if not await has_permission(message.chat.id, message.from_user.id, 2):
    await message.reply(" Требуется уровень 2+ (<b>Модератор</b>)!")
    return
    user_id = await get_user_id(message)
    if not user_id:
    await message.reply("⚠ Укажи пользователя (@username или ответ)!")
    return
    async with aiosqlite.connect(DB_PATH) as db:
    await db.execute("INSERT INTO warns (chat_id, user_id, warn_count) VALUES (?, ?, 1) "
    "ON CONFLICT(chat_id, user_id) DO UPDATE SET warn_count = warn_count + 1",
    (message.chat.id, user_id))
    async with db.e
     
    4 мар 2025 Изменено
  2. Eblocrut
    Eblocrut 7 мар 2025 делаем 5154 14 июн 2023
    перенеси в питон
     
  3. Septefrso
    Septefrso 10 мар 2025 Эбля, ну ты зачем? 52 13 мар 2018
    ох уж эти :pressF:стринги
     
  4. zxcrazov
    zxcrazov 18 мар 2025 90 7 июн 2020
    а чо кодик не дописан
     
  5. Ryebvxgwy
    Ryebvxgwy 19 мар 2025 18 5 окт 2019
    ох уж эти сырые sql запросы
     
    1. Посмотреть предыдущие комментарии (1)
    2. Властелин
      zxcrazov, да, а о нейросетях, которые могут оптимизировать код, мы ничего не слышали
    3. defeatingopps
      zxcrazov, у него видимо код не уместился в рамку лолза :2011_like:
Top