Files
Stardream eace48732d
Build and Push Docker Images / build (push) Successful in 17s
Initial release
2026-06-02 12:02:02 +10:00

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