Как исправить проверку белого списка в 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 Nonemain.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(...)) для отладки.