Init project
This commit is contained in:
13
birthday_pool_bot/notifications/__init__.py
Normal file
13
birthday_pool_bot/notifications/__init__.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from .cli import get_cli
|
||||
from .service import NotificationsService
|
||||
from .settings import NotificationsSettings
|
||||
|
||||
|
||||
__all__ = (
|
||||
# cli
|
||||
"get_cli",
|
||||
# service
|
||||
"NotificationsService",
|
||||
# settings
|
||||
"NotificationsSettings",
|
||||
)
|
||||
44
birthday_pool_bot/notifications/cli.py
Normal file
44
birthday_pool_bot/notifications/cli.py
Normal file
@@ -0,0 +1,44 @@
|
||||
import asyncio
|
||||
|
||||
import typer
|
||||
|
||||
from .service import NotificationsService
|
||||
from .settings import NotificationsSettings
|
||||
|
||||
|
||||
def callback(ctx: typer.Context):
|
||||
ctx.obj["settings"] = ctx.obj["settings"].notifications
|
||||
|
||||
|
||||
def run(ctx: typer.Context):
|
||||
settings: NotificationsSettings = ctx.obj["settings"]
|
||||
repositories_container: RepositoriesContainer = ctx.obj["repositories_container"]
|
||||
|
||||
service = NotificationsService(
|
||||
settings=settings,
|
||||
repositories_container=repositories_container,
|
||||
)
|
||||
|
||||
asyncio.run(service.run())
|
||||
|
||||
|
||||
def run_once(ctx: typer.Context):
|
||||
settings: NotificationsSettings = ctx.obj["settings"]
|
||||
repositories_container: RepositoriesContainer = ctx.obj["repositories_container"]
|
||||
|
||||
service = NotificationsService(
|
||||
settings=settings,
|
||||
repositories_container=repositories_container,
|
||||
)
|
||||
|
||||
asyncio.run(service.send_notifications())
|
||||
|
||||
|
||||
def get_cli() -> typer.Typer:
|
||||
cli = typer.Typer()
|
||||
|
||||
cli.callback()(callback)
|
||||
cli.command(name="run")(run)
|
||||
cli.command(name="run-once")(run_once)
|
||||
|
||||
return cli
|
||||
81
birthday_pool_bot/notifications/service.py
Normal file
81
birthday_pool_bot/notifications/service.py
Normal file
@@ -0,0 +1,81 @@
|
||||
from datetime import date, timedelta
|
||||
|
||||
import facet
|
||||
from aiogram import Bot
|
||||
from aiogram.enums import ParseMode
|
||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
|
||||
from .settings import NotificationsSettings
|
||||
|
||||
|
||||
class NotificationsService(facet.AsyncioServiceMixin):
|
||||
def __init__(
|
||||
self,
|
||||
settings: NotificationsSettings,
|
||||
repositories_container: RepositoriesContainer,
|
||||
):
|
||||
self._settings = settings
|
||||
self._repositories_container = repositories_container
|
||||
self._bot = Bot(token=self._settings.telegram_bot_token)
|
||||
|
||||
async def start(self):
|
||||
scheduler = AsyncIOScheduler()
|
||||
scheduler.add_job(
|
||||
func=self.send_notifications,
|
||||
name="send_notifications",
|
||||
trigger=CronTrigger.from_crontab(self._settings.cron),
|
||||
)
|
||||
scheduler.start()
|
||||
|
||||
async def send_notifications(self):
|
||||
birthday = date.today() + timedelta(days=2)
|
||||
|
||||
users_repository = self._repositories_container.users
|
||||
subscriptions_repository = self._repositories_container.subscriptions
|
||||
|
||||
async with users_repository.transaction():
|
||||
users = await users_repository.get_users_by_birthdays(
|
||||
birthday=birthday,
|
||||
)
|
||||
if not users:
|
||||
return
|
||||
|
||||
async with subscriptions_repository.transaction():
|
||||
subscriptions = await subscriptions_repository.get_to_users_subscriptions(
|
||||
to_users_ids={user.id for user in users},
|
||||
with_from_user=True,
|
||||
with_to_user=True,
|
||||
with_pool=True,
|
||||
)
|
||||
if not subscriptions:
|
||||
return
|
||||
|
||||
for subscription in subscriptions:
|
||||
if subscription.from_user.telegram_id is None:
|
||||
continue
|
||||
|
||||
text = (
|
||||
f"У {subscription.name} скоро день рождения: *{birthday.strftime('%d %B')}*\n\n"
|
||||
)
|
||||
if subscription.pool is not None:
|
||||
if subscription.pool.owner_id == subscription.from_user.id:
|
||||
text += "Вы собираете деньги на подарок\n\n"
|
||||
else:
|
||||
text += (
|
||||
"Вы подписаны на сбор денег для подарка, вы можете отправить их сюда:\n"
|
||||
f"_Телефон_: {subscription.pool.payment_data.phone}\n"
|
||||
f"_Банк_: {subscription.pool.payment_data.bank.value}\n\n"
|
||||
)
|
||||
elif subscription.to_user.gift_payment_data is not None:
|
||||
text += (
|
||||
f"Вы можете отправить именнинику свой подарок сюда:\n"
|
||||
f"_Телефон_: {subscription.to_user.gift_payment_data.phone}\n"
|
||||
f"_Банк_: {subscription.to_user.gift_payment_data.bank.value}\n\n"
|
||||
)
|
||||
|
||||
await self._bot.send_message(
|
||||
text=text,
|
||||
parse_mode=ParseMode.MARKDOWN,
|
||||
chat_id=subscription.from_user.telegram_id,
|
||||
)
|
||||
6
birthday_pool_bot/notifications/settings.py
Normal file
6
birthday_pool_bot/notifications/settings.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class NotificationsSettings(BaseModel):
|
||||
cron: str = "0 12 * * *"
|
||||
telegram_bot_token: str = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
|
||||
Reference in New Issue
Block a user