kaikai_test/daily_report/robot_service.py
2026-05-07 16:31:56 +08:00

73 lines
2.4 KiB
Python

from __future__ import annotations
import json
import urllib.error
import urllib.request
from typing import Any
def _button(text: str, url: str) -> dict[str, Any]:
return {
"tag": "button",
"text": {"tag": "plain_text", "content": text},
"type": "primary",
"url": url,
}
def create_reminder_payload(submit_url: str, title: str = "每日工作汇报提醒") -> dict[str, Any]:
return {
"msg_type": "interactive",
"card": {
"header": {
"title": {"tag": "plain_text", "content": title},
"template": "blue",
},
"elements": [
{"tag": "div", "text": {"tag": "lark_md", "content": "请提交今日日报。"}},
{"tag": "action", "actions": [_button("填写日报", submit_url)]},
],
},
}
def create_summary_payload(manager_url: str, summary: dict[str, Any]) -> dict[str, Any]:
missing_names = "".join(employee["name"] for employee in summary["missing"]) or ""
return {
"msg_type": "interactive",
"card": {
"header": {
"title": {"tag": "plain_text", "content": f"{summary['date']} 日报提交汇总"},
"template": "orange" if summary["missingCount"] > 0 else "green",
},
"elements": [
{
"tag": "div",
"text": {
"tag": "lark_md",
"content": f"已提交:{summary['submittedCount']}/{summary['expectedCount']}\n未提交:{missing_names}",
},
},
{"tag": "action", "actions": [_button("查看全部日报", manager_url)]},
],
},
}
def send_webhook(webhook_url: str, payload: dict[str, Any]) -> dict[str, Any]:
if not webhook_url:
raise ValueError("FEISHU_WEBHOOK_URL is required")
request = urllib.request.Request(
webhook_url,
data=json.dumps(payload).encode("utf-8"),
headers={"content-type": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(request, timeout=10) as response:
body = response.read().decode("utf-8")
return json.loads(body) if body else {"ok": True}
except urllib.error.HTTPError as error:
raise RuntimeError(f"Feishu webhook failed with status {error.code}") from error