Files
ayako/bot.py

111 lines
4.7 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.
import os
import logging
import httpx
from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command, CommandObject
from aiogram.client.default import DefaultBotProperties
from aiogram.enums import ParseMode
TOKEN = os.getenv("TELEGRAM_TOKEN")
API_URL = os.getenv("VNDB_API_URL", "https://api.vndb.org/kana")
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
bot = Bot(token=TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))
dp = Dispatcher()
async def fetch_vndb(endpoint: str, filters: list, fields: str):
payload = {"filters": filters, "fields": fields}
async with httpx.AsyncClient(timeout=10.0) as client:
try:
response = await client.post(f"{API_URL}/{endpoint}", json=payload)
if response.status_code == 200:
return response.json().get("results", [])
logger.error(f"VNDB Error {response.status_code} on {endpoint}: {response.text}")
return None
except Exception as e:
logger.error(f"Request failed: {e}")
return None
@dp.message(Command("start", "help"))
async def cmd_help(message: types.Message):
await message.answer(
"🤖 <b>VNDB Bot</b>\n\n"
"• /vn &lt;id или название&gt;\n"
"• /char &lt;id или название&gt;\n"
"• /release &lt;id или название&gt;"
)
@dp.message(Command("vn"))
async def handle_vn(message: types.Message, command: CommandObject):
if not command.args: return await message.answer("Введите название или ID (v17)")
# Если это ID (начинается с 'v' + цифры)
if command.args.startswith('v') and command.args[1:].isdigit():
filt = ["id", "=", command.args]
else:
filt = ["search", "=", command.args]
# Важно: для VN используем alttitle вместо original
res = await fetch_vndb("vn", filt, "id, title, alttitle, released, rating, votecount")
if not res: return await message.answer("❌ Ничего не найдено.")
if len(res) > 1 and not command.args.startswith('v'):
out = ["🔍 <b>Результаты поиска:</b>"]
for i in res[:10]:
out.append(f"{i['title']} (<code>{i['id']}</code>)")
return await message.answer("\n".join(out))
v = res[0]
rating = f"{v['rating']/10}" if v.get('rating') else "N/A"
text = (f"📖 <b>{v['title']}</b>\n"
f"Original: {v.get('alttitle', 'N/A')}\n"
f"Released: {v.get('released', 'N/A')}\n"
f"Rating: {rating} ({v.get('votecount', 0)} votes)\n"
f"https://vndb.org/{v['id']}")
await message.answer(text)
@dp.message(Command("char"))
async def handle_char(message: types.Message, command: CommandObject):
if not command.args: return await message.answer("Введите имя или ID (c1)")
filt = ["id", "=", command.args] if command.args.startswith('c') and command.args[1:].isdigit() else ["search", "=", command.args]
# Для персонажей original работает
res = await fetch_vndb("character", filt, "id, name, original")
if not res: return await message.answer("Не найдено.")
if len(res) > 1 and not command.args.startswith('c'):
out = ["👤 <b>Персонажи:</b>"]
for i in res[:10]: out.append(f"{i['name']} (<code>{i['id']}</code>)")
return await message.answer("\n".join(out))
c = res[0]
await message.answer(f"👤 <b>{c['name']}</b>\nOriginal: {c.get('original', 'N/A')}\nhttps://vndb.org/{c['id']}")
@dp.message(Command("release"))
async def handle_rel(message: types.Message, command: CommandObject):
if not command.args: return await message.answer("Введите название или ID (r1)")
filt = ["id", "=", command.args] if command.args.startswith('r') and command.args[1:].isdigit() else ["search", "=", command.args]
res = await fetch_vndb("release", filt, "id, title, alttitle, released")
if not res: return await message.answer("Не найдено.")
if len(res) > 1 and not command.args.startswith('r'):
out = ["💿 <b>Релизы:</b>"]
for i in res[:10]: out.append(f"{i['title']} (<code>{i['id']}</code>)")
return await message.answer("\n".join(out))
r = res[0]
await message.answer(f"💿 <b>{r['title']}</b>\nReleased: {r.get('released', 'N/A')}\nhttps://vndb.org/{r['id']}")
# Прямые команды поиска (алиасы для удобства)
@dp.message(Command("search"))
async def search_alias(message: types.Message, command: CommandObject):
await handle_vn(message, command)
if __name__ == "__main__":
dp.run_polling(bot)