2023-09-26 22:04:45 +03:00

132 lines
5.3 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 asyncio
import random
import tempfile
from urllib.parse import urljoin
from uuid import uuid4
import httpx
from constants import CHAT_GPT_BASE_URL, BotEntryPoints
from core.keyboards import main_keyboard
from core.utils import SpeechToTextService
from httpx import AsyncClient, AsyncHTTPTransport
from loguru import logger
from settings.config import settings
from telegram import InlineKeyboardMarkup, Update
from telegram.ext import ContextTypes
async def main_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
"""Send message on `/start`."""
if not update.message:
return BotEntryPoints.end
reply_markup = InlineKeyboardMarkup(main_keyboard)
await update.message.reply_text("Выберете команду:", reply_markup=reply_markup)
return BotEntryPoints.start_routes
async def about_me(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not update.effective_message:
return None
await update.effective_message.reply_text(
'Автор бота: *Дмитрий Афанасьев*\n\nTg nickname: *Balshtg*', parse_mode='MarkdownV2'
)
async def about_bot(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not update.effective_message:
return None
await update.effective_message.reply_text(
"Бот использует бесплатную модель Chat-GPT3.5 для ответов на вопросы. "
"Принимает запросы на разных языках. \n\n Бот так же умеет переводить голосовые сообщения в текст"
"просто пришлите голосовуху и получите поток сознания без запятых в виде текста",
parse_mode='MarkdownV2',
)
async def website(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not update.effective_message:
return None
website = urljoin(settings.DOMAIN, f"{settings.URL_PREFIX}/chat")
await update.effective_message.reply_text(f"Веб версия: {website}")
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Send a message when the command /help is issued."""
if not update.effective_message:
return None
reply_markup = InlineKeyboardMarkup(main_keyboard)
await update.effective_message.reply_text(
"Help!",
disable_notification=True,
api_kwargs={"text": "Список основных команд:"},
reply_markup=reply_markup,
)
async def ask_question(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not update.message:
return None
await update.message.reply_text("Пожалуйста подождите, ответ в среднем занимает 10-15 секунд")
chat_gpt_request = {
"conversation_id": str(uuid4()),
"action": "_ask",
"model": settings.GPT_MODEL,
"jailbreak": "default",
"meta": {
"id": random.randint(10**18, 10**19 - 1), # noqa: S311
"content": {
"conversation": [],
"internet_access": False,
"content_type": "text",
"parts": [{"content": update.message.text, "role": "user"}],
},
},
}
transport = AsyncHTTPTransport(retries=3)
async with AsyncClient(transport=transport, timeout=50) as client:
try:
response = await client.post(CHAT_GPT_BASE_URL, json=chat_gpt_request, timeout=50)
status = response.status_code
if status != httpx.codes.OK:
logger.info(f'got response status: {status} from chat api', data=chat_gpt_request)
await update.message.reply_text(
"Что-то пошло не так, попробуйте еще раз или обратитесь к администратору"
)
return
await update.message.reply_text(response.text)
except Exception as error:
logger.error("error get data from chat api", error=error)
await update.message.reply_text("Вообще всё сломалось :(")
async def voice_recognize(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not update.message:
return None
await update.message.reply_text("Пожалуйста, ожидайте :)\nТрехминутная запись обрабатывается примерно 30 секунд")
if not update.message.voice:
return None
sound_file = await update.message.voice.get_file()
sound_bytes = await sound_file.download_as_bytearray()
with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
tmpfile.write(sound_bytes)
logger.info('file has been saved', filename=tmpfile.name)
speech_to_text_service = SpeechToTextService(filename=tmpfile.name)
speech_to_text_service.get_text_from_audio()
part = 0
while speech_to_text_service.text_parts or not speech_to_text_service.text_recognised:
if text := speech_to_text_service.text_parts.get(part):
speech_to_text_service.text_parts.pop(part)
await update.message.reply_text(text)
part += 1
await asyncio.sleep(5)