First commit

This commit is contained in:
2026-01-23 04:45:55 +07:00
commit 0b251c5967
118 changed files with 9580 additions and 0 deletions

View File

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

View File

@@ -0,0 +1,42 @@
from aiogram import Router, F
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.types import Message, CallbackQuery
from bot.core.bots import BotInfo
from bot.templates import msg_photo
from bot.utils import status_clear
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 status_clear(message=message, state=state)
# Получить статистику сообщений пользователя
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,117 @@
from typing import Dict, Tuple
from aiogram import Router, F
from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.fsm.context import FSMContext
from bot.utils import status_clear
# -------------------
# Router
# -------------------
router: Router = Router(name="anon_router")
# -------------------
# Конфигурация
# -------------------
# CHAT_ID в формате "-100000_29" -> chat_id + thread_id
CHAT_ID: str = "-1003098225669_724"
def parse_chat_id(chat_id_str: str) -> Tuple[int, int]:
chat_str, thread_str = chat_id_str.split("_")
return int(chat_str), int(thread_str)
ADMIN_CHAT_ID, ADMIN_THREAD_ID = parse_chat_id(CHAT_ID)
# -------------------
# FSM состояния
# -------------------
class AnonStates:
USER_WAITING_TEXT = "user_waiting_text"
ADMIN_WAITING_REPLY = "admin_waiting_reply"
# -------------------
# Словари для отслеживания сообщений
# -------------------
# user_id -> message_id в админском топике
user_to_admin_map: Dict[int, int] = {}
# admin_message_id -> user_id
admin_to_user_map: Dict[int, int] = {}
# -------------------
# Команда /anon или callback
# -------------------
@router.callback_query(F.data.casefold() == "anon")
@router.message(Command("anon"))
async def anon_start(message: Message | CallbackQuery, state: FSMContext) -> None:
"""Начало анонимного сообщения. Ждём текст пользователя."""
await status_clear(message=message, state=state)
await state.clear()
await state.set_state(AnonStates.USER_WAITING_TEXT)
text = "Напишите сообщение, которое вы хотите отправить анонимно администраторам."
if isinstance(message, Message):
await message.reply(text)
else:
await message.message.answer(text)
# -------------------
# Получение текста от пользователя
# -------------------
@router.message(F.text, F.state == AnonStates.USER_WAITING_TEXT)
async def anon_send_text(message: Message, state: FSMContext) -> None:
"""Пересылает текст пользователя в админский топик анонимно."""
anon_text = message.text.strip()
if not anon_text:
await message.reply("Сообщение не может быть пустым. Попробуйте снова.")
return
forwarded_text = f"Сообщение от [пользователя](tg://user?id={message.from_user.id}):\n{anon_text}"
keyboard = InlineKeyboardMarkup(
inline_keyboard=[
[InlineKeyboardButton(text="Ответить", callback_data=f"anon_reply:{message.from_user.id}")]
]
)
sent_msg = await message.bot.send_message(
chat_id=ADMIN_CHAT_ID,
message_thread_id=ADMIN_THREAD_ID,
text=forwarded_text,
parse_mode="Markdown",
reply_markup=keyboard
)
user_to_admin_map[message.from_user.id] = sent_msg.message_id
admin_to_user_map[sent_msg.message_id] = message.from_user.id
await message.reply("Ваше сообщение отправлено анонимно администраторам.")
await state.clear()
# -------------------
# Кнопка "Ответить" админа
# -------------------
@router.callback_query(F.data.startswith("anon_reply:"))
async def anon_admin_reply(callback: CallbackQuery, state: FSMContext) -> None:
"""Начинаем сессию ответа админа пользователю."""
user_id = int(callback.data.split(":")[1])
await state.set_state(AnonStates.ADMIN_WAITING_REPLY)
await state.update_data(reply_to_user=user_id)
await callback.message.answer(f"Введите ответ для пользователя [id={user_id}]:")
await callback.answer()
# -------------------
# Текст ответа админа
# -------------------
@router.message(F.text, F.state == AnonStates.ADMIN_WAITING_REPLY)
async def anon_send_admin_text(message: Message, state: FSMContext) -> None:
"""Пересылает текст админа пользователю."""
data = await state.get_data()
reply_to_user = data.get("reply_to_user")
if reply_to_user:
await message.bot.send_message(
chat_id=reply_to_user,
text=f"Ответ администратора:\n{message.text}"
)
await message.reply("Сообщение отправлено пользователю.")
await state.clear()

View File

@@ -0,0 +1,27 @@
from aiogram import Router, F
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.types import Message
from bot import BotInfo
from bot.utils import status_clear
from configs import COMMANDS
from middleware.loggers import logger
__all__ = ("router",)
CMD: str = "cancel".casefold()
router: Router = Router(name=f"{CMD}_cmd_router")
@router.callback_query(F.data.casefold() == CMD)
@router.message(Command(*COMMANDS[CMD], prefix=BotInfo.prefix, ignore_case=True))
@router.message(F.text.casefold().in_(COMMANDS[CMD]))
async def cancel_handler(message: Message, state: FSMContext, text: str = "❌ Отмена предыдущего действия!"):
"""
Позволяет пользователю отменить процесс смены описания
"""
await status_clear(message=message, state=state)
logger.info(text=text)
await message.answer(text)

View File

@@ -0,0 +1,49 @@
# bot/handlers/commands/create_cmd.py
from aiogram import Router, F
from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiogram.fsm.context import FSMContext
from bot.core import BotInfo
from bot.states.anketa_states import StartForm
from bot.templates import msg_photo
from middleware import log
# Настройка экспорта и роутера
__all__ = ("router",)
router: Router = Router(name="create_cmd_router")
@router.callback_query(F.data == "create")
@router.message(Command('create','скуфеу', 'анкета', prefix=BotInfo.prefix, ignore_case=True))
@log(level='INFO', log_type='Start', text="использовал(а) команду /create")
async def create_cmd(message: Message|CallbackQuery, state: FSMContext) -> None:
"""
Обработчик команды /create.
"""
# Сбросим все состояния (отменим создание поста, если оно было)
await state.clear()
# Создание инлайн-клавиатуры
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Правила❗️", url='https://teletype.in/@velli_arsaan/XxUiHcB4Puj'))
ikb.row(InlineKeyboardButton(text="Назад↪️", callback_data='start'))
# Создание базовых переменных сообщения
caption: str = f"""
Если вы хотели бы вступить в наш проект, то напоминаю, что вам сначала нужно ознакомиться с <b>инфо-каналом</b>! При продолжении диалога вы автоматически подтверждаете то, что прочитали все правила и в курсе, что мы ролевой проект, не флуд.
<blockquote>Чтобы вступить к вам мы просим вас заполнить небольшую анкету:
1. <i>Желаемая роль</i>;
2. <i>Кого бы вы хотели в соролы?</i>;
3. <i>Кодовая фраза из наших правил</i>;</blockquote>
[‼️] Оно состоит всего из 4 слов, которые разбросаны в верном порядке по статьям о правилах.
"""
# Установим состояние ожидания анкеты
await state.set_state(StartForm.waiting_for_application)
# Обработчик ответа на сообщение
await msg_photo(message=message, text=caption, file='assets/help.png', markup=ikb)

View File

@@ -0,0 +1,368 @@
from typing import Dict
from aiogram import Router, F
from aiogram.filters import Command, StateFilter
from aiogram.fsm.context import FSMContext
from aiogram.types import Message, InlineKeyboardButton, CallbackQuery
from aiogram.utils.keyboard import InlineKeyboardBuilder
from bot.core.bots import BotInfo
from bot.utils import status_clear
from configs import COMMANDS, ImportantID
from middleware.loggers import log
# user_id -> thread_id (топик пользователя)
user_topic_map: Dict[int, int] = {}
# message_id в топике -> user_id
topic_message_map: Dict[int, int] = {}
__all__ = ("router", "user_topic_map")
CMD: str = "new"
router: Router = Router(name=f"{CMD}_cmd_router")
STATE_WAITING_REQUEST = "waiting_request"
def has_active_topic(user_id: int) -> bool:
"""Проверяет, есть ли у пользователя активный топик"""
return user_id in user_topic_map
async def send_topic_message(user_id: int, text: str, reply_markup=None):
"""Отправляет сообщение в топик пользователя"""
thread_id = user_topic_map.get(user_id)
if not thread_id:
return False
try:
await BotInfo.bot.send_message(
chat_id=ImportantID.SUPPORT_CHAT_ID,
message_thread_id=thread_id,
text=text,
parse_mode="HTML",
reply_markup=reply_markup
)
return True
except Exception as e:
log(level='ERROR', log_type='TOPIC_SEND', text=f"Ошибка отправки в топик: {e}")
return False
# ===================== Продолжение диалога =====================
@router.callback_query(F.data == "continue_dialog")
async def continue_dialog_callback(callback: CallbackQuery, state: FSMContext) -> None:
"""Обработчик продолжения существующего диалога"""
user_id = callback.from_user.id
if not has_active_topic(user_id):
await callback.answer("❌ Активный диалог не найден", show_alert=True)
return
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Отмена↩️", callback_data='start'))
await callback.message.edit_text(
text="💬 У вас уже есть активный диалог с поддержкой. Просто отправьте ваше сообщение (не через reply) и оно будет переслано администратору.",
reply_markup=ikb.as_markup()
)
await callback.answer()
# ===================== Обработчик callback /new =====================
@router.callback_query(F.data.casefold() == CMD)
@log(level='INFO', log_type=f"{CMD.upper()}_CBD", text=f"использовал команду /{CMD} через кнопку")
async def new_cmd_callback(callback: CallbackQuery, state: FSMContext) -> None:
"""Обработчик команды /new из callback кнопки"""
user_id = callback.from_user.id
# Проверяем, есть ли уже активный топик
if has_active_topic(user_id):
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Продолжить диалог💬", callback_data='continue_dialog'))
ikb.row(InlineKeyboardButton(text="Создать новый📝", callback_data='force_new'))
await callback.message.edit_text(
text="⚠️ У вас уже есть активный диалог с поддержкой.\n\n"
"• <b>Продолжить текущий</b> - чтобы писать в существующий диалог\n"
"• <b>Создать новый</b> - если хотите начать новый запрос (старый диалог будет архивирован)",
reply_markup=ikb.as_markup(),
parse_mode="HTML"
)
await callback.answer()
return
await status_clear(message=callback.message, state=state)
await state.set_state(STATE_WAITING_REQUEST)
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Отмена↩️", callback_data='start'))
try:
await callback.message.edit_text(
text="Отправьте свой запрос:",
reply_markup=ikb.as_markup()
)
except Exception:
await callback.message.answer(
text="Отправьте свой запрос:",
reply_markup=ikb.as_markup()
)
await callback.answer()
# ===================== Принудительное создание нового топика =====================
@router.callback_query(F.data == "force_new")
async def force_new_callback(callback: CallbackQuery, state: FSMContext) -> None:
"""Принудительное создание нового топика (при наличии активного)"""
user_id = callback.from_user.id
# Уведомляем в старом топике о создании нового
if has_active_topic(user_id):
await send_topic_message(
user_id,
f"🔔 <b>Пользователь начал новый запрос</b>\n"
f"Старый топик будет архивирован."
)
# Не удаляем старый топик из мапы сразу - он перезапишется при создании нового
await status_clear(message=callback.message, state=state)
await state.set_state(STATE_WAITING_REQUEST)
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Отмена↩️", callback_data='start'))
await callback.message.edit_text(
text="📝 <b>Создание нового запроса</b>\n\nОтправьте ваш запрос:",
reply_markup=ikb.as_markup(),
parse_mode="HTML"
)
await callback.answer()
# ===================== Обработчик сообщения /new =====================
@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: Message, state: FSMContext) -> None:
"""Обработчик команды /new из текстового сообщения"""
user_id = message.from_user.id
# Проверяем, есть ли уже активный топик
if has_active_topic(user_id):
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Продолжить диалог💬", callback_data='continue_dialog'))
await message.answer(
text="⚠️ У вас уже есть активный диалог с поддержкой.\n\n"
"Используйте кнопку ниже чтобы продолжить общение в существующем диалоге.",
reply_markup=ikb.as_markup(),
parse_mode="HTML"
)
return
await status_clear(message=message, state=state)
await state.set_state(STATE_WAITING_REQUEST)
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Отмена↩️", callback_data='start'))
await message.answer(
text="Отправьте свой запрос:",
reply_markup=ikb.as_markup()
)
# ===================== Создание топика и отправка запроса =====================
@router.message(StateFilter(STATE_WAITING_REQUEST))
async def process_request(message: Message, state: FSMContext) -> None:
"""Создание топика и отправка запроса пользователя"""
text = message.text.strip()
if not text:
await message.reply("⚠️ Пожалуйста, отправьте непустое сообщение.")
return
user = message.from_user
try:
# Создаем новый топик для пользователя
topic_name = f"👤 {user.full_name} (ID: {user.id})"
topic_result = await message.bot.create_forum_topic(
chat_id=ImportantID.SUPPORT_CHAT_ID,
name=topic_name
)
thread_id = topic_result.message_thread_id
# Отправляем сообщение пользователя в новый топик
formatted_text = f"<b>📩 Сообщение от <a href='tg://user?id={user.id}'>{user.full_name}</a>:</b>\n{text}"
sent_msg = await message.bot.send_message(
chat_id=ImportantID.SUPPORT_CHAT_ID,
message_thread_id=thread_id,
text=formatted_text,
parse_mode="HTML"
)
# Отправляем сообщение с уведомлением (со звуком)
await message.bot.send_message(
chat_id=ImportantID.SUPPORT_CHAT_ID,
message_thread_id=thread_id,
text="🔔 <b>Новый запрос создан</b>\nАдминистратор уведомлен.",
parse_mode="HTML"
)
# Сохраняем связь пользователя и топика
user_topic_map[user.id] = thread_id
topic_message_map[sent_msg.message_id] = user.id
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Перейти к диалогу💬", callback_data='continue_dialog'))
ikb.row(InlineKeyboardButton(text="В меню↩️", callback_data='start'))
await message.answer(
text="✅ <b>Запрос отправлен!</b>\n\n"
"Администратор ответит в этом боте. Вы можете продолжить общение через меню.",
reply_markup=ikb.as_markup(),
parse_mode="HTML"
)
await state.clear()
except Exception as e:
await message.reply(f"⚠️ Не удалось создать запрос: {e}")
# ===================== Пересылка сообщений пользователя в топик =====================
@router.message(F.chat.type == "private", ~F.reply_to_message)
async def forward_user_to_admin(message: Message) -> None:
"""Пересылает сообщения пользователя в топик (если есть активный диалог)"""
if message.from_user.is_bot:
return
user_id = message.from_user.id
# Проверяем, есть ли активный топик
if not has_active_topic(user_id):
return # Нет активного топика - игнорируем
# Получаем топик пользователя
thread_id = user_topic_map.get(user_id)
if not thread_id:
return
try:
# Отправляем сообщение пользователя в топик
if message.text:
formatted_text = f"<b>💬 Сообщение от <a href='tg://user?id={user_id}'>{message.from_user.full_name}</a>:</b>\n{message.html_text}"
sent_msg = await message.bot.send_message(
chat_id=ImportantID.SUPPORT_CHAT_ID,
message_thread_id=thread_id,
text=formatted_text,
parse_mode="HTML"
)
topic_message_map[sent_msg.message_id] = user_id
elif message.photo:
caption = f"<b>💬 Сообщение от <a href='tg://user?id={user_id}'>{message.from_user.full_name}</a>:</b>\n{message.html_text}" if message.caption else f"<b>💬 Сообщение от <a href='tg://user?id={user_id}'>{message.from_user.full_name}</a>:</b>"
sent_msg = await message.bot.send_photo(
chat_id=ImportantID.SUPPORT_CHAT_ID,
message_thread_id=thread_id,
photo=message.photo[-1].file_id,
caption=caption,
parse_mode="HTML"
)
topic_message_map[sent_msg.message_id] = user_id
await message.answer("✅ Сообщение отправлено администратору")
except Exception as e:
await message.answer(f"⚠️ Не удалось отправить сообщение: {e}")
# ===================== Пересылка ответов админа пользователю =====================
@router.message(F.chat.id == ImportantID.SUPPORT_CHAT_ID, F.message_thread_id)
async def forward_admin_to_user(message: Message) -> None:
"""Пересылает сообщения админа из топика пользователю"""
if message.from_user.is_bot:
return
thread_id = message.message_thread_id
# Ищем пользователя по 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 # Не наш топик
try:
# Пересылаем сообщение админа пользователю
if message.text:
text = f"<b>👨‍💼 Ответ администратора:</b>\n{message.html_text}"
sent_msg = await message.bot.send_message(
chat_id=user_id,
text=text,
parse_mode="HTML"
)
# Сохраняем связь для возможного ответа пользователя
topic_message_map[sent_msg.message_id] = user_id
elif message.photo:
caption = f"<b>👨‍💼 Ответ администратора:</b>\n{message.html_text}" if message.caption else "<b>👨‍💼 Ответ администратора:</b>"
await message.bot.send_photo(
chat_id=user_id,
photo=message.photo[-1].file_id,
caption=caption,
parse_mode="HTML"
)
except Exception as e:
log(level='ERROR', log_type='FORWARD', text=f"Ошибка пересылки админ->пользователь: {e}")
# ===================== Пересылка ответов пользователя в топик =====================
@router.message(F.chat.type == "private", F.reply_to_message)
async def forward_user_reply_to_admin(message: Message) -> None:
"""Пересылает ответы пользователя (reply) в топик"""
if message.from_user.is_bot:
return
user_id = message.from_user.id
reply_to_id = message.reply_to_message.message_id
# Проверяем, является ли это ответом на сообщение из топика
original_user_id = topic_message_map.get(reply_to_id)
if not original_user_id or original_user_id != user_id:
return
# Получаем топик пользователя
thread_id = user_topic_map.get(user_id)
if not thread_id:
await message.reply("⚠️ Не найден активный диалог. Используйте /new для нового запроса.")
return
try:
# Отправляем ответ пользователя в топик
if message.text:
formatted_text = f"<b>💬 Ответ от <a href='tg://user?id={user_id}'>{message.from_user.full_name}</a>:</b>\n{message.html_text}"
sent_msg = await message.bot.send_message(
chat_id=ImportantID.SUPPORT_CHAT_ID,
message_thread_id=thread_id,
text=formatted_text,
parse_mode="HTML"
)
topic_message_map[sent_msg.message_id] = user_id
elif message.photo:
caption = f"<b>💬 Ответ от <a href='tg://user?id={user_id}'>{message.from_user.full_name}</a>:</b>\n{message.html_text}" if message.caption else f"<b>💬 Ответ от <a href='tg://user?id={user_id}'>{message.from_user.full_name}</a>:</b>"
sent_msg = await message.bot.send_photo(
chat_id=ImportantID.SUPPORT_CHAT_ID,
message_thread_id=thread_id,
photo=message.photo[-1].file_id,
caption=caption,
parse_mode="HTML"
)
topic_message_map[sent_msg.message_id] = user_id
await message.reply("✅ Ответ отправлен администратору.")
except Exception as e:
await message.reply(f"⚠️ Не удалось отправить ответ: {e}")

View File

@@ -0,0 +1,68 @@
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.i18n import gettext as _
from aiogram.utils.keyboard import InlineKeyboardBuilder
from bot.core.bots import BotInfo
from bot.templates import msg_photo
from configs import COMMANDS, RpValue
from .new_cmd import user_topic_map # Импортируем мапу топиков из модуля new
__all__ = ("router",)
CMD: str = "start".casefold()
router: Router = Router(name=f"{CMD}_cmd_router")
@router.callback_query(F.data.casefold() == CMD)
@router.message(Command(*COMMANDS[CMD], prefix=BotInfo.prefix, ignore_case=True))
async def start_cmd(update: Message | CallbackQuery, state: FSMContext) -> None:
"""Обработчик команды /start"""
# Определяем тип update
if isinstance(update, CallbackQuery):
message = update.message
callback = update
else:
message = update
callback = None
# Проверяем, есть ли у пользователя активный топик
user_id = update.from_user.id
has_active_topic = user_id in user_topic_map
# Создание инлайн-клавиатуры
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Википедия🌐", url="https://t.me/PrimoWiki"))
if has_active_topic:
# Если есть активный топик, показываем кнопку "Продолжить диалог"
ikb.row(InlineKeyboardButton(text="Продолжить диалог💬", callback_data='continue_dialog'))
else:
# Если нет активного топика, показываем кнопку "Связаться"
ikb.row(InlineKeyboardButton(text="Связаться👀", callback_data='new'))
# Формируем приветственное сообщение
text: str = _(
"""Добро пожаловать, <a href="{url}">{name}</a>!
Я ваш помощник по проекту — <b>PrimoWiki</b>!
Моя цель — помочь вам сориентироваться и сделать ваше вступление куда проще!
Надеюсь, я смогу вам помочь! Пожалуйста, выберите нужную функцию на клавиатуре!
"""
).format(
url=update.from_user.url,
name=update.from_user.first_name,
rp_name=RpValue.RP_NAME,
)
# Добавляем информацию об активном диалоге, если есть
if has_active_topic:
text += "\n\n💬 <b>У вас есть активный диалог с поддержкой!</b>"
# Отправляем сообщение
await msg_photo(message=message, text=text, file=f'assets/{CMD}.jpg', markup=ikb)
if callback:
await callback.answer()

View File

@@ -0,0 +1,58 @@
# bot/handlers/commands/union_cmd.py
from aiogram import Router, F
from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiogram.fsm.context import FSMContext
from bot.core import BotInfo
from bot.states.union_states import UnionStates
from bot.templates import msg
from middleware import log
# Настройка экспорта и роутера
__all__ = ("router",)
router: Router = Router(name="union_cmd_router")
@router.callback_query(F.data == "union")
@router.message(Command('union','гтшщт', 'союз', prefix=BotInfo.prefix, ignore_case=True))
@log(level='INFO', log_type='Start', text="использовал(а) команду /union")
async def create_cmd(message: Message|CallbackQuery, state: FSMContext) -> None:
"""
Обработчик команды /union.
"""
# Сбросим все состояния (отменим создание поста, если оно было)
#await state.clear()
# Создание инлайн-клавиатуры
ikb: InlineKeyboardBuilder = InlineKeyboardBuilder()
ikb.row(InlineKeyboardButton(text="Правила❗️", url='https://teletype.in/@velli_arsaan/XxUiHcB4Puj'))
ikb.row(InlineKeyboardButton(text="Назад↪️", callback_data='start'))
# Создание базовых переменных сообщения
caption: str = f"""
Приветствуем! Это бот для связи по вопросам союзов проекта ˚₊· ‌‌‌‌➳ 𝑆𝑦𝑠𝑡𝑒𝑚 𝑅𝑒𝑠𝑒𝑡 ·₊˚.
Задайте свой вопрос, и мы постараемся ответить вам в ближайшее время — в некотором случае можем попроосить вас дать юз/ссылку на ваш проект.
Предложение о заключении союзов должно выглядеть вот так:
Название
Юз и ссылка на инфо
Юз и ссылка на лайф
Условия союзов
Юзер следящего с вашей стороны
Желаемый следящий с нашей стороны (мы будем в праве поставить вам другого, но тот, которого вы назовёте, будет в приоритете)
Кодовое предложение из условий союзов. Оно состоит из 4 слов, которые расположены в верном порядке в статье о наших условиях сотрудничества.
Имейте ввиду, что мы можем отказаться от союза без объяснения причин!
"""
# Обработчик ответа на сообщение
await msg(message=message, text=caption, markup=ikb)
# Установим состояние ожидания анкеты
await state.set_state(UnionStates.waiting_for_union)