chenchaoyun commited on
Commit
4e99ca3
·
1 Parent(s): 900d6f9

fix: 飞书通知

Browse files
Files changed (2) hide show
  1. api_routes.py +109 -11
  2. config.py +5 -0
api_routes.py CHANGED
@@ -11,6 +11,7 @@ import shutil
11
  import time
12
  import uuid
13
  import subprocess
 
14
  from concurrent.futures import ThreadPoolExecutor
15
  from datetime import datetime
16
  from typing import Any, Dict, List, Optional, Tuple
@@ -36,16 +37,37 @@ except Exception:
36
  from fastapi.responses import JSONResponse, FileResponse, HTMLResponse
37
 
38
  import wx_access_token
39
- from config import logger, OUTPUT_DIR, IMAGES_DIR, DEEPFACE_AVAILABLE, \
40
- DLIB_AVAILABLE, GFPGAN_AVAILABLE, DDCOLOR_AVAILABLE, REALESRGAN_AVAILABLE, \
41
- UPSCALE_SIZE, CLIP_AVAILABLE, REALESRGAN_MODEL, REMBG_AVAILABLE, \
42
- ANIME_STYLE_AVAILABLE, SAVE_QUALITY, \
43
- AUTO_INIT_ANALYZER, AUTO_INIT_GFPGAN, AUTO_INIT_DDCOLOR, \
44
- AUTO_INIT_REALESRGAN, MODELS_PATH, \
45
- AUTO_INIT_REMBG, AUTO_INIT_ANIME_STYLE, RVM_AVAILABLE, AUTO_INIT_RVM, \
46
- FACE_SCORE_MAX_IMAGES, FEMALE_AGE_ADJUSTMENT, \
47
- FEMALE_AGE_ADJUSTMENT_THRESHOLD, CELEBRITY_SOURCE_DIR, \
48
- CELEBRITY_FIND_THRESHOLD
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  from database import (
50
  record_image_creation,
51
  fetch_paged_image_records,
@@ -1589,8 +1611,8 @@ async def app_analyze_face(
1589
  "device_model": request.headers.get("x-device-model"),
1590
  "os_version": request.headers.get("x-os-version"),
1591
  "app_version": request.headers.get("x-app-version"),
1592
- "timezone": request.headers.get("x-timezone"),
1593
  "region": request.headers.get("x-region"),
 
1594
  "language": request.headers.get("Accept-Language"),
1595
  }
1596
  # 创建异步任务,不阻塞当前请求
@@ -1608,6 +1630,82 @@ async def app_analyze_face(
1608
  )
1609
 
1610
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1611
  @api_router.post("/image_search", response_model=ImageFileList, tags=["图像搜索"])
1612
  @log_api_params
1613
  async def search_by_image(
 
11
  import time
12
  import uuid
13
  import subprocess
14
+ import requests
15
  from concurrent.futures import ThreadPoolExecutor
16
  from datetime import datetime
17
  from typing import Any, Dict, List, Optional, Tuple
 
37
  from fastapi.responses import JSONResponse, FileResponse, HTMLResponse
38
 
39
  import wx_access_token
40
+ from config import (
41
+ logger,
42
+ OUTPUT_DIR,
43
+ IMAGES_DIR,
44
+ DEEPFACE_AVAILABLE,
45
+ DLIB_AVAILABLE,
46
+ GFPGAN_AVAILABLE,
47
+ DDCOLOR_AVAILABLE,
48
+ REALESRGAN_AVAILABLE,
49
+ UPSCALE_SIZE,
50
+ CLIP_AVAILABLE,
51
+ REALESRGAN_MODEL,
52
+ REMBG_AVAILABLE,
53
+ ANIME_STYLE_AVAILABLE,
54
+ SAVE_QUALITY,
55
+ AUTO_INIT_ANALYZER,
56
+ AUTO_INIT_GFPGAN,
57
+ AUTO_INIT_DDCOLOR,
58
+ AUTO_INIT_REALESRGAN,
59
+ MODELS_PATH,
60
+ AUTO_INIT_REMBG,
61
+ AUTO_INIT_ANIME_STYLE,
62
+ RVM_AVAILABLE,
63
+ AUTO_INIT_RVM,
64
+ FACE_SCORE_MAX_IMAGES,
65
+ FEMALE_AGE_ADJUSTMENT,
66
+ FEMALE_AGE_ADJUSTMENT_THRESHOLD,
67
+ CELEBRITY_SOURCE_DIR,
68
+ CELEBRITY_FIND_THRESHOLD,
69
+ FEISHU_WEBHOOK_URL,
70
+ )
71
  from database import (
72
  record_image_creation,
73
  fetch_paged_image_records,
 
1611
  "device_model": request.headers.get("x-device-model"),
1612
  "os_version": request.headers.get("x-os-version"),
1613
  "app_version": request.headers.get("x-app-version"),
 
1614
  "region": request.headers.get("x-region"),
1615
+ "timezone": request.headers.get("x-timezone"),
1616
  "language": request.headers.get("Accept-Language"),
1617
  }
1618
  # 创建异步任务,不阻塞当前请求
 
1630
  )
1631
 
1632
 
1633
+ @api_router.post("/send_feishu_notification", tags=["系统通知"])
1634
+ @log_api_params
1635
+ async def send_feishu_notification(
1636
+ request: Request,
1637
+ title: str = Form(..., description="通知标题"),
1638
+ payload: str = Form(None, description="自定义业务数据的JSON字符串"),
1639
+ ):
1640
+ """
1641
+ 发送飞书消息通知,集成设备信息与自定义内容。
1642
+ """
1643
+ # 提取设备信息
1644
+ device_info = {
1645
+ "device_id": request.headers.get("x-device-id"),
1646
+ "device_type": request.headers.get("x-device-type"),
1647
+ "device_model": request.headers.get("x-device-model"),
1648
+ "os_version": request.headers.get("x-os-version"),
1649
+ "app_version": request.headers.get("x-app-version"),
1650
+ "region": request.headers.get("x-region"),
1651
+ }
1652
+
1653
+ # 构造飞书文案
1654
+ time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
1655
+ text_lines = [f"📢 【{title}】"]
1656
+ text_lines.append(f"⏱️ 时间:{time_str}")
1657
+
1658
+ # 映射表
1659
+ header_mapping = {
1660
+ "device_id": "🆔 设备ID",
1661
+ "device_type": "📱 设备类型",
1662
+ "device_model": "🛠️ 设备型号",
1663
+ "os_version": "💿 系统版本",
1664
+ "app_version": "📦 App版本",
1665
+ "region": "🌍 地区"
1666
+ }
1667
+
1668
+ for key, label in header_mapping.items():
1669
+ val = device_info.get(key)
1670
+ if val:
1671
+ text_lines.append(f"{label}:{val}")
1672
+
1673
+ # 处理自定义 payload
1674
+ if payload:
1675
+ try:
1676
+ extra_data = json.loads(payload)
1677
+ if isinstance(extra_data, dict):
1678
+ for k, v in extra_data.items():
1679
+ text_lines.append(f"🔹 {k}:{v}")
1680
+ else:
1681
+ text_lines.append(f"🔹 内容:{payload}")
1682
+ except json.JSONDecodeError:
1683
+ text_lines.append(f"🔹 内容:{payload}")
1684
+
1685
+ full_text = "\n".join(text_lines)
1686
+
1687
+ # 发送通知(在线程池中执行以防阻塞)
1688
+ def _send():
1689
+ try:
1690
+ if not FEISHU_WEBHOOK_URL:
1691
+ logger.warning("FEISHU_WEBHOOK_URL is not configured, skip sending.")
1692
+ return
1693
+ resp = requests.post(
1694
+ FEISHU_WEBHOOK_URL,
1695
+ json={"msg_type": "text", "content": {"text": full_text}},
1696
+ timeout=10
1697
+ )
1698
+ logger.info(f"Feishu notification sent: {resp.status_code}, {resp.text}")
1699
+ except Exception as exc:
1700
+ logger.warning(f"Failed to send Feishu notification: {exc}")
1701
+
1702
+ # 使用 run_in_executor 避免阻塞
1703
+ loop = asyncio.get_event_loop()
1704
+ loop.run_in_executor(executor, _send)
1705
+
1706
+ return {"success": True, "message": "Notification scheduled"}
1707
+
1708
+
1709
  @api_router.post("/image_search", response_model=ImageFileList, tags=["图像搜索"])
1710
  @log_api_params
1711
  async def search_by_image(
config.py CHANGED
@@ -200,6 +200,11 @@ CELEBRITY_FIND_THRESHOLD = float(
200
  )
201
 
202
  # ---- start ----
 
 
 
 
 
203
  # 微信小程序配置(默认值仅用于本地开发)
204
  WECHAT_APPID = os.environ.get("WECHAT_APPID", "******").strip()
205
  WECHAT_SECRET = os.environ.get("WCT_SECRET", "******").strip()
 
200
  )
201
 
202
  # ---- start ----
203
+ # 飞书 Webhook 配置
204
+ FEISHU_WEBHOOK_URL = os.environ.get(
205
+ "FEISHU_WEBHOOK_URL",
206
+ "https://open.feishu.cn/open-apis/bot/v2/hook/07cfc4b6-4dfd-4b5c-80a4-a66ccba83547"
207
+ ).strip()
208
  # 微信小程序配置(默认值仅用于本地开发)
209
  WECHAT_APPID = os.environ.get("WECHAT_APPID", "******").strip()
210
  WECHAT_SECRET = os.environ.get("WCT_SECRET", "******").strip()