import httpx import json from app.config import settings from app.utils.redis_client import get_json, set_json async def get_access_token() -> str | None: if not settings.wx_appid or not settings.wx_secret: return None cache_key = "wx:access_token" cached = await get_json(cache_key) if cached: try: return json.loads(cached).get("access_token") except json.JSONDecodeError: pass url = "https://api.weixin.qq.com/cgi-bin/token" params = { "grant_type": "client_credential", "appid": settings.wx_appid, "secret": settings.wx_secret, } async with httpx.AsyncClient() as client: response = await client.get(url, params=params) data = response.json() access_token = data.get("access_token") expires_in = int(data.get("expires_in", 7200)) if access_token: await set_json(cache_key, json.dumps({"access_token": access_token}), ex=max(expires_in - 300, 60)) return access_token async def send_audit_result(openid: str, passed: bool, remark: str = "") -> None: if not openid or not settings.wx_template_audit_result: return access_token = await get_access_token() if not access_token: return url = f"https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={access_token}" payload = { "touser": openid, "template_id": settings.wx_template_audit_result, "miniprogram_state": "developer", "lang": "zh_CN", "data": { "thing1": {"value": "资料审核结果通知"}, "phrase2": {"value": "审核通过" if passed else "审核未通过"}, "thing3": {"value": remark or ("恭喜,您的资料已通过审核" if passed else "请根据提示修改后重新提交")}, }, } async with httpx.AsyncClient() as client: await client.post(url, json=payload) async def send_match_success(openid: str, other_nickname: str) -> None: if not openid or not settings.wx_template_match_success: return access_token = await get_access_token() if not access_token: return url = f"https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={access_token}" payload = { "touser": openid, "template_id": settings.wx_template_match_success, "page": "pages/my-matches/my-matches", "miniprogram_state": "developer", "lang": "zh_CN", "data": { "name3": {"value": other_nickname or "新匹配对象"}, "thing4": {"value": "你们互相感兴趣,快去查看匹配详情吧"}, }, } async with httpx.AsyncClient() as client: await client.post(url, json=payload)