from aiogram import F from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton from app import dp, ADMIN_ID from auth import is_admin_msg from keyboards import menu_kb HELP_PAGES = [ ( "Overview", "ℹ️ **Help — Overview**\n\n" "🩺 *Health* — быстрый health-check.\n" "📊 *Статус* — общая загрузка.\n" "📋 */status_short* — кратко (load/RAM/диски).\n" "🩺 */health_short* — краткий health.\n" "🧪 */selftest* — health + restic snapshot probe.\n" "🔧 Разделы: Docker, Backup, Artifacts, System, OpenWrt.", ), ( "Alerts", "🚨 **Alerts & Mute**\n\n" "Команды:\n" "• `/alerts test `\n" "• `/alerts mute ` / `/alerts unmute ` / `/alerts list`\n" "• `/alerts recent [hours]`\n" "Шорткаты: `/alerts_list`, `/alerts_recent`, `/alerts_mute_load` (60м).\n" "Категории: load, disk, smart, ssl, docker, test.\n" "Quiet hours: `alerts.quiet_hours` для не‑критичных.\n" "Авто-мьют: `alerts.auto_mute` со слотами времени.\n" "Только красные load: `alerts.load_only_critical: true`.\n" "Валидатор конфига: `/config_check`.", ), ( "Backup", "💾 **Backup (restic)**\n\n" "Кнопки: Status, Last snapshot, Repo stats, Run backup, Queue, Restic check, Weekly report, History.\n" "History — хвост `/var/log/backup-auto.log`.\n" "Fail → кнопка Retry (backup/check).\n" "Run backup/Check учитывают `safety.dry_run`.\n" "После бэкапа приходит TL;DR + путь к логу `/var/log/backup-auto.log`.\n" "Queue → Details показывает отложенные задачи.", ), ( "Docker & System", "🐳 **Docker**\n" "Status/Restart/Logs/Stats — клавиатура Docker.\n" "Команды: `/docker_status`, `/docker_health `.\n\n" "🖥 **System**\n" "Info: Disks/Security/Metrics/Hardware/SMART/OpenWrt.\n" "Ops: Updates/Upgrade/Reboot.\n" "Logs: Audit/Incidents/Security/Integrations/Processes.\n" "OpenWrt: `/openwrt`, `/openwrt_wan`, `/openwrt_clients`, `/openwrt_leases`.", ), ( "Admin", "🛠 **Admin & Deploy**\n\n" "Config: `/config_check`, файл `config.yaml` (см. config.example.yaml).\n" "Deploy: `deploy.sh` (ssh 10.10.10.10:1090 → git pull → systemctl restart tg-bot).\n" "Incidents summary: `/incidents_summary`.\n" "Incidents export: `/incidents_export [hours] [csv|json]`.\n" "Alerts log: `/alerts_log [hours]`.\n" "Disk snapshot: `/disk_snapshot`.\n" "Queue history: `/queue_history`.\n" "BotFather list: `/botfather_list`.\n" "Безопасность: `safety.dry_run: true` блокирует опасные действия.\n" "OpenWrt: кнопка в System → Info.", ), ] def _help_kb(idx: int) -> InlineKeyboardMarkup: buttons = [] if idx > 0: buttons.append(InlineKeyboardButton(text="◀️ Prev", callback_data=f"help:{idx-1}")) buttons.append(InlineKeyboardButton(text=f"{idx+1}/{len(HELP_PAGES)}", callback_data="help:noop")) if idx < len(HELP_PAGES) - 1: buttons.append(InlineKeyboardButton(text="Next ▶️", callback_data=f"help:{idx+1}")) return InlineKeyboardMarkup(inline_keyboard=[buttons]) def _help_text(idx: int) -> str: _title, body = HELP_PAGES[idx] return body @dp.message(F.text.in_({"ℹ️ Help", "ℹ Help", "Help", "/help"})) async def help_cmd(msg: Message): if not is_admin_msg(msg): return idx = 0 await msg.answer( _help_text(idx), reply_markup=_help_kb(idx), parse_mode="Markdown", ) @dp.callback_query(F.data.startswith("help:")) async def help_cb(cb: CallbackQuery): if cb.from_user.id != ADMIN_ID: await cb.answer() return payload = cb.data.split(":", 1)[1] if payload == "noop": await cb.answer() return try: idx = int(payload) except ValueError: await cb.answer() return idx = max(0, min(idx, len(HELP_PAGES) - 1)) await cb.message.edit_text( _help_text(idx), reply_markup=_help_kb(idx), parse_mode="Markdown", ) await cb.answer() BOTFATHER_LIST = """\ help - Show help pages status_short - Compact host status health_short - Compact health report selftest - Health + restic snapshot probe alerts - Manage alerts alerts_list - List active mutes alerts_recent - Show recent incidents (24h) alerts_mute_load - Mute load alerts for 60m alerts_log - Show suppressed alerts backup_run - Run backup (queued) backup_history - Show backup log tail queue_history - Show queue recent jobs docker_status - Docker summary docker_health - Docker inspect/health by alias docker_health_summary - Docker health summary (problems only) openwrt - Full OpenWrt status openwrt_wan - OpenWrt WAN only openwrt_clients - OpenWrt wifi clients openwrt_leases - OpenWrt DHCP leases openwrt_fast - OpenWrt quick WAN view incidents_summary - Incidents counters (24h/7d) incidents_export - Export incidents (hours fmt) disk_snapshot - Disk usage snapshot config_check - Validate config """ @dp.message(F.text == "/botfather_list") async def botfather_list(msg: Message): if not is_admin_msg(msg): return await msg.answer(f"Commands for BotFather:\n```\n{BOTFATHER_LIST}\n```", parse_mode="Markdown")