Files
shaguabijia-app-server/app/integrations/feishu_notifier.py
T

43 lines
2.1 KiB
Python

"""飞书群自定义机器人发送(text / post 消息)。
自定义机器人「关键词」验证:消息 content.text 必须含机器人配置的关键词,否则飞书返回 code!=0
(如 19024 Key Words Not Found)——本项目消息由 compare_alert_format 生成,标题已含「比价失败报警」。
不需要签名(sign)/IP 白名单。文档:https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot
"""
from __future__ import annotations
import httpx
class FeishuNotifyError(Exception):
"""飞书发送失败(网络错误 / 非 2xx / 业务 code!=0,含关键词不匹配)。"""
def _post_feishu(webhook_url: str, payload: dict, timeout: float) -> None:
"""内部 helper:POST payload 到飞书 webhook 并校验响应。失败抛 FeishuNotifyError。"""
try:
resp = httpx.post(webhook_url, json=payload, timeout=timeout)
except httpx.HTTPError as e:
raise FeishuNotifyError(f"feishu request failed: {e}") from e
if resp.status_code >= 300:
raise FeishuNotifyError(f"feishu http {resp.status_code}: {resp.text[:200]}")
try:
data = resp.json()
except ValueError as e:
raise FeishuNotifyError(f"feishu bad json: {resp.text[:200]}") from e
code = data.get("code", data.get("StatusCode", 0))
if code not in (0, None):
raise FeishuNotifyError(f"feishu code={code} msg={data.get('msg') or data.get('StatusMessage')}")
def send_feishu_text(webhook_url: str, text: str, *, timeout: float = 10.0) -> None:
"""POST 一条 text 消息到飞书群机器人 webhook。失败(网络/HTTP/业务 code)抛 FeishuNotifyError。"""
payload = {"msg_type": "text", "content": {"text": text}}
_post_feishu(webhook_url, payload, timeout)
def send_feishu_post(webhook_url: str, title: str, content: list, *, timeout: float = 10.0) -> None:
"""发飞书富文本(post)。content 是段落数组,每段是元素数组[{tag:text/a,...}]。失败抛 FeishuNotifyError。"""
payload = {"msg_type": "post", "content": {"post": {"zh_cn": {"title": title, "content": content}}}}
_post_feishu(webhook_url, payload, timeout)