From 70696ae067e8e46bc31734c17c6ea86c18796c16 Mon Sep 17 00:00:00 2001 From: jsdio Date: Sat, 14 Oct 2023 01:12:02 +0300 Subject: [PATCH] feat: [#49] minimally functioning bot --- src/bot_aiogram/.env.example | 4 +++- src/bot_aiogram/Dockerfile | 13 +++++++++--- src/bot_aiogram/docker-compose.yml | 2 +- src/bot_aiogram/poetry.lock | 17 ++++++++++++++- src/bot_aiogram/pyproject.toml | 1 + src/bot_aiogram/requirements.txt | 3 --- src/bot_aiogram/tgbot/handlers/voice.py | 23 ++++++++++++++++++--- src/bot_aiogram/tgbot/settings.py | 5 ++--- src/bot_aiogram/tgbot/split_settings/api.py | 6 +++--- 9 files changed, 56 insertions(+), 18 deletions(-) delete mode 100644 src/bot_aiogram/requirements.txt diff --git a/src/bot_aiogram/.env.example b/src/bot_aiogram/.env.example index 4a056de..65bcf75 100644 --- a/src/bot_aiogram/.env.example +++ b/src/bot_aiogram/.env.example @@ -1,9 +1,11 @@ BOT_CONTAINER_NAME=bot_container_name BOT_IMAGE_NAME=botimage_name BOT_NAME=mybotname + +# required parameters BOT_TOKEN=123456:Your-TokEn_ExaMple BOT_ADMINS=123456,654321 API_PROTOCOL=http -API_URL=127.0.0.1 +API_URL=api API_PORT=8000 diff --git a/src/bot_aiogram/Dockerfile b/src/bot_aiogram/Dockerfile index a92a6aa..4c1780d 100755 --- a/src/bot_aiogram/Dockerfile +++ b/src/bot_aiogram/Dockerfile @@ -1,8 +1,15 @@ -FROM python:3.9-buster +FROM python:3.11 ENV BOT_NAME=$BOT_NAME WORKDIR /usr/src/app/"${BOT_NAME:-tg_bot}" -COPY requirements.txt /usr/src/app/"${BOT_NAME:-tg_bot}" -RUN pip install -r /usr/src/app/"${BOT_NAME:-tg_bot}"/requirements.txt +COPY pyproject.toml /usr/src/app/"${BOT_NAME:-tg_bot}"/pyproject.toml +COPY poetry.lock /usr/src/app/"${BOT_NAME:-tg_bot}"//poetry.lock +COPY poetry.toml /usr/src/app/"${BOT_NAME:-tg_bot}"/poetry.toml + +WORKDIR /usr/src/app/"${BOT_NAME:-tg_bot}" + +RUN pip install poetry \ + && poetry install --no-dev + COPY . /usr/src/app/"${BOT_NAME:-tg_bot}" diff --git a/src/bot_aiogram/docker-compose.yml b/src/bot_aiogram/docker-compose.yml index c23fdfd..c8ef5c6 100755 --- a/src/bot_aiogram/docker-compose.yml +++ b/src/bot_aiogram/docker-compose.yml @@ -10,7 +10,7 @@ services: working_dir: "/usr/src/app/${BOT_NAME:-tg_bot}" volumes: - .:/usr/src/app/${BOT_NAME:-tg_bot} - command: python3 -m bot + command: poetry run python bot.py restart: always env_file: - ".env" diff --git a/src/bot_aiogram/poetry.lock b/src/bot_aiogram/poetry.lock index 7c5b8b8..b1786ff 100644 --- a/src/bot_aiogram/poetry.lock +++ b/src/bot_aiogram/poetry.lock @@ -907,6 +907,21 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "pydantic-settings" +version = "2.0.3" +description = "Settings management using Pydantic" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic_settings-2.0.3-py3-none-any.whl", hash = "sha256:ddd907b066622bd67603b75e2ff791875540dc485b7307c4fffc015719da8625"}, + {file = "pydantic_settings-2.0.3.tar.gz", hash = "sha256:962dc3672495aad6ae96a4390fac7e593591e144625e5112d359f8f67fb75945"}, +] + +[package.dependencies] +pydantic = ">=2.0.1" +python-dotenv = ">=0.21.0" + [[package]] name = "pylint" version = "2.17.7" @@ -1346,4 +1361,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "6a4d557aec6dcef7c790b3838d67c294ac771255d2967b05d8b6745fd81419cd" +content-hash = "afc5943d3cbf03dd9b7103acb8a74e8750b22fc3b98c50efa21c3ea5f2739483" diff --git a/src/bot_aiogram/pyproject.toml b/src/bot_aiogram/pyproject.toml index 521ac59..da0f281 100644 --- a/src/bot_aiogram/pyproject.toml +++ b/src/bot_aiogram/pyproject.toml @@ -22,6 +22,7 @@ version = "0.1.0" [tool.poetry.dependencies] aiogram = "~2.18" environs = "~9.0" +pydantic-settings = "^2.0.3" pytest-asyncio = "^0.21.1" python = "^3.11" diff --git a/src/bot_aiogram/requirements.txt b/src/bot_aiogram/requirements.txt deleted file mode 100644 index 7105c4d..0000000 --- a/src/bot_aiogram/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -aiogram~=2.18 -aioredis<2.0 -environs~=9.0 diff --git a/src/bot_aiogram/tgbot/handlers/voice.py b/src/bot_aiogram/tgbot/handlers/voice.py index 4fa8faa..1645010 100644 --- a/src/bot_aiogram/tgbot/handlers/voice.py +++ b/src/bot_aiogram/tgbot/handlers/voice.py @@ -1,4 +1,5 @@ import io +import typing import aiogram import aiohttp @@ -7,26 +8,42 @@ import tgbot.settings as tgbot_settings async def voice_response(message_voice: aiogram.types.Message): - config: tgbot_settings.Settings = message_voice.bot.get("config") + config = typing.cast(tgbot_settings.Settings, message_voice.bot.get("config")) + voice_file_id: str = message_voice.voice.file_id file_info = await message_voice.bot.get_file(voice_file_id) file_path: str = file_info.file_path voice_data: io.BytesIO = io.BytesIO() voice_data.name = "voice.ogg" voice_data.seek(0) + await message_voice.bot.download_file(file_path, destination=voice_data) await message_voice.bot.send_chat_action(message_voice.from_user.id, "typing") + async with aiohttp.ClientSession() as session: async with session.post( f"{config.api.api_url}/api/v1/voice/", data={"voice": voice_data}, ) as resp: if resp.status == 200: - voice_answer = await resp.read() - await message_voice.answer_voice(voice_answer) + voice_answer: bytes = await resp.read() + answer_io = io.BytesIO(voice_answer) + answer_io.name = "answer_io.ogg" + + await message_voice.bot.send_chat_action( + message_voice.from_user.id, action=aiogram.types.ChatActions.RECORD_AUDIO + ) + + try: + await message_voice.answer_voice(voice=answer_io) + except aiogram.exceptions.BadRequest: + await message_voice.answer( + "We were unable to send you a voice message. Please check your privacy settings." + ) else: await message_voice.answer("Not recognized text") await session.close() + return def register_voice_response(dp: aiogram.Dispatcher): diff --git a/src/bot_aiogram/tgbot/settings.py b/src/bot_aiogram/tgbot/settings.py index 9769600..dee68d3 100644 --- a/src/bot_aiogram/tgbot/settings.py +++ b/src/bot_aiogram/tgbot/settings.py @@ -1,9 +1,8 @@ -import pydantic import pydantic_settings import tgbot.split_settings as app_split_settings class Settings(pydantic_settings.BaseSettings): - api: app_split_settings.ApiSettings = pydantic.Field(default_factory=app_split_settings.ApiSettings) - tgbot: app_split_settings.TgBotSettings = pydantic.Field(default_factory=app_split_settings.TgBotSettings) + api: app_split_settings.ApiSettings = app_split_settings.ApiSettings() + tgbot: app_split_settings.TgBotSettings = app_split_settings.TgBotSettings() diff --git a/src/bot_aiogram/tgbot/split_settings/api.py b/src/bot_aiogram/tgbot/split_settings/api.py index 68bb82b..4bae8a3 100644 --- a/src/bot_aiogram/tgbot/split_settings/api.py +++ b/src/bot_aiogram/tgbot/split_settings/api.py @@ -11,9 +11,9 @@ class ApiSettings(pydantic_settings.BaseSettings): extra="ignore", ) - url: str - port: int - protocol: str + url: str = "127.0.0.1" + port: int = 8000 + protocol: str = "http" @property def api_url(self) -> str: