Как сделать механизм поиска анкет пользователей на основе их выбора?
Пишу телеграмм-бота для поиска мероприятий и спутника на python, использую telebot и sqlite3. Механизм взаимодействия с ботом:
- Запускаешь бота
- Далее этап регистрации
- Затем переходишь к выбору мероприятий (по фильтрам, либо можно нажать "соучайное")
- Далее по задумке, после того, как бот пришлёт мероприятие, должна быть кнопка "ПОЙДУ", после чего бот должен отправить анкету другого пользователя, идущего на это же мероприятие. Функционал поиска работает, но не могу придумать как сделать поиск и вывод анкет других пользователей. Если кто знает как такое реализовать, прошу помочь. Заранее благодарю. Код бота:
import telebot
import sqlite3
from telebot import types # для указание типов
# инициализация бота
bot = telebot.TeleBot('TOKEN')
# инициализация базы данных
conn = sqlite3.connect('database.db', check_same_thread=False)
cursor = conn.cursor()
# создание таблицы для хранения анкет
cursor.execute("""CREATE TABLE IF NOT EXISTS profiles
(id INTEGER PRIMARY KEY AUTOINCREMENT,
telegram_id INTEGER NOT NULL,
name TEXT NOT NULL,
social_link TEXT NOT NULL,
about TEXT NOT NULL)""")
conn.commit()
# создание таблицы для хранения мероприятий
cursor.execute("""CREATE TABLE IF NOT EXISTS events
(event_id INTEGER PRIMARY KEY AUTOINCREMENT,
type TEXT NOT NULL,
name TEXT NOT NULL,
cost INTEGER NOT NULL,
date TEXT NOT NULL,
time INTEGER NOT NULL,
description TEXT NOT NULL,
link TEXT NOT NULL)""")
# #добавляем тестовые мероприятия в базу данных
# cursor.execute('''INSERT INTO events (type, name, cost, date, time, description, link)
# VALUES ("КИНО", "Матрица", 10.99, "2023-02-30", "20:00", "У меня дежавю", "https://www.kinopoisk.ru/film/301/")''')
# cursor.execute('''INSERT INTO events (type, name, cost, date, time, description, link)
# VALUES ("ВЫСТАВКА", "Музей иллюзий", 5.99, "2023-04-01", "14:00", "Невероятные 3D-инсталляции музея иллюзий", "https://afisha.yandex.ru/kazan/art/muzey-illyuziy?source=rubric")''')
# cursor.execute('''INSERT INTO events (type, name, cost, date, time, description, link)
# VALUES ("ТЕАТР", "Скрипач на крыше", 15.99, "2023-21-06", "19:00", "Это мюзикл", "https://afisha.yandex.ru/kazan/theatre_show/skripach-na-kryshe-teatr-im-kachalova?source=selection-events")''')
# conn.commit()
# функция для создания анкеты пользователя
def create_profile(telegram_id, name, social_link, about):
cursor.execute("INSERT INTO profiles (telegram_id, name, social_link, about) VALUES (?, ?, ?, ?)",
(telegram_id, name, social_link, about))
conn.commit()
def get_events_by_type(event_type):
cursor.execute("SELECT * FROM events WHERE type=?", (event_type,))
events = cursor.fetchall()
return events
# функция для получения анкеты пользователя
def get_profile(telegram_id):
cursor.execute("SELECT * FROM profiles WHERE telegram_id=?", (telegram_id,))
profile=cursor.fetchone()
return profile
# функция для удаления анкеты пользователя
def delete_profile(telegram_id):
cursor.execute("DELETE FROM profiles WHERE telegram_id=?", (telegram_id,))
conn.commit()
# функция для создания мероприятия
def create_event(name, cost, date, description, category):
cursor.execute("INSERT INTO events (type, name, cost, date, time, description, link) VALUES (?, ?, ?, ?, ?, ?, ?)",
(category, name, cost, date, '00:00', description))
conn.commit()
# Функция для получения случайного мероприятия
def get_random_event():
cursor.execute("SELECT * FROM events WHERE link IS NOT NULL ORDER BY RANDOM() LIMIT 1")
return cursor.fetchone()
# Функция для получения мероприятий по категории
def get_events_by_category(category):
cursor.execute("SELECT * FROM events WHERE type=? AND link IS NOT NULL LIMIT 1", (category,))
return cursor.fetchall()
# функция для проверки наличия анкеты пользователя
def check_registration(telegram_id):
cursor.execute("SELECT * FROM profiles WHERE telegram_id=?", (telegram_id,))
return cursor.fetchone() is not None
@bot.message_handler(func=lambda message: message.text == 'Выбрать мероприятие вручную')
def handle_manual_event_selection(message):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
btn1 = types.KeyboardButton("КИНО")
btn2 = types.KeyboardButton("ВЫСТАВКА")
btn3 = types.KeyboardButton("ТЕАТР")
btn4 = types.KeyboardButton("Вернуться в главное меню")
markup.add(btn1, btn2, btn3, btn4)
bot.send_message(message.chat.id, "Выберите тип мероприятия", reply_markup=markup)
# функция для обработки команды /start
@bot.message_handler(commands=['start'])
def start(message):
# проверяем наличие анкеты пользователя
if check_registration(message.chat.id):
profile = get_profile(message.chat.id)
name, social_link, about = profile[2], profile[3], profile[4]
text = f'Имя: {name}\nСсылка на соцсеть: {social_link}\nО себе: {about}'
bot.send_message(message.chat.id, text)
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
btn1 = types.KeyboardButton('Моя анкета')
btn2 = types.KeyboardButton('Удалить анкету')
btn3 = types.KeyboardButton('Случайное мероприятие')
btn4 = types.KeyboardButton('Выбрать мероприятие вручную')
markup.add(btn1, btn2, btn3, btn4)
bot.send_message(message.chat.id, 'Выбери действие:', reply_markup=markup)
else:
# отправляем сообщение приветствия
bot.send_message(message.chat.id, 'Привет! Нажми на кнопку "Зарегистрироваться", чтобы создать свою анкету.')
markup = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard = True)
markup.add(types.KeyboardButton('Зарегистрироваться'))
bot.send_message(message.chat.id, 'Выбери действие:', reply_markup=markup)
# функция для обработки регистрации пользователя
@bot.message_handler(func=lambda message: message.text == 'Зарегистрироваться')
def register(message):
# запрашиваем у пользователя необходимую информацию для анкеты
bot.send_message(message.chat.id, 'Введите ваше имя:')
bot.register_next_step_handler(message, get_name)
# функция для получения имени пользователя
def get_name(message):
name = message.text
# запрашиваем у пользователя ссылку на социальную сеть
bot.send_message(message.chat.id, 'Введите ссылку на свою страницу в социальной сети:')
bot.register_next_step_handler(message, get_social_link, name)
# функция для получения ссылки на социальную сеть
def get_social_link(message, name):
social_link = message.text
# запрашиваем у пользователя информацию о себе
bot.send_message(message.chat.id, 'Расскажите немного о себе:')
bot.register_next_step_handler(message, get_about, name, social_link)
# функция для получения информации о пользователе
def get_about(message, name, social_link):
about = message.text
telegram_id = message.chat.id
# создаем анкету пользователя
create_profile(telegram_id, name, social_link, about)
bot.send_message(message.chat.id, 'Ваша анкета успешно создана!')
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
btn1 = types.KeyboardButton('Моя анкета')
btn2 = types.KeyboardButton('Удалить анкету')
btn3 = types.KeyboardButton('Случайное мероприятие')
btn4 = types.KeyboardButton('Выбрать мероприятие вручную')
markup.add(btn1, btn2, btn3, btn4)
bot.send_message(message.chat.id, 'Выбери действие:', reply_markup=markup)
# функция для обработки запроса моей анкеты
@bot.message_handler(func=lambda message: message.text == 'Моя анкета')
def get_my_profile(message):
telegram_id = message.chat.id
profile = get_profile(telegram_id)
# если анкета существует, отправляем информацию о ней пользователю
if profile:
name, social_link, about = profile[2], profile[3], profile[4]
text = f'Имя: {name}\n Ссылка на соцсеть: {social_link}\n О себе: {about}'
bot.send_message(message.chat.id, text)
else:
bot.send_message(message.chat.id, 'Вы еще не создали анкету.')
# функция для обработки запроса удаления анкеты
@bot.message_handler(func=lambda message: message.text == 'Удалить анкету')
def delete_my_profile(message):
telegram_id = message.chat.id
delete_profile(telegram_id)
bot.send_message(message.chat.id, 'Анкета успешно удалена!')
# переходим на этап регистрации
start(message)
# добавляем оператор return, чтобы не выполнять последующий код
return
# функция для обработки запроса случайного мероприятия
@bot.message_handler(func=lambda message: message.text == 'Случайное мероприятие')
def random_event_handler(message):
telegram_id = message.chat.id
event = get_random_event()
if event:
name, cost, date, description, link = event[2], event[3], event[4], event[6], event[7]
text = f'Название: {name}\nСтоимость: {cost}\nДата: {date}\nОписание: {description}'
markup = types.InlineKeyboardMarkup()
btn = types.InlineKeyboardButton(text='Купить билет', url=link)
markup.add(btn)
bot.send_message(message.chat.id, text, reply_markup=markup)
else:
bot.send_message(message.chat.id, 'В базе данных нет мероприятий.')
# Обработка нажатий на кнопки
@bot.message_handler(func=lambda message: message.text == 'КИНО')
def handle_cinema_events(message):
events = get_events_by_type('КИНО')
if len(events) == 0:
bot.send_message(message.chat.id, "Нет мероприятий типа 'КИНО'")
else:
event_index = 0
send_event(message.chat.id, events, event_index)
for event in events:
name, cost, date, description, link = event[2], event[3], event[4], event[6], event[7]
text = f'Название: {name}\nСтоимость: {cost}\nДата: {date}\nОписание: {description}'
markup = types.InlineKeyboardMarkup()
btn = types.InlineKeyboardButton(text='Купить билет', url=link)
markup.add(btn)
bot.send_message(message.chat.id, text, reply_markup=markup)
bot.send_message(message.chat.id, text)
@bot.message_handler(func=lambda message: message.text == 'ВЫСТАВКА')
def handle_exhibition_events(message):
events = get_events_by_type('ВЫСТАВКА')
if len(events) == 0:
bot.send_message(message.chat.id, "Нет мероприятий типа 'ВЫСТАВКА'")
else:
event_index = 0
send_event(message.chat.id, events, event_index)
for event in events:
name, cost, date, description, link = event[2], event[3], event[4], event[6], event[7]
text = f'Название: {name}\nСтоимость: {cost}\nДата: {date}\nОписание: {description}'
markup = types.InlineKeyboardMarkup()
btn = types.InlineKeyboardButton(text='Купить билет', url=link)
markup.add(btn)
bot.send_message(message.chat.id, text, reply_markup=markup)
@bot.message_handler(func=lambda message: message.text == 'ТЕАТР')
def handle_theatre_events(message):
events = get_events_by_type('ТЕАТР')
if len(events) == 0:
bot.send_message(message.chat.id, "Нет мероприятий типа 'ТЕАТР'")
else:
event_index = 0
send_event(message.chat.id, events, event_index)
for event in events:
name, cost, date, description, link = event[2], event[3], event[4], event[6], event[7]
text = f'Название: {name}\nСтоимость: {cost}\nДата: {date}\nОписание: {description}'
markup = types.InlineKeyboardMarkup()
btn = types.InlineKeyboardButton(text='Купить билет', url=link)
markup.add(btn)
bot.send_message(message.chat.id, text, reply_markup=markup)
@bot.message_handler(func=lambda message: message.text == 'Вернуться в главное меню')
def handle_back_to_main_menu(message):
start(message)
# # Создать глобальную переменную для хранения текущих списков мероприятий по категориям
# current_events = {}
# def get_events_by_category(category):
# global current_events
# if category in current_events:
# return current_events[category]
# cursor.execute("SELECT * FROM events WHERE type=? AND link IS NOT NULL", (category,))
# events = cursor.fetchall()
# current_events[category] = events
# return events
def send_event(chat_id, events, event_index):
if len(events) == 0:
bot.send_message(chat_id, 'Нет доступных мероприятий.')
return
event_index = event_index % len(events)
event = events[event_index]
name, cost, date, description, link = event[2], event[3], event[4], event[6], event[7]
text = f'Название: {name}\nСтоимость: {cost}\nДата: {date}\nОписание: {description}'
markup = telebot.types.InlineKeyboardMarkup()
prev_btn = telebot.types.InlineKeyboardButton(text='<', callback_data=f'prev_{event_index}')
next_btn = telebot.types.InlineKeyboardButton(text='>', callback_data=f'next_{event_index}')
markup.row(prev_btn, next_btn)
btn = telebot.types.InlineKeyboardButton(text='Перейти к мероприятию', url=link)
markup.add(btn)
bot.send_message(chat_id, text, reply_markup=markup)
# # Обработка нажатий на кнопки "<" и ">"
# @bot.callback_query_handler(func=lambda call: call.data.startswith(('prev_', 'next_')))
# def handle_navigation_buttons(call):
# chat_id = call.message.chat.id
# category = call.message.text.split('\n')[0].split(': ')[1]
# event_index = int(call.data.split('_')[1])
# events = get_events_by_category(category)
# if len(events) == 0:
# bot.send_message(chat_id, 'Нет доступных мероприятий.')
# return
# if call.data.startswith('prev_'):
# event_index -= 1
# elif call.data.startswith('next_'):
# event_index += 1
# send_event(chat_id, events, event_index)
bot.polling(none_stop=True, interval=0)