Files
bot-telegram/bot2.py
2025-09-14 17:30:02 +05:00

177 lines
6.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command, StateFilter
from aiogram.fsm.state import State, StatesGroup
from aiogram.fsm.context import FSMContext
from aiogram.fsm.storage.memory import MemoryStorage
from aiogram.types import KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove
import psycopg2
import psycopg2.extras
from datetime import datetime
import os
from aiogram.types import FSInputFile
TOKEN = "ВАШ_TOKEN"
bot = Bot(token=TOKEN)
dp = Dispatcher(storage=MemoryStorage())
# ===== FSM =====
class Form(StatesGroup):
consent = State()
fio = State()
dob = State()
phone = State()
city = State()
klimov = State()
@dp.message(Command("start"))
async def start(message: types.Message, state: FSMContext):
kb = [[KeyboardButton("✅ Да, согласен"), KeyboardButton("❌ Нет")]]
keyboard = ReplyKeyboardMarkup(keyboard=kb, resize_keyboard=True)
await message.answer(
"Привет! Сначала нужно согласие на обработку персональных данных. Согласны?",
reply_markup=keyboard
)
await state.set_state(Form.consent)
@dp.message(Form.consent)
async def consent(message: types.Message, state: FSMContext):
if message.text.startswith(""):
await state.set_state(Form.fio)
await message.answer("Введите своё ФИО:", reply_markup=ReplyKeyboardRemove())
else:
await message.answer("Без согласия мы не можем продолжить 🙏", reply_markup=ReplyKeyboardRemove())
await state.clear()
@dp.message(Form.fio)
async def fio(message: types.Message, state: FSMContext):
await state.update_data(fio=message.text)
await state.set_state(Form.dob)
await message.answer("Введите дату рождения (ДД.MM.ГГГГ):")
@dp.message(Form.dob)
async def dob(message: types.Message, state: FSMContext):
await state.update_data(dob=message.text)
await state.set_state(Form.phone)
await message.answer("Введите номер телефона:")
@dp.message(Form.phone)
async def phone(message: types.Message, state: FSMContext):
await state.update_data(phone=message.text)
await state.set_state(Form.city)
await message.answer("Из какого ты города?")
@dp.message(Form.city)
async def city(message: types.Message, state: FSMContext):
await state.update_data(city=message.text)
data = await state.get_data()
# Сохраняем в БД
try:
dob_parsed = datetime.strptime(data["dob"], "%d.%m.%Y").date()
except ValueError:
await message.answer("Неверный формат даты. Введите ДД.MM.ГГГГ")
await state.set_state(Form.dob)
return
conn = psycopg2.connect(dbname="botdb", user="botuser", password="tpg44dm*oOas&2geWc^Paw7")
cur = conn.cursor()
cur.execute("""
INSERT INTO users (telegram_id, fio, dob, phone, city)
VALUES (%s,%s,%s,%s,%s)
ON CONFLICT (telegram_id) DO UPDATE
SET fio=EXCLUDED.fio, dob=EXCLUDED.dob, phone=EXCLUDED.phone, city=EXCLUDED.city
""", (message.from_user.id, data["fio"], dob_parsed, data["phone"], data["city"]))
conn.commit()
cur.close()
conn.close()
kb = [[KeyboardButton("📘 Тест Климова")]]
keyboard = ReplyKeyboardMarkup(keyboard=kb, resize_keyboard=True)
await state.clear()
await message.answer("Анкета сохранена ✅ Выберите тест:", reply_markup=keyboard)
@dp.message(StateFilter(None))
async def select_test(message: types.Message, state: FSMContext):
if message.text == "📘 Тест Климова":
conn = psycopg2.connect(dbname="botdb", user="botuser", password="ваш_пароль")
cur = conn.cursor()
cur.execute("SELECT id, text1, category1, text2, category2, image FROM klimov_questions ORDER BY id")
questions = cur.fetchall()
cur.close()
conn.close()
await state.update_data(klimov_questions=questions, klimov_index=0, klimov_result={})
await state.set_state(Form.klimov)
await send_klimov_question(message.from_user.id, state)
else:
await message.answer("Пока этот тест не реализован.")
async def send_klimov_question(user_id, state: FSMContext):
data = await state.get_data()
index = data.get("klimov_index", 0)
questions = data.get("klimov_questions", [])
if index >= len(questions):
await send_klimov_result(user_id, state)
await state.clear()
return
q = questions[index]
kb = [[KeyboardButton(q[1])], [KeyboardButton(q[3])]]
keyboard = ReplyKeyboardMarkup(keyboard=kb, resize_keyboard=True)
image_path = q[5]
if image_path and os.path.exists(image_path):
photo = FSInputFile(image_path)
await bot.send_photo(
chat_id=user_id,
photo=photo,
caption=f"Вопрос {index+1} из {len(questions)}:\nВыберите вариант",
reply_markup=keyboard
)
return
await bot.send_message(
chat_id=user_id,
text=f"Вопрос {index+1} из {len(questions)}:\nВыберите вариант",
reply_markup=keyboard
)
@dp.message(Form.klimov)
async def klimov_answer(message: types.Message, state: FSMContext):
data = await state.get_data()
index = data["klimov_index"]
questions = data["klimov_questions"]
result = data["klimov_result"]
q = questions[index]
if message.text == q[1]:
result[q[2]] = result.get(q[2], 0) + 1
elif message.text == q[3]:
result[q[4]] = result.get(q[4], 0) + 1
index += 1
await state.update_data(klimov_index=index, klimov_result=result)
await send_klimov_question(message.from_user.id, state)
async def send_klimov_result(user_id, state: FSMContext):
data = await state.get_data()
result = data.get("klimov_result", {})
questions = data.get("klimov_questions", [])
if not questions:
await bot.send_message(user_id, "Вы не ответили ни на один вопрос.")
return
max_points = {}
for q in questions:
max_points[q[2]] = max_points.get(q[2], 0) + 1
max_points[q[4]] = max_points.get(q[4], 0) + 1
output = "Ваши результаты:\n"
for cat, max_pt in max_points.items():
pts = result.get(cat, 0)
percent = (pts / max_pt) * 100
output += f"- {cat}: {percent:.1f}%\n"
if result:
top_cat = max(result, key=result.get)
output += f"\nТип профессии: {top_cat}"
await bot.send_message(user_id, output, reply_markup=ReplyKeyboardRemove())