Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the start function and initiated the bot in echo mode #10

Merged
merged 3 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ python = "^3.12"
django = "^5.0.4"
python-telegram-bot = "^21.1.1"
poetry-plugin-export = "^1.7.1"
django-asgi-lifespan = "^0.3.1"


[build-system]
Expand Down
19 changes: 19 additions & 0 deletions src/bot/apps.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
from django.apps import AppConfig
from django_asgi_lifespan.signals import asgi_shutdown


class BotConfig(AppConfig):
"""Configuration class for the bot application."""

default_auto_field = "django.db.models.BigAutoField"
name = "bot"

def stop_bot(self, **kwargs):
self.bot.stop()

def ready(self) -> None:
"""Perform actions when the application is ready."""
import os

if os.environ.get('RUN_MAIN', None) != 'true':
from bot.bot_interface import Bot

self.bot = Bot()

asgi_shutdown.connect(self.stop_bot)

self.bot.start()
55 changes: 55 additions & 0 deletions src/bot/bot_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import asyncio
import signal
import threading

from django.conf import settings
from telegram.ext import ApplicationBuilder

from bot.handlers import start_handler, echo_handler


class Bot:
"""A class representing a Telegram bot."""

def __init__(self):
"""Initialize the bot."""
self._app: None
self._stop_event = threading.Event()

def start(self):
merkme marked this conversation as resolved.
Show resolved Hide resolved
"""Starts the bot in a separate thread and sets up signal handling."""
self._stop_event.clear()
bot_thread = threading.Thread(target=self._run)
bot_thread.start()
signal.signal(signal.SIGINT, self._handle_sigint)

def stop(self):
"""Stop the bot."""
self._stop_event.set()

async def _build_app(self):
"""Build the application."""
app = ApplicationBuilder().token(settings.TELEGRAM_TOKEN).build()
app.add_handler(start_handler)
app.add_handler(echo_handler)
return app

def _run(self):
"""Run the bot."""
asyncio.set_event_loop(asyncio.new_event_loop())
asyncio.get_event_loop().run_until_complete(self._start_bot())

async def _start_bot(self):
"""Start the bot."""
self._app = await self._build_app()
await self._app.initialize()
await self._app.updater.start_polling()
await self._app.start()
while not self._stop_event.is_set():
await asyncio.sleep(1)

await self._app.stop()

def _handle_sigint(self, signum, frame):
"""Handle pressing CTRL+C in terminal."""
self.stop()
31 changes: 31 additions & 0 deletions src/bot/handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from telegram import Update
from telegram.ext import (
filters,
ContextTypes,
CommandHandler,
MessageHandler
)

from core.logging import log_errors


async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

То есть скрипт test.py случайно попал? Теперь понял) Но комментарии к нему сюда тогда относятся

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, абсолютно случайно попал сюда файл test.py, я пытался вне django запустить бота и проверить его функционал) забыл удалить файл. Комментарии все применил.

"""Handler for the /start command."""
await context.bot.send_message(
chat_id=update.effective_chat.id,
text=(
'Привет, я бот онлайн школы GoodStart.\n\n'
'Здесь ты найдёшь лучших преподавателей.')
)


@log_errors
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handler for echoing user messages."""
await context.bot.send_message(
chat_id=update.effective_chat.id,
text=update.message.text
)

start_handler = CommandHandler('start', start)
echo_handler = MessageHandler(filters.TEXT & (~filters.COMMAND), echo)
1 change: 1 addition & 0 deletions src/core/logging/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from core.logging.logger import log_errors # noqa
10 changes: 10 additions & 0 deletions src/core/logging/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
def log_errors(f):
"""Decorator to log errors raised by the decorated function."""
def inner(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception as e:
error_message = f'Произошла ошибка: {e}'
print(error_message)
raise e
return inner
2 changes: 2 additions & 0 deletions src/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,5 @@
STATIC_URL = "static/"

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

TELEGRAM_TOKEN = 'нужно импортировать из environ'
merkme marked this conversation as resolved.
Show resolved Hide resolved