93 lines
3.8 KiB
Python
93 lines
3.8 KiB
Python
from aiogram import F, Router
|
|
from aiogram.types import ChatMemberUpdated, Message
|
|
|
|
from app.core.database import AsyncSessionLocal
|
|
from app.models.managed_chat import ManagedChat
|
|
from app.models.lottery import Lottery, LotteryStatus
|
|
from app.models.passphrase_verification import PassphraseVerification
|
|
from sqlalchemy import select
|
|
|
|
router = Router()
|
|
|
|
|
|
@router.my_chat_member(F.chat.type.in_({"group", "supergroup", "channel"}))
|
|
async def bot_chat_member_updated(event: ChatMemberUpdated) -> None:
|
|
"""Record or update the bot's presence in a group/channel."""
|
|
async with AsyncSessionLocal() as db:
|
|
chat = event.chat
|
|
new_status = event.new_chat_member.status
|
|
|
|
result = await db.execute(
|
|
select(ManagedChat).where(ManagedChat.id == chat.id)
|
|
)
|
|
managed = result.scalar_one_or_none()
|
|
|
|
if new_status in ("member", "administrator"):
|
|
if managed is None:
|
|
managed = ManagedChat(
|
|
id=chat.id,
|
|
title=chat.title or "",
|
|
username=getattr(chat, 'username', None),
|
|
chat_type=chat.type,
|
|
)
|
|
db.add(managed)
|
|
else:
|
|
managed.is_active = True
|
|
managed.title = chat.title or managed.title
|
|
managed.username = getattr(chat, 'username', None)
|
|
await db.commit()
|
|
elif new_status in ("left", "kicked") and managed is not None:
|
|
managed.is_active = False
|
|
await db.commit()
|
|
|
|
|
|
@router.channel_post(F.chat.type == "channel")
|
|
@router.message(F.chat.type.in_({"group", "supergroup"}))
|
|
async def on_chat_message(message: Message) -> None:
|
|
"""Track latest message ID and detect passphrase submissions."""
|
|
async with AsyncSessionLocal() as db:
|
|
result = await db.execute(select(ManagedChat).where(ManagedChat.id == message.chat.id))
|
|
managed = result.scalar_one_or_none()
|
|
if managed is None:
|
|
managed = ManagedChat(
|
|
id=message.chat.id,
|
|
title=message.chat.title or "",
|
|
username=getattr(message.chat, "username", None),
|
|
chat_type=message.chat.type,
|
|
last_message_id=message.message_id,
|
|
)
|
|
db.add(managed)
|
|
elif message.message_id > (managed.last_message_id or 0):
|
|
managed.last_message_id = message.message_id
|
|
await db.commit()
|
|
|
|
if message.text and message.from_user:
|
|
text = message.text.strip()
|
|
uid = message.from_user.id
|
|
cid = message.chat.id
|
|
async with AsyncSessionLocal() as db2:
|
|
r = await db2.execute(
|
|
select(Lottery).where(
|
|
Lottery.status == LotteryStatus.ACTIVE,
|
|
Lottery.require_membership == True,
|
|
)
|
|
)
|
|
for lottery in r.scalars().all():
|
|
ids = lottery.required_chat_ids or []
|
|
phrases = lottery.required_chat_passphrases or []
|
|
for i, chat_id in enumerate(ids):
|
|
if chat_id == cid and i < len(phrases) and phrases[i] and text == phrases[i]:
|
|
existing = await db2.execute(
|
|
select(PassphraseVerification).where(
|
|
PassphraseVerification.lottery_id == lottery.id,
|
|
PassphraseVerification.chat_id == cid,
|
|
PassphraseVerification.user_id == uid,
|
|
)
|
|
)
|
|
if existing.scalar_one_or_none() is None:
|
|
db2.add(PassphraseVerification(
|
|
lottery_id=lottery.id, chat_id=cid, user_id=uid
|
|
))
|
|
await db2.commit()
|
|
break
|