forked from FOSS/ASF-Control-Bot
feat(bot): add bot account ownership and balance
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
from aiogram import Router
|
||||
from aiogram.filters import Command
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
|
||||
from bot.config import ADMIN_ID
|
||||
from bot.states import AdminFlow
|
||||
from bot.filters import AdminCallbackFilter, AdminFilter
|
||||
from bot.ui.keyboards import admin_keyboard, back_keyboard, admin_profile_keyboard
|
||||
from bot.services.balance import (
|
||||
BalanceError,
|
||||
change_user_balance,
|
||||
get_bot_slot_price,
|
||||
get_user_profile,
|
||||
set_bot_slot_price,
|
||||
)
|
||||
|
||||
router = Router()
|
||||
|
||||
|
||||
@router.message(Command("admin"), AdminFilter())
|
||||
async def admin_menu(message: Message, state: FSMContext) -> None:
|
||||
await state.clear()
|
||||
await message.answer("🤵 <b>Админ-панель</b>", reply_markup=admin_keyboard())
|
||||
|
||||
|
||||
@router.callback_query(lambda c: c.data == "admin_panel", AdminCallbackFilter())
|
||||
async def admin_panel(callback: CallbackQuery, state: FSMContext) -> None:
|
||||
await state.clear()
|
||||
|
||||
await callback.answer()
|
||||
await callback.message.edit_text(
|
||||
"🤵 <b>Админ-панель</b>", reply_markup=admin_keyboard()
|
||||
)
|
||||
|
||||
|
||||
@router.callback_query(
|
||||
AdminCallbackFilter(), lambda c: c.data.startswith("admin_lookup")
|
||||
)
|
||||
async def admin_lookup_prompt(callback: CallbackQuery, state: FSMContext) -> None:
|
||||
user_id = None
|
||||
try:
|
||||
user_id = int(callback.data.split(":")[1])
|
||||
except:
|
||||
pass
|
||||
|
||||
if user_id:
|
||||
try:
|
||||
if user_id <= 0:
|
||||
raise ValueError
|
||||
_, balance, bot_count = await get_user_profile(user_id)
|
||||
|
||||
except (ValueError, TypeError):
|
||||
await callback.message.edit_text("❌ Некорректный Telegram ID")
|
||||
return
|
||||
|
||||
await callback.message.edit_text(
|
||||
f"👤 <b>Профиль</b>\n\n"
|
||||
f"🆔: <code>{user_id}</code>\n"
|
||||
f"💰 Баланс: <code>{balance}</code> ₽\n"
|
||||
f"🤖 Ботов: <code>{bot_count}</code>",
|
||||
reply_markup=admin_profile_keyboard(user_id=user_id),
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
await callback.answer()
|
||||
await callback.message.edit_text(
|
||||
"🆔 Отправьте ID пользователя",
|
||||
reply_markup=back_keyboard(callback_data="admin_panel"),
|
||||
)
|
||||
|
||||
await state.set_state(AdminFlow.waiting_user_id)
|
||||
await state.update_data(action="lookup")
|
||||
|
||||
|
||||
@router.callback_query(
|
||||
AdminCallbackFilter(), lambda c: c.data.startswith("admin_balance:")
|
||||
)
|
||||
async def admin_balance_prompt(callback: CallbackQuery, state: FSMContext) -> None:
|
||||
user_id = int(callback.data.split(":")[1])
|
||||
|
||||
await callback.answer()
|
||||
await callback.message.edit_text(
|
||||
"💲 Отправьте сумму для изменения баланса пользователя",
|
||||
reply_markup=back_keyboard(callback_data=f"admin_lookup:{user_id}"),
|
||||
)
|
||||
|
||||
await state.set_state(AdminFlow.waiting_amount)
|
||||
await state.update_data(action="balance", user_id=user_id)
|
||||
|
||||
|
||||
@router.callback_query(AdminCallbackFilter(), lambda c: c.data == "admin_price")
|
||||
async def admin_price_prompt(callback: CallbackQuery, state: FSMContext) -> None:
|
||||
await callback.answer()
|
||||
await callback.message.edit_text(
|
||||
f"💲 Текущая цена слота: <code>{await get_bot_slot_price()}</code> ₽\n"
|
||||
"Отправьте новую положительную цену.",
|
||||
reply_markup=back_keyboard(callback_data="admin_panel"),
|
||||
)
|
||||
|
||||
await state.set_state(AdminFlow.waiting_amount)
|
||||
await state.update_data(action="price")
|
||||
|
||||
|
||||
@router.message(AdminFlow.waiting_user_id, AdminFilter())
|
||||
async def admin_lookup(message: Message, state: FSMContext) -> None:
|
||||
try:
|
||||
user_id = int((message.text or "").strip())
|
||||
if user_id <= 0:
|
||||
raise ValueError
|
||||
_, balance, bot_count = await get_user_profile(user_id)
|
||||
|
||||
except (ValueError, TypeError):
|
||||
await message.answer("❌ Некорректный Telegram ID")
|
||||
return
|
||||
|
||||
await message.answer(
|
||||
f"👤 <b>Профиль</b>\n\n"
|
||||
f"🆔: <code>{user_id}</code>\n"
|
||||
f"💰 Баланс: <code>{balance}</code> ₽\n"
|
||||
f"🤖 Ботов: <code>{bot_count}</code>",
|
||||
reply_markup=admin_profile_keyboard(user_id=user_id),
|
||||
)
|
||||
|
||||
await state.clear()
|
||||
|
||||
|
||||
@router.message(AdminFlow.waiting_amount, AdminFilter())
|
||||
async def admin_amount(message: Message, state: FSMContext) -> None:
|
||||
data = await state.get_data()
|
||||
text = (message.text or "").strip()
|
||||
|
||||
try:
|
||||
if data.get("action") == "price":
|
||||
price = int(text)
|
||||
await set_bot_slot_price(price, updated_by=ADMIN_ID)
|
||||
response = f"✅ Цена слота обновлена: <code>{price}</code> ₽"
|
||||
|
||||
else:
|
||||
amount_text = text
|
||||
user_text = data.get("user_id", None)
|
||||
|
||||
print(amount_text, user_text)
|
||||
|
||||
user_id, signed_amount = int(user_text), int(amount_text)
|
||||
|
||||
if user_id <= 0 or signed_amount == 0:
|
||||
raise ValueError
|
||||
|
||||
balance = await change_user_balance(
|
||||
telegram_id=user_id,
|
||||
amount=signed_amount,
|
||||
actor_telegram_id=message.from_user.id,
|
||||
)
|
||||
|
||||
response = f"✅ Баланс пользователя обновлён: <code>{balance}</code> ₽"
|
||||
|
||||
except (ValueError, TypeError, BalanceError):
|
||||
response = "❌ Некорректные данные: нужны положительные целые числа"
|
||||
|
||||
await message.answer(response)
|
||||
|
||||
if data.get("action") == "price":
|
||||
return await admin_menu(message, state)
|
||||
|
||||
_, balance, bot_count = await get_user_profile(user_id)
|
||||
|
||||
await message.answer(
|
||||
f"👤 <b>Профиль</b>\n\n"
|
||||
f"🆔: <code>{user_id}</code>\n"
|
||||
f"💰 Баланс: <code>{balance}</code> ₽\n"
|
||||
f"🤖 Ботов: <code>{bot_count}</code>",
|
||||
reply_markup=admin_profile_keyboard(user_id=user_id),
|
||||
)
|
||||
|
||||
await state.clear()
|
||||
Reference in New Issue
Block a user