Skip to content
This repository was archived by the owner on Nov 2, 2025. It is now read-only.

Commit d489ca4

Browse files
committed
Fix datetime and locale in subscription expiry task
1 parent b5960c7 commit d489ca4

File tree

2 files changed

+30
-18
lines changed

2 files changed

+30
-18
lines changed

app/__main__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from aiogram.utils.i18n import I18n
1111
from aiogram.webhook.aiohttp_server import SimpleRequestHandler, setup_application
1212
from aiohttp.web import Application, _run_app
13+
from redis.asyncio.client import Redis
1314

1415
from app import logger
1516
from app.bot import filters, middlewares, routers, services, tasks
@@ -42,7 +43,8 @@ async def on_startup(
4243
bot: Bot,
4344
services: ServicesContainer,
4445
db: Database,
45-
storage: RedisStorage,
46+
redis: Redis,
47+
i18n: I18n,
4648
) -> None:
4749
webhook_url = urljoin(config.bot.DOMAIN, TELEGRAM_WEBHOOK)
4850

@@ -62,7 +64,8 @@ async def on_startup(
6264
)
6365
tasks.subscription_expiry.start_scheduler(
6466
session_factory=db.session,
65-
storage=storage,
67+
redis=redis,
68+
i18n=i18n,
6669
vpn_service=services.vpn,
6770
notification_service=services.notification,
6871
)
@@ -132,6 +135,8 @@ async def main() -> None:
132135
bot=bot,
133136
services=services_container,
134137
gateway_factory=gateway_factory,
138+
redis=storage.redis,
139+
i18n=i18n,
135140
)
136141

137142
# Register event handlers
Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import logging
2-
import time
3-
from datetime import datetime, timedelta
2+
from datetime import datetime, timedelta, timezone
43

5-
from aiogram.fsm.storage.redis import RedisStorage
6-
from aiogram.utils.i18n import lazy_gettext as __
4+
from aiogram.utils.i18n import I18n
75
from apscheduler.schedulers.asyncio import AsyncIOScheduler
6+
from redis.asyncio.client import Redis
87
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
98

109
from app.bot.services import NotificationService, VPNService
@@ -15,7 +14,8 @@
1514

1615
async def notify_users_with_expiring_subscription(
1716
session_factory: async_sessionmaker,
18-
storage: RedisStorage,
17+
redis: Redis,
18+
i18n: I18n,
1919
vpn_service: VPNService,
2020
notification_service: NotificationService,
2121
) -> None:
@@ -31,7 +31,7 @@ async def notify_users_with_expiring_subscription(
3131
user_notified_key = f"user:notified:{user.tg_id}"
3232

3333
# Check if user was recently notified
34-
if await storage.redis.get(user_notified_key):
34+
if await redis.get(user_notified_key):
3535
continue
3636

3737
client_data = await vpn_service.get_client_data(user)
@@ -40,25 +40,31 @@ async def notify_users_with_expiring_subscription(
4040
if not client_data or client_data._expiry_time == -1:
4141
continue
4242

43-
current_time_ms = time.time() * 1000
44-
time_left_ms = client_data._expiry_time - current_time_ms
45-
threshold_ms = timedelta(hours=24).total_seconds() * 1000
43+
now = datetime.now(timezone.utc)
44+
expiry_datetime = datetime.fromtimestamp(
45+
client_data._expiry_time / 1000, timezone.utc
46+
)
47+
time_left = expiry_datetime - now
4648

4749
# Skip if not within the notification threshold
48-
if not (0 < time_left_ms <= threshold_ms):
50+
if not (timedelta(0) < time_left <= timedelta(hours=24)):
4951
continue
5052

51-
# Send notification and set Redis flag
53+
# BUG: The button and expiry_time will not be translated
54+
# (the translation logic needs to be changed outside the current context)
5255
await notification_service.notify_by_id(
5356
chat_id=user.tg_id,
54-
text=__("task:message:subscription_expiry").format(
57+
text=i18n.gettext(
58+
"task:message:subscription_expiry",
59+
locale=user.language_code,
60+
).format(
5561
devices=client_data.max_devices,
5662
expiry_time=client_data.expiry_time,
5763
),
5864
# reply_markup=keyboard_extend
5965
)
6066

61-
await storage.redis.set(user_notified_key, "true", ex=timedelta(hours=24))
67+
await redis.set(user_notified_key, "true", ex=timedelta(hours=24))
6268
logger.info(
6369
f"[Background task] Sent expiry notification to user {user.tg_id}."
6470
)
@@ -67,7 +73,8 @@ async def notify_users_with_expiring_subscription(
6773

6874
def start_scheduler(
6975
session_factory: async_sessionmaker,
70-
storage: RedisStorage,
76+
redis: Redis,
77+
i18n: I18n,
7178
vpn_service: VPNService,
7279
notification_service: NotificationService,
7380
) -> None:
@@ -76,7 +83,7 @@ def start_scheduler(
7683
notify_users_with_expiring_subscription,
7784
"interval",
7885
minutes=15,
79-
args=[session_factory, storage, vpn_service, notification_service],
80-
next_run_time=datetime.now(),
86+
args=[session_factory, redis, i18n, vpn_service, notification_service],
87+
next_run_time=datetime.now(tz=timezone.utc),
8188
)
8289
scheduler.start()

0 commit comments

Comments
 (0)