From 460123ef2842a57f21181c2968c722f98ae3a1b9 Mon Sep 17 00:00:00 2001 From: Dmitry Afanasyev <71835315+Balshgit@users.noreply.github.com> Date: Fri, 22 Dec 2023 04:05:15 +0300 Subject: [PATCH] add bug report action (#71) * add bug report * add admin section to env --- bot_microservice/constants.py | 6 +++ bot_microservice/core/bot/commands.py | 27 +++++++++++--- bot_microservice/core/bot/handlers.py | 8 +++- bot_microservice/settings/.env.template | 2 + bot_microservice/settings/config.py | 1 + .../tests/integration/bot/test_bot_updates.py | 37 +++++++++++++++++-- .../tests/integration/factories/bot.py | 2 +- 7 files changed, 71 insertions(+), 12 deletions(-) diff --git a/bot_microservice/constants.py b/bot_microservice/constants.py index 0d0d12d..0b7159d 100644 --- a/bot_microservice/constants.py +++ b/bot_microservice/constants.py @@ -22,6 +22,12 @@ class BotStagesEnum(StrEnum): help = "help" +class BotCommands(StrEnum): + help = "help" + bug_report = "bug_report" + website = "website" + + class BotEntryPoints(StrEnum): start_routes = "start_routes" end = "end" diff --git a/bot_microservice/core/bot/commands.py b/bot_microservice/core/bot/commands.py index 3f7f506..29cc597 100644 --- a/bot_microservice/core/bot/commands.py +++ b/bot_microservice/core/bot/commands.py @@ -6,7 +6,8 @@ from loguru import logger from telegram import InlineKeyboardMarkup, Update from telegram.ext import ContextTypes -from constants import BotEntryPoints +from constants import BotCommands, BotEntryPoints +from core.bot.app import get_bot from core.bot.keyboards import main_keyboard from core.bot.services import ChatGptService, SpeechToTextService from settings.config import settings @@ -36,9 +37,7 @@ async def about_bot(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: chatgpt_service = ChatGptService.build() model = await chatgpt_service.get_current_chatgpt_model() await update.effective_message.reply_text( - f"Бот использует бесплатную модель *{model}* для ответов на вопросы.\nПринимает запросы на разных языках." - f"\n\nБот так же умеет переводить русские голосовые сообщения в текст. Просто пришлите или перешлите " - f"голосовуху боту и получите поток сознания в виде текста, но без знаков препинания.", + f"Бот использует бесплатную модель *{model}* для ответов на вопросы.\nПринимает запросы на разных языках.", parse_mode="Markdown", ) @@ -64,6 +63,20 @@ async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No ) +async def bug_report(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Send a message when the command /bug-report is issued.""" + + if not update.effective_message: + return + async with get_bot(settings.TELEGRAM_API_TOKEN) as bot: + await bot.send_message(chat_id=settings.ADMIN_CHAT_ID, text=f"Bug report from user: {update.effective_user}") + await update.effective_message.reply_text( + f"Спасибо за баг репорт.\n" + f"Можете попробовать воспользоваться веб версией /{BotCommands.website}, выбрав различные GPT модели", + parse_mode="Markdown", + ) + + async def github(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: """Send a message when the command /help is issued.""" @@ -79,7 +92,11 @@ async def ask_question(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No if not update.message: return - await update.message.reply_text("Пожалуйста, подождите, ответ в среднем занимает 10-15 секунд") + await update.message.reply_text( + f"Ответ в среднем занимает 10-15 секунд.\n" + f"- Список команд: /{BotCommands.help}\n" + f"- Сообщить об ошибке: /{BotCommands.bug_report}", + ) chatgpt_service = ChatGptService.build() logger.warning("question asked", user=update.message.from_user, question=update.message.text) diff --git a/bot_microservice/core/bot/handlers.py b/bot_microservice/core/bot/handlers.py index 957c59a..e31e64c 100644 --- a/bot_microservice/core/bot/handlers.py +++ b/bot_microservice/core/bot/handlers.py @@ -9,11 +9,12 @@ from telegram.ext import ( filters, ) -from constants import BotEntryPoints, BotStagesEnum +from constants import BotCommands, BotEntryPoints, BotStagesEnum from core.bot.commands import ( about_bot, about_me, ask_question, + bug_report, github, help_command, start_command, @@ -32,7 +33,10 @@ class BotEventHandlers: bot_event_handlers = BotEventHandlers() -bot_event_handlers.add_handler(CommandHandler("help", help_command)) +bot_event_handlers.add_handler(CommandHandler(BotCommands.help, help_command)) +bot_event_handlers.add_handler(CommandHandler(BotCommands.website, website)) +bot_event_handlers.add_handler(CommandHandler(BotCommands.bug_report, bug_report)) + bot_event_handlers.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, ask_question)) bot_event_handlers.add_handler(MessageHandler(filters.VOICE | filters.AUDIO, voice_recognize)) bot_event_handlers.add_handler( diff --git a/bot_microservice/settings/.env.template b/bot_microservice/settings/.env.template index c701cc8..b7a3598 100644 --- a/bot_microservice/settings/.env.template +++ b/bot_microservice/settings/.env.template @@ -9,9 +9,11 @@ WORKERS_COUNT=1 RELOAD="true" DEBUG="true" +# ==== admin ===== SUPERUSER="user" SUPERUSER_PASSWORD="hackme" SALT="change me" +ADMIN_CHAT_ID="123456789" # ==== sentry ==== ENABLE_SENTRY="false" diff --git a/bot_microservice/settings/config.py b/bot_microservice/settings/config.py index 22b172c..b4db0f9 100644 --- a/bot_microservice/settings/config.py +++ b/bot_microservice/settings/config.py @@ -71,6 +71,7 @@ class AppSettings(SentrySettings, LoggingSettings, BaseSettings): SUPERUSER: str | None = None SUPERUSER_PASSWORD: SecretStr | None = None SALT: SecretStr | None = None + ADMIN_CHAT_ID: int | None = None # telegram settings TELEGRAM_API_TOKEN: str = "123456789:AABBCCDDEEFFaabbccddeeff-1234567890" diff --git a/bot_microservice/tests/integration/bot/test_bot_updates.py b/bot_microservice/tests/integration/bot/test_bot_updates.py index 6d585ee..9d48213 100644 --- a/bot_microservice/tests/integration/bot/test_bot_updates.py +++ b/bot_microservice/tests/integration/bot/test_bot_updates.py @@ -210,9 +210,7 @@ async def test_about_bot_callback_action( assert mocked_reply_text.call_args.args == ( f"Бот использует бесплатную модель *{model_with_highest_priority.model}* для ответов на вопросы.\n" - f"Принимает запросы на разных языках.\n\nБот так же умеет переводить русские голосовые сообщения в текст. " - f"Просто пришлите или перешлите голосовуху боту и получите поток сознания в виде текста, " - f"но без знаков препинания.", + f"Принимает запросы на разных языках.", ) assert mocked_reply_text.call_args.kwargs == {"parse_mode": "Markdown"} @@ -234,6 +232,35 @@ async def test_website_callback_action( assert mocked_reply_text.call_args.args == ("Веб версия: http://localhost/chat/",) +async def test_bug_report_action( + main_application: Application, + test_settings: AppSettings, +) -> None: + with ( + mock.patch.object(telegram._message.Message, "reply_text") as mocked_reply_text, + mock.patch.object( + telegram._bot.Bot, "send_message", return_value=lambda *args, **kwargs: (args, kwargs) + ) as mocked_send_message, + ): + bot_update = BotUpdateFactory(message=BotMessageFactory.create_instance(text="/bug_report")) + + await main_application.bot_app.application.process_update( + update=Update.de_json(data=bot_update, bot=main_application.bot_app.bot) + ) + + assert mocked_reply_text.call_args.args == ( + "Спасибо за баг репорт.\n" + "Можете попробовать воспользоваться веб версией /website, выбрав различные GPT модели", + ) + from_user = bot_update["message"]["from"] + assert mocked_send_message.call_args.kwargs["text"] == ( + f"Bug report from user: " + f"User(first_name='{from_user['first_name']}', id={from_user['id']}, is_bot={from_user['is_bot']}, " + f"language_code='{from_user['language_code']}', last_name='{from_user['last_name']}', " + f"username='{from_user['username']}')" + ) + + async def test_ask_question_action( dbsession: Session, main_application: Application, @@ -254,7 +281,9 @@ async def test_ask_question_action( ) assert_that(mocked_send_message.call_args_list[0].kwargs).is_equal_to( { - "text": "Пожалуйста, подождите, ответ в среднем занимает 10-15 секунд", + "text": ( + "Ответ в среднем занимает 10-15 секунд.\n- Список команд: /help\n- Сообщить об ошибке: /bug_report" + ), "chat_id": bot_update["message"]["chat"]["id"], }, include=["text", "chat_id"], diff --git a/bot_microservice/tests/integration/factories/bot.py b/bot_microservice/tests/integration/factories/bot.py index 472efff..687ebb5 100644 --- a/bot_microservice/tests/integration/factories/bot.py +++ b/bot_microservice/tests/integration/factories/bot.py @@ -84,7 +84,7 @@ class BotInfoFactory(factory.DictFactory): class BotEntitleFactory(factory.DictFactory): type = "bot_command" offset = 0 - length = 7 + length = 42 class BotMessageFactory(factory.DictFactory):