Как снять ограничения, для одного пользователя?
Подскажите, как сделать так, чтобы только пользователь, которому адресована капча мог снять ограничения, а не любой юзер. Скажем, капча адресована для Екатерины (пользователь, которому запрещено писать), но при этом другой пользователь может нажать на кнопку и все ограничения снимаются. Как это исправить?
Я долго лепил этот код, несколько человек с разных сайтов оказали мне помощь, один человек даже целый день правил код, я же потом просто немного его улучшил, пользуясь информацией, которую читал по различным сайтам.
Я видел в группах боты, в которых эта функция работает корректно. Например, после нажатия на чужую капчу мне написал бот: "Эта капча не для Вас".
Мой код идеально работает, но существует такой недочет.
#База Данных
conn = sqlite3.connect("misqlite.db")
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS USERS
(id INTEGER PRIMARY KEY NOT NULL, user_id INTEGER, username TEXT, name TEXT, last_name TEXT, chat_id INTEGER)''')
conn.commit()
#conn.close()
class SQLither:
def __init__(self, database) -> object:
self.conn = sqlite3.connect(database)
self.c = self.conn.cursor()
def exists_user_chat(self, user_id, chat_id):
"""Проверка существования пользователя в БД и в группе"""
#return bool(self.c.execute("SELECT * FROM users WHERE user_id=?", (user_id,)).fetchone())
return bool(self.c.execute("SELECT * FROM users WHERE user_id=? and chat_id=?", (user_id, chat_id,)).fetchone())
def add_to_db(self, user_id, username, name, last_name, chat_id):
"""Добавление пользователя в БД"""
#self.c.execute("INSERT INTO users ('user_id') VALUES(?)", (user_id,)) and self.c.execute("INSERT INTO users ('username') VALUES(?)", (username,))
self.c.execute("INSERT INTO users(user_id, username, name, last_name, chat_id) VALUES(?,?,?,?,?)", (user_id, username, name, last_name, chat_id))
self.conn.commit()
db = SQLither("misqlite.db")
@dp.message_handler(commands=['start'])
async def inline_menu(message: types.Message):
await bot.send_message(message.chat.id, f'<b>\nНажми кнопку.</b>'.format(message.from_user), parse_mode='html', reply_markup=menu)
return
Рабочий код
@dp.message_handler(content_types=['text'])
async def handler_text(message: types.Message):
member = await bot.get_chat_member(message.chat.id, message.from_user.id)
if member.user.username == 'GroupAnonymousBot':
#if member.user.first_name == 'Group':
return
user_id = message.from_user.id
username = message.from_user.username
last_name = message.from_user.last_name
name = message.from_user.full_name
chat_id = message.chat.id
if not db.exists_user_chat(user_id, chat_id):
keyboard = types.InlineKeyboardMarkup(row_width=1)
checkYes = types.InlineKeyboardButton(text='Я не робот!', callback_data=f'captcha:{user_id}')
keyboard.add(checkYes)
msg = await bot.send_message(message.chat.id, f"<a href=\"tg://user?id={user_id}\">{name}</a>. нажми кнопку.".format(message.from_user), parse_mode='html', disable_notification=True, disable_web_page_preview=True, reply_markup = keyboard)
asyncio.create_task(delete_message(msg, 180))
await bot.restrict_chat_member(message.chat.id, message.from_user.id, ChatPermissions(can_send_messages=False, can_send_media_messages=False, can_send_other_messages=False, can_add_web_page_previews=False, can_send_polls=False, can_pin_messages=False, disable_notification=True, can_invite_users=True))
await message.delete()
db.add_to_db(message.from_user.id, username, name, last_name, message.chat.id)
return
@dp.callback_query_handler(text_startswith='captcha')
async def captcha(call: types.CallbackQuery):
user_id = str(call.from_user.id)
to_id = call.data.split(':')[1]
username = call.from_user.username
last_name = call.from_user.last_name
name = call.from_user.full_name
chat_id = call.message.chat.id
if not db.exists_user_chat(user_id, chat_id):
db.add_to_db(call.from_user.id, username, name, last_name, call.message.chat.id)
member = await bot.get_chat_member(chat_id=call.message.chat.id, user_id=call.from_user.id)
if user_id in to_id:
#if member.status in member_statuses:
await call.answer(text="Спасибо)", show_alert=True)
#await call.message.delete()
await bot.restrict_chat_member(call.message.chat.id, call.from_user.id, ChatPermissions(can_send_messages=True, can_send_media_messages=True, can_send_other_messages=True, can_add_web_page_previews=True, can_send_polls=True, can_pin_messages=True, can_invite_users=True, can_change_info=True))
else:
await call.answer(text="Не принято", show_alert=True)
Ответы (1 шт):
Это можно сделать, храня данные об адресате в inline-кнопке. Например, вместо callback_data = 'captcha', мы сделаем callback_data = f'captcha:{id пользователя}'. Далее в хендлере мы достаем этот id (это можно сделать с помощью split) и сравниваем его с id пользователя, нажавшего на кнопку.
Вот как это выглядит в коде:
def captcha(user_id: int) -> types.InlineKeyboardMarkup: #генерация клавиатуры
markup = types.InlineKeyboardMarkup(
inline_keyboard=[
types.InlineKeyboardButton(
'Я не робот!',
callback_data=f'captcha:{user_id}',
),
],
)
return markup
@dp.message_handler(commands='start')
async def captcha(message: types.Message):
await message.answer(
'<b>Нажми на кнопку!</b>',
reply_markup=captcha(message.from_user.id),
)
@dp.callback_query_handler(text_startswith='captcha')
async def check(call: types.CallbackQuery):
user_id = str(call.from_user.id)
to_id = call.data.split(':')[1]
if user_id == to_id: # сверяем id в кнопке с id нажавшего
await call.message.edit_text(
'Капча пройдена!',
)
# разблокируем возможность писать
else:
await call.answer(
'Это не ваша капча!',
True,
)