88import aiohttp
99from fastapi import FastAPI , HTTPException , Request , Response
1010from pydantic import BaseModel , ConfigDict , Field
11+ from wechatpy .client import BaseWeChatClient
1112from wechatpy .exceptions import InvalidSignatureException
1213from wechatpy .replies import create_reply
1314
1819from kirara_ai .web .app import WebServer
1920from kirara_ai .workflow .core .dispatch .dispatcher import WorkflowDispatcher
2021
22+ from .delegates import CorpWechatApiDelegate , PublicWechatApiDelegate
23+
2124WECOM_TEMP_DIR = os .path .join (os .getcwd (), 'data' , 'temp' , 'wecom' )
2225
2326WEBHOOK_URL_PREFIX = "/im/webhook/wechat"
@@ -68,9 +71,13 @@ def __init__(self, **kwargs: Any):
6871class WeComUtils :
6972 """企业微信相关的工具类"""
7073
71- def __init__ (self , access_token : str ):
72- self .access_token = access_token
74+ def __init__ (self , client : BaseWeChatClient ):
75+ self .client = client
7376 self .logger = get_logger ("WeComUtils" )
77+
78+ @property
79+ def access_token (self ) -> str :
80+ return self .client .access_token
7481
7582 async def download_and_save_media (self , media_id : str , file_name : str ) -> Optional [str ]:
7683 """下载并保存媒体文件到本地"""
@@ -114,7 +121,6 @@ def __init__(self, config: WecomConfig):
114121 else :
115122 self .app = self .web_server .app
116123
117- self .setup_wechat_api ()
118124 self .logger = get_logger ("Wecom-Adapter" )
119125 self .is_running = False
120126 if not self .config .host :
@@ -127,25 +133,20 @@ def __init__(self, config: WecomConfig):
127133
128134 self .reply_tasks = {}
129135
136+ # 根据配置选择合适的API代理
137+ self .setup_wechat_api ()
138+
130139 def setup_wechat_api (self ):
140+ """根据配置设置微信API代理"""
131141 if self .config .corp_id :
132- from wechatpy .enterprise import parse_message
133- from wechatpy .enterprise .client import WeChatClient
134- from wechatpy .enterprise .crypto import WeChatCrypto
135- self .crypto = WeChatCrypto (
136- self .config .token , self .config .encoding_aes_key , self .config .corp_id
137- )
138- self .client = WeChatClient (self .config .corp_id , self .config .secret )
139- self .parse_message = parse_message
142+ self .api_delegate = CorpWechatApiDelegate ()
140143 else :
141- from wechatpy import WeChatClient
142- from wechatpy .crypto import WeChatCrypto
143- from wechatpy .parser import parse_message
144- self .crypto = WeChatCrypto (
145- self .config .token , self .config .encoding_aes_key , self .config .app_id
146- )
147- self .client = WeChatClient (self .config .app_id , self .config .secret )
148- self .parse_message = parse_message
144+ self .api_delegate = PublicWechatApiDelegate ()
145+
146+ self .api_delegate .setup_api (self .config )
147+
148+ # 设置工具类
149+ self .wecom_utils = WeComUtils (self .api_delegate .client )
149150
150151 def setup_routes (self ):
151152 if self .config .host :
@@ -165,19 +166,16 @@ async def handle_check_request(request: Request):
165166 raise HTTPException (status_code = 404 )
166167
167168 signature = request .query_params .get ("msg_signature" , "" )
169+ if not signature :
170+ signature = request .query_params .get ("signature" , "" )
168171 timestamp = request .query_params .get ("timestamp" , "" )
169172 nonce = request .query_params .get ("nonce" , "" )
170173 echo_str = request .query_params .get ("echostr" , "" )
171174
172-
173175 try :
174- if self .config .corp_id :
175- echo_str = self .crypto .check_signature (
176- signature , timestamp , nonce , echo_str
177- )
178- else :
179- from wechatpy .utils import check_signature
180- check_signature (self .config .token , signature , timestamp , nonce )
176+ echo_str = self .api_delegate .check_signature (
177+ signature , timestamp , nonce , echo_str
178+ )
181179 return Response (content = echo_str , media_type = "text/plain" )
182180 except InvalidSignatureException :
183181 self .logger .error ("failed to check signature, please check your settings." )
@@ -190,16 +188,18 @@ async def handle_message(request: Request):
190188 self .logger .warning ("Wecom-Adapter is not running, skipping message request." )
191189 raise HTTPException (status_code = 404 )
192190 signature = request .query_params .get ("msg_signature" , "" )
191+ if not signature :
192+ signature = request .query_params .get ("signature" , "" )
193193 timestamp = request .query_params .get ("timestamp" , "" )
194194 nonce = request .query_params .get ("nonce" , "" )
195195 try :
196- msg = self .crypto .decrypt_message (
196+ msg = self .api_delegate .decrypt_message (
197197 await request .body (), signature , timestamp , nonce
198198 )
199199 except InvalidSignatureException :
200200 self .logger .error ("failed to check signature, please check your settings." )
201201 raise HTTPException (status_code = 403 )
202- msg = self .parse_message (msg )
202+ msg = self .api_delegate . parse_message (msg )
203203
204204 if msg .id in self .reply_tasks :
205205 self .logger .debug (f"skip processing due to duplicate msgid: { msg .id } " )
@@ -262,7 +262,7 @@ def convert_to_message(self, raw_message: Any, media_path: Optional[str] = None)
262262 async def _send_text (self , user_id : str , text : str ):
263263 """发送文本消息"""
264264 try :
265- return self .client . message .send_text (self .config .app_id , user_id , text )
265+ return await self .api_delegate .send_text (self .config .app_id , user_id , text )
266266 except Exception as e :
267267 self .logger .error (f"Failed to send text message: { e } " )
268268 raise e
@@ -271,10 +271,7 @@ async def _send_media(self, user_id: str, media_data: str, media_type: str):
271271 """发送媒体消息的通用方法"""
272272 try :
273273 media_bytes = BytesIO (base64 .b64decode (media_data ))
274- media_id = self .client .media .upload (
275- media_type , media_bytes )["media_id" ]
276- send_method = getattr (self .client .message , f"send_{ media_type } " )
277- return send_method (self .config .app , user_id , media_id )
274+ return await self .api_delegate .send_media (self .config .app_id , user_id , media_type , media_bytes )
278275 except Exception as e :
279276 self .logger .error (f"Failed to send { media_type } message: { e } " )
280277 raise e
0 commit comments