ForcePilot/backend/package/yuxi/channels/adapters/synologychat/webhook_send.py
Kris 3ad218e537 feat(synologychat): 新增群晖Chat适配器完整实现
新增群晖Chat渠道适配器的全套实现,包括:
1. 基础适配器与导出接口定义
2. DSM API认证、探测与会话管理
3. 轮询与Webhook两种消息接收方式
4. 消息去重、格式化与规范化处理
5. 多账号支持与权限安全策略
6. 目录用户/群组发现功能
7. 审批配对与流量控制机制
8. 安全审计与配置检查功能
2026-05-12 00:49:16 +08:00

54 lines
1.9 KiB
Python

"""Incoming Webhook sender for Synology Chat.
Provides an alternative send path via Synology Chat's Incoming Webhook URL,
as a lighter-weight alternative to the DSM API direct connection.
"""
from __future__ import annotations
from typing import Any
import httpx
from yuxi.channels.models import DeliveryResult
from yuxi.utils.logging_config import logger
async def send_via_incoming_webhook(
webhook_url: str,
text: str,
file_url: str | None = None,
timeout: float = 30.0,
) -> DeliveryResult:
if not webhook_url:
return DeliveryResult(success=False, error="Incoming webhook URL not configured")
payload: dict[str, Any] = {"text": text}
if file_url:
payload["file_url"] = file_url
try:
async with httpx.AsyncClient(timeout=httpx.Timeout(timeout)) as client:
response = await client.post(webhook_url, data=payload)
response.raise_for_status()
result = response.json()
if result.get("success"):
return DeliveryResult(success=True, message_id=result.get("data", {}).get("message_id"))
return DeliveryResult(
success=False,
error=f"Webhook send failed: {result.get('error', {})}",
)
except httpx.TimeoutException:
return DeliveryResult(success=False, error="Incoming webhook request timed out")
except httpx.HTTPStatusError as e:
return DeliveryResult(success=False, error=f"Incoming webhook HTTP {e.response.status_code}")
except Exception as e:
logger.error(f"[SynologyChat] Incoming webhook send failed: {e}")
return DeliveryResult(success=False, error=str(e))
def build_webhook_url(dsm_url: str, webhook_token: str) -> str:
"""Build a Synology Chat Incoming Webhook URL from DSM URL and token."""
base = dsm_url.rstrip("/")
return f"{base}/webapi/entry.cgi?api=SYNO.Chat.External&method=incoming&version=1&token={webhook_token}"