Files
Messenger/app/realtime/presence.py
benya e6a271f8be
Some checks failed
CI / test (push) Failing after 22s
feat(chat): add presence metadata and improve web chat core
- add user last_seen_at with alembic migration and persist on realtime disconnect
- extend chat serialization with private online/last_seen, group members/online, channel subscribers
- add Redis batch presence lookup helper
- update web chat list/header to display status counters and last-seen labels
- improve delivery receipt handling using last_delivered/last_read boundaries
- include chat info panel and related API/type updates
2026-03-08 02:02:09 +03:00

50 lines
1.4 KiB
Python

from redis.exceptions import RedisError
from app.utils.redis_client import get_redis_client
async def mark_user_online(user_id: int) -> None:
try:
redis = get_redis_client()
key = f"presence:user:{user_id}"
count = await redis.incr(key)
if count == 1:
await redis.expire(key, 3600)
except RedisError:
return
async def mark_user_offline(user_id: int) -> None:
try:
redis = get_redis_client()
key = f"presence:user:{user_id}"
value = await redis.decr(key)
if value <= 0:
await redis.delete(key)
except RedisError:
return
async def is_user_online(user_id: int) -> bool:
try:
redis = get_redis_client()
value = await redis.get(f"presence:user:{user_id}")
return bool(value and str(value).isdigit() and int(value) > 0)
except RedisError:
return False
async def get_users_online_map(user_ids: list[int]) -> dict[int, bool]:
if not user_ids:
return {}
try:
redis = get_redis_client()
keys = [f"presence:user:{user_id}" for user_id in user_ids]
values = await redis.mget(keys)
return {
user_id: bool(value and str(value).isdigit() and int(value) > 0)
for user_id, value in zip(user_ids, values, strict=False)
}
except RedisError:
return {user_id: False for user_id in user_ids}