130 lines
4.4 KiB
Python
130 lines
4.4 KiB
Python
import requests
|
|
import json
|
|
import time
|
|
import logging
|
|
from app.core.config import settings
|
|
from typing import Dict, Any, Optional, List
|
|
|
|
class WecomClient:
|
|
"""企业微信客户端"""
|
|
|
|
def __init__(self):
|
|
self.corp_id = settings.WECHAT_CORP_ID
|
|
self.corp_secret = settings.WECHAT_CORP_SECRET
|
|
self.access_token = None
|
|
self.token_expires_at = 0
|
|
|
|
async def get_access_token(self) -> str:
|
|
"""获取访问令牌"""
|
|
# 检查令牌是否过期
|
|
if self.access_token and time.time() < self.token_expires_at:
|
|
return self.access_token
|
|
|
|
# 获取新令牌
|
|
url = f"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={self.corp_id}&corpsecret={self.corp_secret}"
|
|
|
|
try:
|
|
response = requests.get(url)
|
|
result = response.json()
|
|
|
|
if result.get("errcode") == 0:
|
|
self.access_token = result.get("access_token")
|
|
self.token_expires_at = time.time() + result.get("expires_in") - 200 # 提前200秒过期
|
|
return self.access_token
|
|
else:
|
|
logging.error(f"获取企业微信访问令牌失败: {result}")
|
|
return None
|
|
|
|
except Exception as e:
|
|
logging.exception(f"获取企业微信访问令牌异常: {str(e)}")
|
|
return None
|
|
|
|
async def miniprogram_to_userid(self, openid: str) -> Optional[Dict[str, Any]]:
|
|
"""
|
|
小程序openid转换为企业微信userid
|
|
|
|
Args:
|
|
openid: 小程序用户的openid
|
|
|
|
Returns:
|
|
Dict: 包含userid或pending_id的字典
|
|
"""
|
|
token = await self.get_access_token()
|
|
if not token:
|
|
return None
|
|
|
|
url = f"https://qyapi.weixin.qq.com/cgi-bin/miniprogram/jscode2session?access_token={token}"
|
|
|
|
data = {
|
|
"code": openid,
|
|
"grant_type": "authorization_code"
|
|
}
|
|
|
|
try:
|
|
response = requests.post(url, json=data)
|
|
result = response.json()
|
|
|
|
if result.get("errcode") == 0:
|
|
return {
|
|
"userid": result.get("userid"),
|
|
"pending_id": result.get("pending_id")
|
|
}
|
|
else:
|
|
logging.error(f"小程序openid转换失败: {result}")
|
|
return None
|
|
|
|
except Exception as e:
|
|
logging.exception(f"小程序openid转换异常: {str(e)}")
|
|
return None
|
|
|
|
async def get_user_in_group_chat(self, userid: str) -> List[str]:
|
|
"""
|
|
获取用户所在的群聊列表
|
|
|
|
Args:
|
|
userid: 企业微信用户ID
|
|
|
|
Returns:
|
|
List[str]: 群聊ID列表
|
|
"""
|
|
token = await self.get_access_token()
|
|
if not token:
|
|
return []
|
|
|
|
url = f"https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list_group_chat?access_token={token}"
|
|
|
|
# 先获取所有群聊
|
|
try:
|
|
response = requests.post(url, json={})
|
|
result = response.json()
|
|
|
|
if result.get("errcode") != 0:
|
|
logging.error(f"获取群聊列表失败: {result}")
|
|
return []
|
|
|
|
chat_ids = []
|
|
for chat in result.get("group_chat_list", []):
|
|
chat_id = chat.get("chat_id")
|
|
|
|
# 获取群聊详情
|
|
detail_url = f"https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get?access_token={token}"
|
|
detail_response = requests.post(detail_url, json={"chat_id": chat_id})
|
|
detail_result = detail_response.json()
|
|
|
|
if detail_result.get("errcode") == 0:
|
|
group_chat = detail_result.get("group_chat", {})
|
|
members = group_chat.get("member_list", [])
|
|
|
|
# 检查用户是否在群内
|
|
for member in members:
|
|
if member.get("userid") == userid:
|
|
chat_ids.append(chat_id)
|
|
break
|
|
|
|
return chat_ids
|
|
|
|
except Exception as e:
|
|
logging.exception(f"获取用户群聊异常: {str(e)}")
|
|
return []
|
|
|
|
wecom_client = WecomClient() |