типо да

This commit is contained in:
admin
2025-09-08 00:40:18 +07:00
commit 0f05fc8455
83 changed files with 5775 additions and 0 deletions

15
bot/handlers/__init__.py Normal file
View File

@@ -0,0 +1,15 @@
from aiogram import Router
#from .commands import router as cmd_routers
from .messages import router as messages_routers
from .secret import router as secret_routers
# Настройка экспорта и роутера
__all__ = ("router",)
router: Router = Router(name=__name__)
# Подключение роутеров
router.include_routers(
#cmd_routers,
secret_routers,
messages_routers,
)

View File

@@ -0,0 +1,13 @@
from aiogram import Router
from .admins import router as admin_cmd_router
from .users import router as users_cmd_router
# Настройка экспорта и роутера
__all__ = ("router",)
router: Router = Router(name=__name__)
# Подключение роутеров
router.include_routers(
admin_cmd_router,
users_cmd_router,
)

View File

@@ -0,0 +1,11 @@
from aiogram import Router
from .settings_cmd import router as settings_cmd_router
# Настройка экспорта и роутера
__all__ = ("router",)
router: Router = Router(name=__name__)
# Подключение роутеров
router.include_routers(
settings_cmd_router,
)

View File

@@ -0,0 +1,51 @@
from aiogram import Router, F
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.types import Message, CallbackQuery, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiogram.utils.i18n import gettext as _
from bot.templates import msg_photo
from bot.utils.interesting_facts import interesting_fact
from bot.core.bots import BotInfo
from configs import COMMANDS, RpValue
# Настройки экспорта и роутера
__all__ = ("router",)
CMD: str = "settings".lower()
router: Router = Router(name=f"{CMD}_cmd_router")
@router.callback_query(F.data.lower() == CMD)
@router.message(Command(*COMMANDS[CMD], prefix=BotInfo.prefix, ignore_case=True))
async def start_cmd(message: Message | CallbackQuery, state: FSMContext) -> None:
"""Обработчик команды /start"""
await state.clear()
# Создание инлайн-клавиатуры
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Инфо-канал🗂", url=RpValue.INFO_URL))
ikb.row(InlineKeyboardButton(text="Вступление🚀", callback_data='new'),
InlineKeyboardButton(text="Анкета📖", callback_data='anketa'))
ikb.row(InlineKeyboardButton(text="Связь с администрацией🌐", callback_data='admin'))
# Формируем приветственное сообщение
text: str = _(
"""Добро пожаловать, <a href="{url}">{name}</a>!
Я ваш искусственный помощник по ролевой - <b>{rp_name}</b>!
Моя цель — помочь вам сориентироваться и сделать ваше вступление куда проще!
Надеюсь, я смогу вам помочь! Пожалуйста, выберите нужную функцию на клавиатуре!
Интересный факт:
<blockquote>{fact}</blockquote>
"""
).format(
url=message.from_user.url if message.from_user else "",
name=message.from_user.first_name if message.from_user else "пользователь",
rp_name=RpValue.RP_NAME,
fact=interesting_fact(),
)
# Отправляем сообщение
await msg_photo(message=message, text=text, file=f'assets/{CMD}.jpg', markup=ikb)

View File

@@ -0,0 +1,13 @@
from aiogram import Router
from .start_cmd import router as start_cmd_router
from .active import router as active_cmd_router
# Настройка экспорта и роутера
__all__ = ("router",)
router: Router = Router(name=__name__)
# Подключение роутеров
router.include_routers(
start_cmd_router,
active_cmd_router,
)

View File

@@ -0,0 +1,45 @@
from aiogram import Router, F
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.types import Message, CallbackQuery
from bot.templates import msg_photo
from bot.core.bots import BotInfo
from configs import COMMANDS
from database import db
# Настройки экспорта и роутера
__all__ = ("router",)
CMD: str = "active".lower()
router: Router = Router(name=f"{CMD}_cmd_router")
@router.callback_query(F.data.lower() == CMD)
@router.message(Command(*COMMANDS[CMD], prefix=BotInfo.prefix, ignore_case=True))
async def active_cmd(message: Message | CallbackQuery, state: FSMContext) -> None:
"""Обработчик команды /active"""
await state.clear()
# Получить статистику сообщений пользователя
day, week, month, total = await db.get_message_stats(message.from_user.id)
print(f"За день: {day} сообщений")
print(f"За неделю: {week} сообщений")
print(f"За месяц: {month} сообщений")
print(f"Всего: {total} сообщений")
# Формируем приветственное сообщение
text: str =f"""
За день: {day} сообщений
За неделю: {week} сообщений
За месяц: {month} сообщений
Всего: {total} сообщений
"""
# Отправляем сообщение
await msg_photo(message=message, text=text,)

View File

@@ -0,0 +1,218 @@
import re
from typing import Optional, Dict, Tuple
from aiogram import Router, F
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.types import Message, CallbackQuery, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiogram.utils.i18n import gettext as _
from bot.core.bots import BotInfo
from bot.keyboards.inline.decision import decision_keyboard
from bot.states.new_states import NewStates
from bot.templates import msg
from middleware.loggers import log
from configs import COMMANDS, ImportantID, RpValue
# Глобальная мапа для хранения связей пользователь-топик
user_topic_map: Dict[Tuple[int, str], int] = {}
__all__ = ("router",)
CMD: str = "new"
router: Router = Router(name=f"{CMD}_cmd_router")
TOPIC_TYPE: str = "anketa"
TEXTS: Dict[str, Dict[str, str]] = {
"anketa": {
"accept": f"<b>🎉 Ваша анкета принята!</b>\n\nДобро пожаловать в проект!\n\nФлуд: {RpValue.FLUD_URL}\nРолевая: {RpValue.RP_URL}",
"reject": "<b>❌ Ваша анкета отклонена.</b>\n\nВы можете попробовать позже."
}
}
async def validate_russian_text(text: str) -> bool:
"""Проверяет текст на соответствие русским буквам, пробелам и дефисам."""
return bool(re.fullmatch(r"[А-Яа-яЁё\s\-]+", text))
# ===================== Команда /new =====================
@router.callback_query(F.data == CMD)
@router.message(Command(*COMMANDS[CMD], prefix=BotInfo.prefix, ignore_case=True))
@log(level='INFO', log_type=CMD.upper(), text=f"использовал команду /{CMD}")
async def new_cmd(message: Message | CallbackQuery, state: FSMContext) -> None:
"""
Начало анкеты /new.
Отправляет пользователю сообщение с просьбой указать желаемую роль.
"""
await state.clear()
await state.set_state(NewStates.role)
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Отмена↩️", callback_data='start'))
text: str = _(
"Пожалуйста, отправьте желаемую роль:\n"
"(только русские буквы, пробелы или дефисы)"
)
await msg(message=message, text=text, markup=ikb)
# ===================== Обработка роли =====================
@router.message(NewStates.role)
async def process_role(message: Message, state: FSMContext) -> None:
"""Обрабатывает ввод роли и запрашивает сортол."""
if not await validate_russian_text(message.text):
await message.reply("Ошибка: роль должна содержать только русские буквы, пробелы или дефисы.")
return
await state.update_data(role=message.text.strip().title())
await state.set_state(NewStates.sorol)
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Отмена↩️", callback_data='start'))
await message.reply(
text="Теперь укажите желаемый сортол:\n(только русские буквы, пробелы или дефисы)",
reply_markup=ikb.as_markup()
)
# ===================== Обработка сортола =====================
@router.message(NewStates.sorol)
async def process_sortol(message: Message, state: FSMContext) -> None:
"""Обрабатывает ввод сортола и запрашивает кодовую фразу."""
if not await validate_russian_text(message.text):
await message.reply("Ошибка: сорол должен содержать только русские буквы, пробелы или дефисы.")
return
await state.update_data(sortol=message.text.strip().title())
await state.set_state(NewStates.code_phrase)
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Отмена↩️", callback_data='start'))
await message.reply(
text="Теперь введите кодовую фразу из правил:",
reply_markup=ikb.as_markup()
)
# ===================== Обработка кодовой фразы =====================
@router.message(NewStates.code_phrase)
async def process_code_phrase(message: Message, state: FSMContext) -> None:
"""Обрабатывает ввод кодовой фразы и показывает предпросмотр анкеты."""
code_phrase = message.text.strip()
if not code_phrase:
await message.reply("Кодовая фраза не может быть пустой.")
return
await state.update_data(code_phrase=code_phrase)
data: Dict[str, str] = await state.get_data()
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(
InlineKeyboardButton(text="Отправить!", callback_data="submit_new"),
InlineKeyboardButton(text="Отмена↩️", callback_data="start")
)
text: str = (
f"<b>Проверьте данные анкеты:</b>\n\n"
f"• Роль: {data['role']}\n"
f"• Сортол: {data['sortol']}\n"
f"• Кодовая фраза: {data['code_phrase']}"
)
await message.reply(text, reply_markup=ikb.as_markup())
# ===================== Отправка анкеты в поддержку =====================
@router.callback_query(F.data == "submit_new")
async def submit_new_cmd(callback: CallbackQuery, state: FSMContext) -> None:
"""Отправляет анкету в топик форума поддержки и создает запись в мапе."""
data: Dict[str, str] = await state.get_data()
user = callback.from_user
# Создаем топик в форуме
topic = await callback.bot.create_forum_topic(
chat_id=ImportantID.SUPPORT_CHAT_ID,
name=f"Анкета от {user.full_name}"
)
thread_id: int = topic.message_thread_id
# Сохраняем связь пользователь-топик
user_topic_map[(user.id, TOPIC_TYPE)] = thread_id
# Формируем текст анкеты
text: str = (
f'<b><a href="tg://user?id={user.id}">Анкета</a></b>\n\n'
f"• Роль: {data['role']}\n"
f"• Сортол: {data['sortol']}\n"
f"• Кодовая фраза: {data['code_phrase']}"
)
# Отправляем в топик с кнопками принятия/отклонения
await callback.bot.send_message(
chat_id=ImportantID.SUPPORT_CHAT_ID,
message_thread_id=thread_id,
text=text,
parse_mode="HTML",
reply_markup=decision_keyboard(thread_id=thread_id, kind=TOPIC_TYPE)
)
await callback.message.edit_text("✅ Ваша анкета успешно отправлена на рассмотрение!")
await state.clear()
# ===================== Обработка решения админов =====================
@router.callback_query(F.data.regexp(r"^([a-z_]+):(accept|reject):(\d+)$"))
async def process_decision_callback(callback: CallbackQuery) -> None:
"""Обрабатывает решение администраторов и отправляет результат пользователю."""
kind, action, thread_id_str = callback.data.split(":")
thread_id = int(thread_id_str)
# Ищем пользователя по thread_id в мапе
user_id = None
for (uid, k), tid in user_topic_map.items():
if k == kind and tid == thread_id:
user_id = uid
break
if not user_id:
await callback.answer("Пользователь не найден.", show_alert=True)
return
text_to_send: Optional[str] = TEXTS.get(kind, {}).get(action)
if not text_to_send:
await callback.answer("Некорректные данные.", show_alert=True)
return
await callback.bot.send_message(chat_id=user_id, text=text_to_send, parse_mode="HTML")
await callback.message.edit_reply_markup(reply_markup=None)
await callback.answer("Ответ отправлен пользователю.")
# ===================== Пересылка ответов админов пользователю =====================
@router.message(F.is_topic_message, F.reply_to_message, ~F.from_user.is_bot)
async def forward_reply_to_user(message: Message) -> None:
"""Пересылает ответы администраторов из топика пользователю."""
thread_id = message.message_thread_id
if not thread_id:
return
# Ищем пользователя по thread_id
user_id = None
for (uid, _), tid in user_topic_map.items():
if tid == thread_id:
user_id = uid
break
if not user_id:
return
reply_text: str = f"<b>Ответ администратора:</b>\n{message.html_text}"
try:
await message.bot.send_message(chat_id=user_id, text=reply_text, parse_mode="HTML")
except Exception as e:
await message.reply(f"⚠️ Не удалось отправить сообщение пользователю: {e}")

View File

@@ -0,0 +1,51 @@
from aiogram import Router, F
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.types import Message, CallbackQuery, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiogram.utils.i18n import gettext as _
from bot.templates import msg_photo
from bot.utils.interesting_facts import interesting_fact
from bot.core.bots import BotInfo
from configs import COMMANDS, RpValue
# Настройки экспорта и роутера
__all__ = ("router",)
CMD: str = "start".lower()
router: Router = Router(name=f"{CMD}_cmd_router")
@router.callback_query(F.data.lower() == CMD)
@router.message(Command(*COMMANDS[CMD], prefix=BotInfo.prefix, ignore_case=True))
async def start_cmd(message: Message | CallbackQuery, state: FSMContext) -> None:
"""Обработчик команды /start"""
await state.clear()
# Создание инлайн-клавиатуры
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Инфо-канал🗂", url=RpValue.INFO_URL))
ikb.row(InlineKeyboardButton(text="Вступление🚀", callback_data='new'),
InlineKeyboardButton(text="Анкета📖", callback_data='anketa'))
ikb.row(InlineKeyboardButton(text="Связь с администрацией🌐", callback_data='admin'))
# Формируем приветственное сообщение
text: str = _(
"""Добро пожаловать, <a href="{url}">{name}</a>!
Я ваш искусственный помощник по ролевой - <b>{rp_name}</b>!
Моя цель — помочь вам сориентироваться и сделать ваше вступление куда проще!
Надеюсь, я смогу вам помочь! Пожалуйста, выберите нужную функцию на клавиатуре!
Интересный факт:
<blockquote>{fact}</blockquote>
"""
).format(
url=message.from_user.url if message.from_user else "",
name=message.from_user.first_name if message.from_user else "пользователь",
rp_name=RpValue.RP_NAME,
fact=interesting_fact(),
)
# Отправляем сообщение
await msg_photo(message=message, text=text, file=f'assets/{CMD}.jpg', markup=ikb)

View File

@@ -0,0 +1,15 @@
from aiogram import Router
from .default import router as default_message_router
from .reply_msg import router as reply_message_router
# Настройка экспорта и роутера
__all__ = ('router',)
router: Router = Router(name=__name__)
# Подготовка роутера команд
#router.include_routers(
#reply_message_router,
#)
# Подключение стандартного роутера
router.include_router(default_message_router)

View File

@@ -0,0 +1,139 @@
from typing import Dict, List
from aiogram import Router
from aiogram.fsm.context import FSMContext
from aiogram.types import Message
from bot.utils import get_best_response
# Настройка экспорта и роутера
__all__ = ("router",)
router: Router = Router(name="message_router")
# === Словарь ключевых слов (синонимы) и возможных ответов ===
RESPONSES: Dict[str, Dict[str, List[str]]] = {
"док": {
"keywords": ["доктор", "док", "дотторе", "зандик"],
"answers": [
"Дотторе довольно милый друг! Мне нравится проводить с ним время!",
"Иногда он бывает слишком суровым... Но я верю, что смогу его перевоспитать!",
"Мне иногда кажется, что он знает больше историй, чем хранится в библиотеке!",
"Дотторе говорит загадками... а я всё равно не всегда понимаю!",
"Он умный, но я уверен — внутри он добрый!",
"Дотторе иногда ворчит, но всё равно заботится обо мне по-своему!",
"Он часто думает о науке... а я думаю о печеньках!",
"Мне кажется, он притворяется злым, а на самом деле просто боится дружбы.",
"Когда он работает, в комнате становится тихо... даже огонь боится мешать ему.",
"Я иногда думаю... а улыбается ли он, когда меня не видит?",
],
},
"ара": {
"keywords": ["ара", "аранара", "аранары", "ары", "кто ты", "ты кто"],
"answers": [
"Мы, аранары, очень любим веселиться и смеяться!",
"Хи-хи! 🌱 Ты можешь звать меня Ари!",
"Наш народ живёт уже тысячи лет... но мы не умеем считать!",
"Я маленький грибочек, но у меня большое сердце!",
"Аранара — это хранитель улыбок и весёлых историй!",
"Я люблю играть с детьми и рассказывать им истории!",
"Говорят, что аранары видят то, что скрыто от других.",
"Я — часть этой библиотеки, её дыхание и её смех!",
"Аранара — это маленький проводник в мир грёз и чудес.",
"Мы появляемся там, где нужен друг, даже если никто не звал!",
],
},
"малыш": {
"keywords": ["малыш", "девочка", "малышка", "она", "болезнь"],
"answers": [
"Она милая девочка! Жаль, что больна!",
"Она обожает сказки! Может, именно поэтому засыпает так сладко.",
"А как её зовут?.. Я всегда забываю спросить!",
"Иногда во сне она улыбается... значит, ей снятся хорошие истории.",
"Дотторе грустит, когда смотрит на неё... но я верю, он её спасёт!",
"Она словно светильник в тёмной комнате... даже если свет её тускнеет.",
"Я думаю, её мечты сильнее болезни.",
],
},
"эфир": {
"keywords": ["эфир", "проект", "изобретение", "сплав", "эксперимент", "ядро"],
"answers": [
"Эфир звучит как ветер, который нельзя поймать... но можно почувствовать!",
"Дотторе часто говорит о проектах, но я понимаю в них только половину!",
"Каждый новый сплав для него как новая история для меня.",
"Эксперимент — это как игра, только иногда она пахнет гарью...",
"Я слышал, что ядро может изменить всё... даже судьбы людей.",
"В лаборатории так много звуков — шипение кислот, стук молотов, шёпот формул.",
"Иногда мне кажется, что изобретения Дотторе живут своей жизнью...",
"Эфир? Кефир? ЗЕФИР!",
],
},
"мысль": {
"keywords": ["мысл", "мысль", "мысли", "думаешь"],
"answers": [
"О чём я думаю?.. Иногда о печеньках!",
"Голова как будто полная тумана...",
"Кажется, я что-то забыл... но не могу вспомнить...",
"Мысли приходят и уходят, как маленькие птички.",
"А ты когда-нибудь задумывался, откуда приходят мысли?",
"Иногда мои мысли путаются и превращаются в сказки.",
"Я думаю, что думать — это тяжело... лучше веселиться!",
"Может, мысли — это просто шёпот библиотеки в моей голове?",
"Когда я думаю слишком долго — у меня начинает чесаться макушка!",
"Мысли — как облака... смотришь, и они уже другие.",
],
},
"тайн": {
"keywords": ["тайн", "тайны", "тайну", "тайна"],
"answers": [
"Тайны? О-о, мы играем в детективов?!",
"Я знаю много секретов... но не все можно рассказывать!",
"Иногда самые большие тайны прячутся на виду.",
"Тайна — это как закрытая книга. Ты хочешь открыть её?",
"Хи-хи... а если твоя тайна уже записана в библиотеке?",
"Некоторые тайны лучше хранить, чем раскрывать.",
"Каждый друг — это тоже тайна, которую мы открываем постепенно.",
"А твои секреты я храню надёжнее любого сундука!",
"Тайна — это искра любопытства! Без неё жизнь скучная.",
"Ш-ш-ш... хочешь услышать одну маленькую, но очень смешную тайну?",
],
},
}
# === Случайные фразы, если совпадения нет ===
RANDOM_PHRASES: List[str] = [
"Я Ари! Компаньон Дотторе и ваш лучший друг! Можете обращаться ко мне!",
"Я живу здесь уже десятки лет... и мне всё ещё весело!",
"Кхм... почему ты так странно разговариваешь? Ничего не понимаю!",
"Мы играем в шарады? Давай попробуй ещё раз, может я пойму хоть одно слово!",
"Ты кажешься таким загадочным... прямо как проекты Дотторе, которые меня вечно пугают!",
"Ой! Ты меня напугал! Но всё равно приятно видеть нового друга!",
"Если вдруг станет грустно — просто обними аранару. Мы очень мягкие!",
"Иногда даже мне хочется спрятаться между колб и подремать...",
"А может, именно твоё слово станет началом новой истории?",
"Дотторе говорит, что я слишком болтлив... а разве это плохо?",
"Ты такой серьёзный... может, стоит немного пошутить?",
"Иногда кажется, что слова сами выбирают нас, а не мы их!",
]
# === Хэндлеры ===
@router.message()
async def handle_message(message: Message, state: FSMContext) -> None:
"""
Обрабатывает входящие сообщения от пользователя.
Определяет ответ по ключевым словам или случайную фразу.
:param message: объект сообщения
:param state: FSMContext для работы с состояниями
"""
await state.clear()
response: str = get_best_response(
message.text or "",
responses=RESPONSES,
random_phrases=RANDOM_PHRASES,
)
await message.answer(text=response)

View File

@@ -0,0 +1,39 @@
from random import choice
from typing import List
from aiogram import Router
from aiogram.fsm.context import FSMContext
from aiogram.types import Message
router: Router = Router(name="reply_router")
RANDOM_PHRASES: List[str] = [
"Бла-бла-бла!", "Хва-а-а-тит!", "Серьёзно? 😏", "Опять ты это говоришь...",
"Хи-хи, смешно же!", "Ты снова шутник?", "Я уже слышал это раньше!", "Эй, не надо так!",
"Ладно, ладно, хватит!", "Хмм... интересно...", "Ты меня удивляешь!", "А давай лучше что-то новое?",
"Не могу поверить!", "Ахаха, это забавно!", "Серьёзно? Ну ладно...", "Эй, это уже слишком!",
"О, это было неожиданно!",
]
@router.message()
async def reply_message(message: Message, state: FSMContext) -> None:
# Достаём данные из состояния
data = await state.get_data()
last_bot_text = data.get("last_bot_text", "")
# КРИТИЧЕСКИ ВАЖНО: Проверяем, что состояние не пустое после перезапуска.
# Если состояние пустое (например, после перезапуска), то мы НЕ должны считать,
if last_bot_text and message.text and message.text.strip() == last_bot_text.strip():
response = "Не повторяй за мной!"
else:
response = choice(RANDOM_PHRASES)
ids = message.message_id-1
print(str())
# Отправляем ответ и ПОЛУЧАЕМ ОБЪЕКТ ОТПРАВЛЕННОГО СООБЩЕНИЯ
sent_message = await message.reply(response)
# Сохраняем текст последнего сообщения бота в состоянии
# Теперь состояние будет обновлено после каждого сообщения бота
await state.update_data(last_bot_text=sent_message.text)

View File

@@ -0,0 +1,13 @@
from aiogram import Router
from .secret1 import router as secret1_router
#from .secret2 import router as secret2_router
# Настройка экспорта и роутера
__all__ = ('router',)
router: Router = Router(name=__name__)
# Подключение секретного роутера
router.include_routers(
secret1_router,
#secret2_router,
)

View File

@@ -0,0 +1,45 @@
from aiogram import Router, F
from aiogram.fsm.context import FSMContext
from aiogram.types import Message
from aiogram.utils.markdown import hide_link
from middleware.loggers import log
# Настройки экспорта и роутера
__all__ = ("router",)
router: Router = Router(name="secret_router")
CMD: str = "secret_1"
@router.message(F.text.lower() == "истинная цель короля всегда было мироздание")
@log(level='INFO', log_type=CMD.upper(), text=f"использовал команду /{CMD}")
async def secret1_cmd(message: Message, state: FSMContext) -> None:
"""Обработчик секретов"""
await state.clear()
# Формируем приветственное сообщение
text: str = f"""{hide_link("https://rp.primo.dpdns.org/wp-content/uploads/2025/08/1234567.png")}
<b><u>Запись №-...18</u></b>
<blockquote><i>Значит, этот </i><i><b>правда</b> действительно </i><i><b>существует…</b> Хах.. Хахахах! Я смог найти решение</i><i><b>! Я!! СМОГ!!!</b>
Все линии, пропорции, каждый слой металла и кристалла — всё сходится.
Сколько лет я </i><i><b>скитался</b> по лабораториям, библиотекам, ища этот след… а ведь всё это время </i><i><b>ключ</b> к моей цели лежал прямо перед глазами — на чертеже.</i></blockquote>
<blockquote><i>Получится ли у меня...?\n
Я создаю не просто броню. Я пытаюсь воплотить в материале замысел, который перевернёт всё, что мы знали.
Каждый слой, каждая руна — это шаг к воплощению моей идеи. Даже спустя десятки лет я помню, как возвращал из небытия те конструкции, что раньше казались невозможными…</i></blockquote>
<blockquote><i>Возможно ли, что сама структура материи и магии </i><i><b>изменит..</b>
Или же это моя броня станет первым устройством, способное изменить их мнение?..</i></blockquote>
<blockquote><i>И всё же один вопрос не даёт мне покоя: сможет ли этот замысел завершить то, что я задумал…
Станет ли моя броня инструментом, с помощью которого замысел воплотится в реальность?..</i></blockquote>
<blockquote><i>Пожалуй, придётся ещё раз вернуться к чертежам и проверить расчёты.
Что-то подсказывает мне: каждая линия, каждый символ на этом листе — это не просто металл и руны, это путь к моей великой… </i><i><b>идее</b>. ~</i></blockquote>
<tg-spoiler>Да… это оно. Всё ведёт к замыслу, к который я стремился десятилетиями…</tg-spoiler>"""
# Отправляем сообщение
await message.reply(text=text)

View File

@@ -0,0 +1,134 @@
from aiogram import Router, F
from aiogram.filters import Command, StateFilter
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.types import Message
# Создаем роутер
knowledge_router = Router()
# Определяем состояния
class KnowledgeStates(StatesGroup):
question1 = State()
question2 = State()
question3 = State()
question4 = State()
question5 = State()
question6 = State()
# Вопросы и ответы (замените на свои)
QUESTIONS = {
1: "Вопрос1",
2: "Вопрос2",
3: "Вопрос3",
4: "Вопрос4",
5: "Вопрос5",
6: "Вопрос6"
}
ANSWERS = {
1: {"Ответ 11": "СообщениеА1", "Ответ 12": "СообщениеБ1"},
2: {"Ответ 21": "СообщениеА2", "Ответ 22": "СообщениеБ2"},
3: {"Ответ 31": "СообщениеА3", "Ответ 32": "СообщениеБ3"},
4: {"Ответ 41": "СообщениеА4", "Ответ 42": "СообщениеБ4"},
5: {"Ответ 51": "СообщениеА5", "Ответ 52": "СообщениеБ5"},
6: {"Ответ 61": "СообщениеА6", "Ответ 62": "СообщениеБ6"}
}
FINAL_MESSAGES = {
"all_1": "ИТОГ1 - Все ответы первого типа!",
"all_2": "ИТОГ2 - Все ответы второго типа!",
"mixed": "ИТОГ1 - Смешанные ответы!"
}
# Запуск сессии знаний
@knowledge_router.message(StateFilter(None), Command("знания"))
@knowledge_router.message(StateFilter(None), F.text.casefold() == "пора заняться знаниями")
async def start_knowledge_session(message: Message, state: FSMContext):
await message.answer("Отлично! Начинаем сессию знаний! 🧠")
await message.answer(QUESTIONS[1])
await state.set_state(KnowledgeStates.question1)
await state.update_data(answers={})
# Обработчики для каждого вопроса
@knowledge_router.message(KnowledgeStates.question1, F.text.in_(ANSWERS[1].keys()))
async def process_question1(message: Message, state: FSMContext):
user_answer = message.text
response_message = ANSWERS[1][user_answer]
# Сохраняем ответ
answer_code = 1 if user_answer == "Ответ 11" else 2
await state.update_data(answers={"q1": answer_code})
# Отправляем сообщение и следующий вопрос
await message.answer(response_message + "\n\n" + QUESTIONS[2])
await state.set_state(KnowledgeStates.question2)
@knowledge_router.message(KnowledgeStates.question2, F.text.in_(ANSWERS[2].keys()))
async def process_question2(message: Message, state: FSMContext):
user_answer = message.text
response_message = ANSWERS[2][user_answer]
# Сохраняем ответ
answer_code = 1 if user_answer == "Ответ 21" else 2
data = await state.get_data()
answers = data.get("answers", {})
answers["q2"] = answer_code
await state.update_data(answers=answers)
# Отправляем сообщение и следующий вопрос
await message.answer(response_message + "\n\n" + QUESTIONS[3])
await state.set_state(KnowledgeStates.question3)
# Добавьте аналогичные обработчики для question3-question5
@knowledge_router.message(KnowledgeStates.question6, F.text.in_(ANSWERS[6].keys()))
async def process_question6(message: Message, state: FSMContext):
user_answer = message.text
response_message = ANSWERS[6][user_answer]
# Сохраняем ответ
answer_code = 1 if user_answer == "Ответ 61" else 2
data = await state.get_data()
answers = data.get("answers", {})
answers["q6"] = answer_code
await state.update_data(answers=answers)
# Отправляем финальное сообщение
await message.answer(response_message)
await finish_knowledge_session(message, state)
# Обработчики для некорректных ответов
@knowledge_router.message(KnowledgeStates.question1)
async def process_incorrect_answer1(message: Message):
await message.answer("Пожалуйста, выберите один из предложенных вариантов ответа.")
await message.answer(QUESTIONS[1])
@knowledge_router.message(KnowledgeStates.question2)
async def process_incorrect_answer2(message: Message):
await message.answer("Пожалуйста, выберите один из предложенных вариантов ответа.")
await message.answer(QUESTIONS[2])
# Добавьте аналогичные обработчики для остальных вопросов
# Завершение сессии
async def finish_knowledge_session(message: Message, state: FSMContext):
data = await state.get_data()
answers = data.get("answers", {})
# Проверяем результаты
if all(answer == 2 for answer in answers.values()):
await message.answer(FINAL_MESSAGES["all_2"])
else:
await message.answer(FINAL_MESSAGES["mixed"])
await state.clear()