Files
malenia/keyboards/client.py
hexdev 606aa4b89f feat: add admin promotion broadcast system and psql health check
- Add `/push` command for admins to broadcast messages to all users
  with approve/decline confirmation flow (handlers/ads.py)
- Add common handler for undefined commands and delete callback
- Add `UserRepository.get_users()` to fetch all users
- Add `UserService.send_promotion_to_users()` with error logging
- Add promotion confirmation keyboard and FSM state
- Add PostgreSQL availability check in startup.sh before migrations
- Add new text constants for promotion flow
2026-04-15 20:19:07 +07:00

104 lines
3.4 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.types import InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.utils.keyboard import InlineKeyboardBuilder
from config import settings
from misc.utils import convert_duration_to_int
from schemas.subscriptions import SubscriptionDuration
main_menu = InlineKeyboardBuilder(
[
[
InlineKeyboardButton(text="⚙️ Купить", callback_data="buy"),
InlineKeyboardButton(text="FAQ", callback_data="faq"),
],
[
InlineKeyboardButton(text="Наш Канал", url="https://goo.gle"),
InlineKeyboardButton(text="Тех. Поддержка", callback_data="support"),
],
[InlineKeyboardButton(text="🔗 Обновить ссылку", callback_data="update_link")],
[InlineKeyboardButton(text="👤 Реферальная система", callback_data="referal")],
]
).as_markup()
_return_to_menu_btn: InlineKeyboardButton = InlineKeyboardButton(
text="⬅️ Назад", callback_data="menu:main"
)
return_to_menu: InlineKeyboardMarkup = InlineKeyboardBuilder([[_return_to_menu_btn]]).as_markup()
payment_gateways: InlineKeyboardMarkup = InlineKeyboardBuilder(
[
[InlineKeyboardButton(text="✍️ Перейти в поддержку", callback_data="checkout")],
[_return_to_menu_btn],
]
).as_markup()
def _return_btn(data: str = "menu:main", text: str = "⬅️ Назад") -> InlineKeyboardButton:
return InlineKeyboardButton(text=text, callback_data=data)
def build_return_menu(data: str = "menu:main", text: str = "⬅️ Назад") -> InlineKeyboardMarkup:
return InlineKeyboardBuilder([[_return_btn(data, text)]]).as_markup()
def devices_selector(current: int = settings.min_devices, whitelists: bool = False):
builder = InlineKeyboardBuilder()
buttons = [
InlineKeyboardButton(
text=f"{'' if i == current else ''}{i}", callback_data=f"devices:{i}"
)
for i in range(settings.min_devices, settings.max_devices + 1)
]
builder.add(*buttons).adjust(6)
wl_icon = "" if whitelists else ""
builder.row(
InlineKeyboardButton(
text=f"{wl_icon}Обход Белых Списков (+100₽)",
callback_data="whitelist:toggle",
)
)
builder.row(InlineKeyboardButton(text="🟢", callback_data="confirm"))
builder.row(_return_to_menu_btn)
return builder.as_markup()
def duration_selector(
current: SubscriptionDuration = SubscriptionDuration.MONTH,
back_cb: str = "menu:main",
) -> InlineKeyboardMarkup:
builder = InlineKeyboardBuilder()
duration_int = convert_duration_to_int(current)
durations = [
(1, "1 Месяц"),
(3, "3 Месяца"),
(6, "6 Месяцев"),
(12, "1 Год"),
]
for val, label in durations:
is_selected = val == duration_int
builder.button(
text=f"{'' if is_selected else ''}{label}",
callback_data=f"duration:{val}",
)
builder.row(InlineKeyboardButton(text="🛒 Перейти к оплате", callback_data="confirm"))
builder.row(_return_btn(back_cb))
return builder.as_markup()
def referals_kb(share_link: str) -> InlineKeyboardMarkup:
return InlineKeyboardBuilder(
[
[InlineKeyboardButton(text="🔗 Поделиться ссылкой", url=share_link)],
[_return_to_menu_btn],
]
).as_markup()