Files
chatbottren/bot.py

83 lines
2.7 KiB
Python
Raw Normal View History

2026-02-16 10:45:01 +05:00
"""Telegram-бот: текстовые и голосовые сообщения → LLM → ответ."""
import asyncio
import logging
import tempfile
from pathlib import Path
from aiogram import Bot, Dispatcher, F, Router
from aiogram.types import Message
import config
from config import get_gitea_username
from llm_handler import process_message
from transcribe import transcribe_audio
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
config.validate()
bot = Bot(token=config.TELEGRAM_BOT_TOKEN)
dp = Dispatcher()
router = Router()
dp.include_router(router)
@router.message(F.text)
async def on_text(message: Message) -> None:
text = (message.text or "").strip()
if not text:
return
gitea_username = get_gitea_username(
message.from_user.username if message.from_user else None,
message.from_user.id if message.from_user else None,
)
try:
reply = await asyncio.wait_for(process_message(text, gitea_username), timeout=60.0)
await message.answer(reply or "Готово.")
except asyncio.TimeoutError:
await message.answer("Таймаут. Попробуй короче или позже.")
except Exception as e:
logger.exception("Handler error")
await message.answer(f"Ошибка: {e!s}")
@router.message(F.voice)
async def on_voice(message: Message) -> None:
if not message.voice:
return
gitea_username = get_gitea_username(
message.from_user.username if message.from_user else None,
message.from_user.id if message.from_user else None,
)
tmp = None
try:
file = await message.bot.get_file(message.voice.file_id)
tmp = tempfile.NamedTemporaryFile(suffix=".ogg", delete=False)
tmp.close()
await message.bot.download_file(file.file_path, tmp.name)
text = await asyncio.to_thread(transcribe_audio, tmp.name)
Path(tmp.name).unlink(missing_ok=True)
tmp = None
if not (text or "").strip():
await message.answer("Не удалось распознать речь.")
return
reply = await asyncio.wait_for(process_message(text.strip(), gitea_username), timeout=60.0)
await message.answer(reply or "Готово.")
except asyncio.TimeoutError:
await message.answer("Таймаут. Попробуй короче или позже.")
except Exception as e:
logger.exception("Voice handler error")
await message.answer(f"Ошибка: {e!s}")
finally:
if tmp is not None and getattr(tmp, "name", None):
Path(tmp.name).unlink(missing_ok=True)
async def main() -> None:
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())