save blocked users in sender service

This commit is contained in:
Vladless
2026-02-28 19:18:07 +03:00
parent 0e4dfbf369
commit 630bf5069c
5 changed files with 40 additions and 18 deletions
+8 -1
View File
@@ -15,8 +15,8 @@ from sqlalchemy import distinct, exists, func, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from api.depends import get_session, verify_admin_token, verify_admin_token_short
from database import async_session_maker
from config import API_TOKEN, BOT_SERVICE
from database import async_session_maker, save_blocked_user_ids
from core.bootstrap import MANAGEMENT_CONFIG
from core.executor import run_io
from core.settings.management_config import update_management_config
@@ -212,6 +212,13 @@ async def launch_broadcast(
rate = max(1, min(int(payload.messages_per_second or 35), 60))
broadcast_service = BroadcastService(bot=bot, session=None, messages_per_second=rate)
stats = await broadcast_service.broadcast(messages, workers=workers)
blocked_ids = stats.get("blocked_user_ids") or []
if blocked_ids:
async with async_session_maker() as session:
try:
await save_blocked_user_ids(session, blocked_ids)
except Exception:
pass
return {
"success": True,
"message": "Broadcast completed",
+8 -1
View File
@@ -15,8 +15,8 @@ from sqlalchemy import distinct, exists, func, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from api.depends import get_session, verify_identity_admin, verify_identity_admin_short
from database import async_session_maker
from config import API_TOKEN, BOT_SERVICE
from database import async_session_maker, save_blocked_user_ids
from core.bootstrap import MANAGEMENT_CONFIG
from core.executor import run_io
from core.settings.management_config import update_management_config
@@ -201,6 +201,13 @@ async def launch_broadcast(
rate = max(1, min(int(payload.messages_per_second or 35), 60))
broadcast_service = BroadcastService(bot=bot, session=None, messages_per_second=rate)
stats = await broadcast_service.broadcast(messages, workers=workers)
blocked_ids = stats.get("blocked_user_ids") or []
if blocked_ids:
async with async_session_maker() as session:
try:
await save_blocked_user_ids(session, blocked_ids)
except Exception:
pass
return {
"success": True,
"message": "Broadcast completed",
+12
View File
@@ -2,9 +2,21 @@ from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.ext.asyncio import AsyncSession
from database.models import BlockedUser
from logger import logger
async def create_blocked_user(session: AsyncSession, tg_id: int):
stmt = insert(BlockedUser).values(tg_id=tg_id).on_conflict_do_nothing(index_elements=[BlockedUser.tg_id])
await session.execute(stmt)
await session.commit()
async def save_blocked_user_ids(session: AsyncSession, tg_ids: list[int]) -> None:
"""Вставка списка tg_id в таблицу BlockedUser. Вызывать только из основного event loop."""
if not tg_ids:
return
values = [{"tg_id": tg_id} for tg_id in tg_ids]
stmt = insert(BlockedUser).values(values).on_conflict_do_nothing(index_elements=[BlockedUser.tg_id])
await session.execute(stmt)
await session.commit()
logger.info(f"📝 Добавлено {len(tg_ids)} пользователей в blocked_users")
+6
View File
@@ -9,6 +9,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
from config import API_TOKEN
from core.executor import run_io, should_run_heavy_tasks_separately
from database import save_blocked_user_ids
from database.models import Server
from filters.admin import IsAdminFilter
from logger import logger
@@ -230,6 +231,11 @@ async def handle_broadcast_confirm(callback_query: CallbackQuery, state: FSMCont
state_keyboard_data,
progress_cb,
)
if stats.get("blocked_user_ids"):
try:
await save_blocked_user_ids(session, stats["blocked_user_ids"])
except Exception as e:
logger.error(f"❌ Ошибка при сохранении заблокированных пользователей: {e}")
else:
messages = []
for tg_id in tg_ids:
+6 -16
View File
@@ -12,7 +12,7 @@ from aiogram.exceptions import TelegramBadRequest, TelegramForbiddenError, Teleg
from aiogram.types import InlineKeyboardMarkup
from sqlalchemy.ext.asyncio import AsyncSession
from database import async_session_maker
from database import async_session_maker, save_blocked_user_ids
from logger import logger
@@ -208,24 +208,12 @@ class BroadcastService:
async def _save_blocked_users(self) -> None:
if not self.blocked_users:
return
async def _do_save(session: AsyncSession) -> None:
from sqlalchemy.dialects.postgresql import insert
from database.models import BlockedUser
values = [{"tg_id": tg_id} for tg_id in self.blocked_users]
stmt = insert(BlockedUser).values(values).on_conflict_do_nothing(index_elements=[BlockedUser.tg_id])
await session.execute(stmt)
await session.commit()
logger.info(f"📝 Добавлено {len(self.blocked_users)} пользователей в blocked_users")
try:
if self._session is not None:
await _do_save(self._session)
await save_blocked_user_ids(self._session, list(self.blocked_users))
else:
async with async_session_maker() as session:
await _do_save(session)
await save_blocked_user_ids(session, list(self.blocked_users))
except Exception as e:
logger.error(f"❌ Ошибка при сохранении заблокированных пользователей: {e}")
if self._session is not None:
@@ -316,7 +304,8 @@ class BroadcastService:
await asyncio.gather(*worker_tasks, delayed_task, return_exceptions=True)
await self._save_blocked_users()
if self._session is not None:
await self._save_blocked_users()
end_time = time.time()
total_duration = end_time - self.start_time
@@ -331,6 +320,7 @@ class BroadcastService:
"avg_speed": avg_speed,
"total_messages": len(messages),
"blocked_users": len(self.blocked_users),
"blocked_user_ids": list(self.blocked_users),
}
logger.info(