Как исправить проверку белого списка в aiogram с SQLite

    При разработке Telegram-ботов на aiogram часто возникает задача ограничения доступа по белому списку (whitelist). Типичная ошибка - бот не находит ID пользователя в базе данных, хотя запись существует. Разберём причины и решение на примере SQLite.

    Почему aiogram не видит ID в белом списке?

    Основная проблема в вашем коде - некорректная проверка типа данных. Функция get_users() возвращает кортеж (adduser_id,), а не просто число. При сравнении message.chat.id == db.get_users(message.chat.id) вы сравниваете число с кортежем, что всегда даёт False. Кроме того, вы используете функцию get_users_exist(), которая не определена в предоставленном коде.

    Исправляем функцию get_users()

    Нужно извлекать первый элемент кортежа. Обновите код в db.py:

    def get_user(user_id):
        db = sqlite3.connect('data.db', check_same_thread=False)
        cursor = db.cursor()
        cursor.execute("SELECT adduser_id FROM white WHERE adduser_id=?", (user_id,))
        row = cursor.fetchone()
        db.close()
        if row:
            return row[0]  # возвращаем число, а не кортеж
        return None

    Корректная проверка в main.py

    Теперь исправим обработчик команды /checkwhite. Добавим проверку существования пользователя в БД:

    @dp.message_handler(commands=['checkwhite'])
    async def check_white(message: types.Message):
        user_id = message.chat.id
        if db.get_user(user_id) is not None:
            await message.answer('Добро пожаловать')
        else:
            await message.answer('У вас нет доступа')

    Дополнительные рекомендации по работе с SQLite в aiogram

    • Закрывайте соединение с БД после каждого запроса, чтобы избежать блокировок.
    • Используйте контекстные менеджеры для автоматического закрытия: with sqlite3.connect(...) as db:.
    • Проверяйте типы данных: message.chat.id - это int, поэтому в БД столбец должен быть INTEGER.
    • Обрабатывайте случай отсутствия записи - возвращайте None вместо ошибки.

    Пример полного рабочего кода

    Ниже приведён минимальный рабочий пример с пояснениями.

    db.py (работа с базой)

    import sqlite3
    
    def init_db():
        with sqlite3.connect('data.db') as db:
            db.execute('''CREATE TABLE IF NOT EXISTS white (
                adduser_id INTEGER PRIMARY KEY
            )''')
    
    def add_user(user_id: int):
        with sqlite3.connect('data.db') as db:
            db.execute('INSERT OR IGNORE INTO white (adduser_id) VALUES (?)', (user_id,))
            db.commit()
    
    def get_user(user_id: int):
        with sqlite3.connect('data.db') as db:
            row = db.execute('SELECT adduser_id FROM white WHERE adduser_id=?', (user_id,)).fetchone()
            return row[0] if row else None

    main.py (обработчик)

    from aiogram import Bot, Dispatcher, types
    from aiogram.utils import executor
    import db
    
    bot = Bot(token='YOUR_TOKEN')
    dp = Dispatcher(bot)
    
    @dp.message_handler(commands=['start'])
    async def start(message: types.Message):
        await message.answer('Бот запущен. Используйте /checkwhite для проверки доступа.')
    
    @dp.message_handler(commands=['checkwhite'])
    async def check_white(message: types.Message):
        user_id = message.from_user.id  # или message.chat.id для групп
        if db.get_user(user_id):
            await message.answer('Добро пожаловать!')
        else:
            await message.answer('У вас нет доступа.')
    
    if __name__ == '__main__':
        db.init_db()
        executor.start_polling(dp, skip_updates=True)

    Заключение

    Главная ошибка - сравнение числа с кортежем. Исправив возвращаемое значение функции get_users() на row[0], вы получите корректную проверку белого списка. Всегда проверяйте типы данных и закрывайте соединения с БД. Если проблема сохраняется, используйте print(type(...)) для отладки.

    Часто задаваемые вопросы