1f18d2ec87
- 新增 chinese_holidays 表,通过 timor.tech API 同步节假日数据 - 修正 holiday 字段解读:holiday=true → 休息日,holiday=false → 调休工作日 - 工作日 8:00-22:00 每小时爬取,周末/节假日/夜间自动跳过 - 新增 /api/v1/holidays/sync 和 /api/v1/holidays/today 接口 - 企微菜单新增「同步节假日」按钮,支持手动触发同步
69 lines
2.1 KiB
Python
69 lines
2.1 KiB
Python
from fastapi import APIRouter, Request, Response
|
|
|
|
from app.wechat.handler import WeChatMessageHandler
|
|
|
|
router = APIRouter()
|
|
|
|
_handler: WeChatMessageHandler | None = None
|
|
|
|
|
|
def get_handler() -> WeChatMessageHandler:
|
|
global _handler
|
|
if _handler is None:
|
|
_handler = WeChatMessageHandler()
|
|
return _handler
|
|
|
|
|
|
@router.get("/wechat/callback")
|
|
async def wechat_verify(request: Request):
|
|
handler = get_handler()
|
|
params = request.query_params
|
|
echostr = handler.verify_url(
|
|
params.get("msg_signature", ""),
|
|
params.get("timestamp", ""),
|
|
params.get("nonce", ""),
|
|
params.get("echostr", ""),
|
|
)
|
|
if echostr:
|
|
return Response(content=echostr, media_type="text/plain")
|
|
return Response(content="verification failed", status_code=403)
|
|
|
|
|
|
@router.post("/wechat/callback")
|
|
async def wechat_callback(request: Request):
|
|
handler = get_handler()
|
|
params = request.query_params
|
|
post_data = await request.body()
|
|
post_text = post_data.decode("utf-8")
|
|
|
|
xml_tree = handler.decrypt_message(
|
|
post_text,
|
|
params.get("msg_signature", ""),
|
|
params.get("timestamp", ""),
|
|
params.get("nonce", ""),
|
|
)
|
|
if xml_tree is None:
|
|
return Response(content="decrypt failed", status_code=403)
|
|
|
|
msg_type = xml_tree.find("MsgType")
|
|
msg_type = msg_type.text if msg_type is not None else "unknown"
|
|
|
|
if msg_type == "event":
|
|
event = xml_tree.find("Event")
|
|
event_key = xml_tree.find("EventKey")
|
|
from_user = xml_tree.find("FromUserName")
|
|
await handler.handle_event(
|
|
event.text if event is not None else "",
|
|
event_key.text if event_key is not None else None,
|
|
from_user.text if from_user is not None else "",
|
|
)
|
|
elif msg_type == "text":
|
|
content = xml_tree.find("Content")
|
|
from_user = xml_tree.find("FromUserName")
|
|
await handler.handle_text(
|
|
content.text if content is not None else "",
|
|
from_user.text if from_user is not None else "",
|
|
)
|
|
|
|
return Response(content="success")
|