62 lines
2.0 KiB
Python
62 lines
2.0 KiB
Python
from datetime import datetime, timezone as py_tz
|
|
from telegram import Update
|
|
from telegram.ext import ContextTypes
|
|
from django.utils import timezone
|
|
from .models import TelegramChat
|
|
|
|
def _now_aware():
|
|
return timezone.now()
|
|
|
|
async def upsert_chat_from_update(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
|
"""
|
|
Вызывайте в message-хендлерах, чтобы обновлять last_message_at и тайтл.
|
|
"""
|
|
chat = update.effective_chat
|
|
if not chat:
|
|
return
|
|
|
|
obj, created = TelegramChat.objects.update_or_create(
|
|
id=chat.id,
|
|
defaults={
|
|
"type": chat.type,
|
|
"title": chat.title or "",
|
|
"username": chat.username or "",
|
|
"is_member": True, # если есть сообщения — бот, скорее всего, в чате
|
|
"last_message_at": _now_aware(),
|
|
}
|
|
)
|
|
# created можно игнорировать; при необходимости — логировать
|
|
|
|
|
|
async def on_my_chat_member(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
|
"""
|
|
Ловим изменение статуса бота в чатах (добавили/кикнули).
|
|
"""
|
|
if not update.my_chat_member:
|
|
return
|
|
|
|
chat = update.my_chat_member.chat
|
|
new_status = update.my_chat_member.new_chat_member.status # "member"/"administrator"/"kicked"/"left"/...
|
|
is_in_chat = new_status in ("member", "administrator")
|
|
|
|
defaults = {
|
|
"type": chat.type,
|
|
"title": chat.title or "",
|
|
"username": getattr(chat, "username", "") or "",
|
|
"is_member": is_in_chat,
|
|
"last_message_at": _now_aware(),
|
|
}
|
|
|
|
if is_in_chat:
|
|
defaults["left_at"] = None
|
|
defaults.setdefault("joined_at", _now_aware())
|
|
|
|
obj, _ = TelegramChat.objects.update_or_create(
|
|
id=chat.id,
|
|
defaults=defaults
|
|
)
|
|
|
|
if not is_in_chat and obj.left_at is None:
|
|
obj.left_at = _now_aware()
|
|
obj.save(update_fields=["is_member", "left_at"])
|