ForcePilot/backend/package/yuxi/channel/extensions/zalouser/auth.py
Kris d5e36d33b7 feat(channel): 添加 Zalo OA、Zoom Chat 和 Zulip 渠道扩展
新增 Zalo OA、Zoom Chat、Zulip 三个渠道扩展。

Zalo OA 渠道扩展主要模块:sidecar_client, config, gateway, outbound, streaming, pairing, security, auth, dedupe, directory, monitor, status, session, reactions, tools

Zoom Chat 渠道扩展主要模块:config, gateway, webhook, outbound, streaming, pairing, security, crypto, dedupe, actions, media, mentions, monitor, status, session, reactions, threading

Zulip 渠道扩展主要模块:client, config, gateway, outbound, streaming, pairing, security, monitor, status
2026-05-21 12:06:26 +08:00

99 lines
3.4 KiB
Python

from __future__ import annotations
import logging
from yuxi.channel.extensions.zalouser.errors import (
ZaloUserAuthError,
ZaloUserConnectionError,
)
from yuxi.channel.extensions.zalouser.sidecar_client import ZcaSidecarClient
logger = logging.getLogger(__name__)
class ZaloUserAuthAdapter:
def __init__(self):
self._client: ZcaSidecarClient | None = None
def set_client(self, client: ZcaSidecarClient) -> None:
self._client = client
async def login_with_qr_start(
self,
account_id: str | None = None,
*,
force: bool = False,
timeout_ms: int | None = None,
) -> dict:
if not self._client:
raise ZaloUserAuthError("Sidecar client not initialized")
timeout = timeout_ms or 30_000
try:
result = await self._client.login_qr_start(force=force, timeout_ms=timeout)
return {
"qr_data_url": result.get("qrDataUrl", ""),
"message": result.get("message", "QR code generated"),
"connected": result.get("connected", False),
}
except ZaloUserConnectionError as e:
return {"qr_data_url": "", "message": str(e), "connected": False}
async def login_with_qr_wait(
self,
account_id: str | None = None,
*,
timeout_ms: int | None = None,
current_qr_data_url: str | None = None,
) -> dict:
if not self._client:
raise ZaloUserAuthError("Sidecar client not initialized")
timeout = timeout_ms or 120_000
try:
result = await self._client.login_qr_wait(timeout_ms=timeout)
return {
"connected": True,
"message": "Login successful",
"qr_data_url": None,
"user_id": result.get("user_id", ""),
"display_name": result.get("display_name", ""),
}
except ZaloUserAuthError as e:
return {"connected": False, "message": str(e), "qr_data_url": None}
async def login_with_qr_cancel(self, account_id: str | None = None) -> dict:
if not self._client:
raise ZaloUserAuthError("Sidecar client not initialized")
try:
await self._client.login_qr_cancel()
return {"cancelled": True}
except Exception as e:
logger.warning("QR cancel failed: %s", e)
return {"cancelled": False, "error": str(e)}
async def logout_account(self, ctx: object) -> dict:
if not self._client:
return {"cleared": False, "logged_out": None}
try:
await self._client.logout()
return {"cleared": True, "logged_out": True}
except Exception as e:
logger.warning("Logout failed: %s", e)
return {"cleared": False, "logged_out": None}
async def ensure_session(self, timeout_ms: int = 20_000) -> dict:
if not self._client:
raise ZaloUserAuthError("Sidecar client not initialized")
try:
return await self._client.ensure_session(timeout_ms=timeout_ms)
except ZaloUserConnectionError as e:
raise ZaloUserAuthError(f"Session ensure failed: {e}") from e
async def get_cookie(self) -> dict:
if not self._client:
raise ZaloUserAuthError("Sidecar client not initialized")
return await self._client.get_cookie()