Files
sino-mci/channel-service/app/services/heartbeat_service.py

52 lines
2.0 KiB
Python

from __future__ import annotations
import time
from app.clients.pywechat_client import ClientRegistry, OnlineStatus, registry
from app.models.event import EventType, OutboundEvent
from app.repositories.event_store import EventStore
class HeartbeatService:
def __init__(self, registry: ClientRegistry):
self.registry = registry
self.store: EventStore | None = None
def heartbeat(self, account_id: str, payload: dict) -> dict:
client = self.registry.get_or_create(account_id, payload.get("account_name"))
client.heartbeat()
if "risk_level" in payload:
client.state.risk_level = payload["risk_level"]
if "sent_count_today" in payload:
client.state.sent_count_today = payload["sent_count_today"]
event = OutboundEvent(
event_type=EventType.HEARTBEAT,
account_id=account_id,
tenant_code=payload.get("tenant_code", "default"),
data={
"login_status": client.state.login_status.value,
"online_status": client.state.online_status.value,
"risk_level": client.state.risk_level,
"sent_count_today": client.state.sent_count_today,
},
)
if self.store is not None:
self.store.save(event)
return {"success": True, "account_id": account_id}
def check_offline_accounts(self, timeout_seconds: int = 120) -> list[dict]:
now = time.time()
offline = []
for client in self.registry.list_all():
last = client.state.last_heartbeat_at
if client.state.online_status == OnlineStatus.ONLINE and (last is None or now - last > timeout_seconds):
client.state.online_status = OnlineStatus.OFFLINE
offline.append({"account_id": client.state.account_id, "last_heartbeat_at": last})
return offline
heartbeat_service = HeartbeatService(registry)
from app.repositories.event_store import event_store # noqa: E402
heartbeat_service.store = event_store