1.0 Добавлена /help как проверка клавиатур, и сохздан класс простого создания reply_kb

This commit is contained in:
Verum
2025-02-25 15:02:38 +07:00
parent 47896a0597
commit c3a4d45678
11 changed files with 162 additions and 17 deletions

View File

@@ -2,4 +2,4 @@
# Инициализация модуля inline_kb, для inline-клавиатур
# Экспортирование модулей во внешние слои проекта
from start_inline_kb import get_start_kb
from .start_inline_kb import get_start_kb

View File

@@ -9,7 +9,7 @@ __all__ = ("get_start_kb",)
# Функция создания клавиатуры
def get_start_kb(row_width : int = 1):
buttons = [
("Я Новичок!", None, "novice_cbd"),
("Я Новичок!", "https://t.me/+3DOBTGhBIEc4ZThi", "novice_cbd"),
("Где я?", None, "where_i_am_cbd"),
("Мне уже известен этот феномен..", None, "menu"),
]

View File

@@ -2,3 +2,4 @@
# Инициализация модуля reply_kb, для reply-клавиатур
# Экспортирование модулей во внешние слои проекта
from .help_reply_kb import *

View File

@@ -0,0 +1,28 @@
# BotCode/keyboards/reply_kb/help_reply_kb.py
# Создание reply-клавиатуры на команду: /start с использованием всех возможностей
from aiogram.types import ReplyKeyboardMarkup
from BotLibrary import BaseReplyKeyboard
# Настройка экспорта в модули
__all__ = ("get_help_kb",)
# Функция создания клавиатуры
def get_help_kb(row_width: int = 1, resize_kb: bool = True, one_time_kb: bool = True) -> ReplyKeyboardMarkup:
buttons = [
["Я Новичок!"], # Простая текстовая кнопка
[("Укажи местоположение", "location")], # Запрос геолокации
[("Поделись контактом", "contact")], # Запрос контакта
[("Выбери друзей", "users", {"request_id": 1, "max_quantity": 2})], # Запрос списка пользователей
[("Выбери чат", "chat", {"request_id": 2, "chat_is_channel": False})], # Запрос чата
[("Создай опрос", "poll")], # Запрос создания опроса
[("Создай квиз", "quiz")], # Запрос создания квиза
[("Открыть руководство", "web_app", {"url": "https://example.com/guide"})], # Запуск веб-приложения
[("Поделись пользователем", "user", {"request_id": 3, "user_is_premium": True})], # Запрос конкретного пользователя
]
return BaseReplyKeyboard(
buttons,
resize_keyboard=resize_kb,
one_time_keyboard=one_time_kb,
row_width=row_width # Передаем row_width в класс
).get_keyboard()

View File

@@ -2,7 +2,7 @@
# Работа с командой /help, для вывода помощи пользователю
from BotLibrary import CommandHandler
from BotCode.keyboards import get_start_kb
from BotCode.keyboards import get_help_kb
# Создание команды /help с нужными параметрами
@@ -11,7 +11,7 @@ help_cmd = CommandHandler(
description="Получить помощь",
keywords=["help", "info", "помощь", "инфо", "информация", "рудз", "штащ", "byaj", "gjvjom", "byajhvfwbz"],
callbackdata="keywords",
keyboard=get_start_kb,
keyboard=get_help_kb,
text_msg="Привет! Это команда помощи. Тут ты можешь узнать, как пользоваться ботом.",
media="gif", path_to_media="https://t.me/c/2442589033/74653"
#media="", path_to_media=""
)

View File

@@ -8,7 +8,7 @@ from BotCode.keyboards import get_start_kb
start_cmd = CommandHandler(
name="start",
description="Добро пожаловать!",
keywords=["start"],
keywords=["start", "старт", "cnfhn", "ыефке", "пуск", "gecr", "on"],
keyboard=get_start_kb,
media="photo",
path_to_media=[

View File

@@ -3,4 +3,5 @@
# Экспортирование модулей во внешние слои проекта
from .user_cmd_class import *
from .keyboards_sample import *
from .inline_kb_sample import *
from .reply_kb_sample import *

View File

@@ -1,11 +1,7 @@
# BotCode/keyboards/inline_kb/base_inline_kb.py
# Базовый класс для создания инлайн-клавиатур
from aiogram.types import InlineKeyboardMarkup
from aiogram.types import InlineKeyboardMarkup, ReplyKeyboardRemove
from aiogram.utils.keyboard import InlineKeyboardBuilder
from typing import List, Tuple, Optional
class BaseInlineKeyboard:
def __init__(self, buttons: List[Tuple[str, Optional[str], Optional[str]]], row_width: int = 1):
"""
@@ -17,8 +13,8 @@ class BaseInlineKeyboard:
def get_keyboard(self) -> InlineKeyboardMarkup:
"""
Создаёт инлайн-клавиатуру.
:return: объект InlineKeyboardMarkup
Создаёт инлайн-клавиатуру и возвращает её вместе с объектом для удаления reply-клавиатуры.
:return: кортеж (InlineKeyboardMarkup, ReplyKeyboardRemove)
"""
ikb = InlineKeyboardBuilder()
for text, url, callback_data in self.buttons:

View File

@@ -0,0 +1,103 @@
# BotCode/keyboards/reply_kb/base_reply_kb.py
# Базовый класс для создания reply-клавиатур с расширенными возможностями и поддержкой row_width
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton, KeyboardButtonPollType, WebAppInfo, KeyboardButtonRequestUsers, KeyboardButtonRequestChat, KeyboardButtonRequestUser
from aiogram.utils.keyboard import ReplyKeyboardBuilder
from typing import List, Union, Tuple, Optional, Dict, Any
class BaseReplyKeyboard:
def __init__(
self,
buttons: List[List[Union[str, Tuple[str, str, Optional[Dict[str, Any]]]]]],
resize_keyboard: bool = True,
one_time_keyboard: bool = False,
row_width: int = 1 # Добавляем row_width как параметр
):
"""
:param buttons: список кнопок, каждая из которых может быть:
- строкой (обычная кнопка с текстом)
- кортежем (текст, тип кнопки, дополнительные параметры).
Типы кнопок: "location", "contact", "users", "chat", "poll", "quiz", "web_app", "user".
Дополнительные параметры: словарь с настройками (опционально).
:param resize_keyboard: изменять ли размер клавиатуры под содержимое.
:param one_time_keyboard: скрывать ли клавиатуру после нажатия.
:param row_width: количество кнопок в одной строке (если требуется динамическое распределение).
"""
self.buttons = buttons
self.resize_keyboard = resize_keyboard
self.one_time_keyboard = one_time_keyboard
self.row_width = row_width
def get_keyboard(self) -> ReplyKeyboardMarkup:
"""
Создаёт reply-клавиатуру с поддержкой всех типов кнопок и динамическим распределением по row_width.
:return: объект ReplyKeyboardMarkup
"""
rkb = ReplyKeyboardBuilder()
# Преобразуем вложенные списки в плоский список для динамического распределения
flat_buttons = [button for row in self.buttons for button in row]
# Разбиваем кнопки на строки с учетом row_width
for i in range(0, len(flat_buttons), self.row_width):
row = flat_buttons[i:i + self.row_width]
buttons = []
for button in row:
if isinstance(button, tuple):
text, button_type = button[0], button[1]
params = button[2] if len(button) > 2 else {}
if button_type == "location":
buttons.append(KeyboardButton(text=text, request_location=True))
elif button_type == "contact":
buttons.append(KeyboardButton(text=text, request_contact=True))
elif button_type == "users":
buttons.append(KeyboardButton(
text=text,
request_users=KeyboardButtonRequestUsers(
request_id=params.get("request_id", 1),
user_is_bot=params.get("user_is_bot"),
user_is_premium=params.get("user_is_premium"),
max_quantity=params.get("max_quantity", 1)
)
))
elif button_type == "chat":
buttons.append(KeyboardButton(
text=text,
request_chat=KeyboardButtonRequestChat(
request_id=params.get("request_id", 1),
chat_is_channel=params.get("chat_is_channel", False),
chat_is_forum=params.get("chat_is_forum"),
chat_has_username=params.get("chat_has_username"),
chat_is_created=params.get("chat_is_created")
)
))
elif button_type == "poll":
buttons.append(KeyboardButton(
text=text,
request_poll=KeyboardButtonPollType(type="regular")
))
elif button_type == "quiz":
buttons.append(KeyboardButton(
text=text,
request_poll=KeyboardButtonPollType(type="quiz")
))
elif button_type == "web_app":
buttons.append(KeyboardButton(
text=text,
web_app=WebAppInfo(url=params.get("url", ""))
))
elif button_type == "user":
buttons.append(KeyboardButton(
text=text,
request_user=KeyboardButtonRequestUser(
request_id=params.get("request_id", 1),
user_is_bot=params.get("user_is_bot"),
user_is_premium=params.get("user_is_premium")
)
))
else:
buttons.append(KeyboardButton(text=button))
rkb.row(*buttons)
return rkb.as_markup(resize_keyboard=self.resize_keyboard, one_time_keyboard=self.one_time_keyboard)

View File

@@ -80,6 +80,22 @@ class CommandHandler:
chat_id=message.chat.id,
action=ChatAction.TYPING,
)
elif self.media == "quiz":
# Отправка викторины (quiz)
await message.reply_poll(
question=self.text_msg, # Текст сообщения используется как вопрос викторины
options=["Вариант 1", "Вариант 2"], # Заглушка, варианты нужно задавать отдельно
is_anonymous=True,
type="quiz",
correct_option_id=0, # Первый вариант по умолчанию правильный
reply_markup=self.keyboard() if self.keyboard else None,
disable_notification=self.disable_notification
)
if self.chat_action:
await message.bot.send_chat_action(
chat_id=message.chat.id,
action=ChatAction.TYPING,
)
else:
if self.media == "photo" and len(self.path_to_media) > 1:
# Отправка медиагруппы для фотографий

View File

@@ -3,8 +3,8 @@
# Токены от ботов телеграмма
BOT_TOKEN=7193685715:AAHFEnFreZGLQcHj8_wdWYJ2FLPrB-A-hzY
BOT1_TOKEN=8076305634:AAGNoo4N-WVP9mbeD76G7SLClSsySw23nGw
BOT2_TOKEN=
BOT1_TOKEN=7193685715:AAHFEnFreZGLQcHj8_wdWYJ2FLPrB-A-hzY
BOT2_TOKEN=8076305634:AAGNoo4N-WVP9mbeD76G7SLClSsySw23nGw
# Ключи от API
API_KEY=КЛЮЧ_ОТ_СТОРОННЕГО_API