8
8
import aiohttp
9
9
from fastapi import FastAPI , HTTPException , Request , Response
10
10
from pydantic import BaseModel , ConfigDict , Field
11
+ from wechatpy .client import BaseWeChatClient
11
12
from wechatpy .exceptions import InvalidSignatureException
12
13
from wechatpy .replies import create_reply
13
14
18
19
from kirara_ai .web .app import WebServer
19
20
from kirara_ai .workflow .core .dispatch .dispatcher import WorkflowDispatcher
20
21
22
+ from .delegates import CorpWechatApiDelegate , PublicWechatApiDelegate
23
+
21
24
WECOM_TEMP_DIR = os .path .join (os .getcwd (), 'data' , 'temp' , 'wecom' )
22
25
23
26
WEBHOOK_URL_PREFIX = "/im/webhook/wechat"
@@ -68,9 +71,13 @@ def __init__(self, **kwargs: Any):
68
71
class WeComUtils :
69
72
"""企业微信相关的工具类"""
70
73
71
- def __init__ (self , access_token : str ):
72
- self .access_token = access_token
74
+ def __init__ (self , client : BaseWeChatClient ):
75
+ self .client = client
73
76
self .logger = get_logger ("WeComUtils" )
77
+
78
+ @property
79
+ def access_token (self ) -> str :
80
+ return self .client .access_token
74
81
75
82
async def download_and_save_media (self , media_id : str , file_name : str ) -> Optional [str ]:
76
83
"""下载并保存媒体文件到本地"""
@@ -114,7 +121,6 @@ def __init__(self, config: WecomConfig):
114
121
else :
115
122
self .app = self .web_server .app
116
123
117
- self .setup_wechat_api ()
118
124
self .logger = get_logger ("Wecom-Adapter" )
119
125
self .is_running = False
120
126
if not self .config .host :
@@ -127,25 +133,20 @@ def __init__(self, config: WecomConfig):
127
133
128
134
self .reply_tasks = {}
129
135
136
+ # 根据配置选择合适的API代理
137
+ self .setup_wechat_api ()
138
+
130
139
def setup_wechat_api (self ):
140
+ """根据配置设置微信API代理"""
131
141
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 ()
140
143
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 )
149
150
150
151
def setup_routes (self ):
151
152
if self .config .host :
@@ -165,19 +166,16 @@ async def handle_check_request(request: Request):
165
166
raise HTTPException (status_code = 404 )
166
167
167
168
signature = request .query_params .get ("msg_signature" , "" )
169
+ if not signature :
170
+ signature = request .query_params .get ("signature" , "" )
168
171
timestamp = request .query_params .get ("timestamp" , "" )
169
172
nonce = request .query_params .get ("nonce" , "" )
170
173
echo_str = request .query_params .get ("echostr" , "" )
171
174
172
-
173
175
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
+ )
181
179
return Response (content = echo_str , media_type = "text/plain" )
182
180
except InvalidSignatureException :
183
181
self .logger .error ("failed to check signature, please check your settings." )
@@ -190,16 +188,18 @@ async def handle_message(request: Request):
190
188
self .logger .warning ("Wecom-Adapter is not running, skipping message request." )
191
189
raise HTTPException (status_code = 404 )
192
190
signature = request .query_params .get ("msg_signature" , "" )
191
+ if not signature :
192
+ signature = request .query_params .get ("signature" , "" )
193
193
timestamp = request .query_params .get ("timestamp" , "" )
194
194
nonce = request .query_params .get ("nonce" , "" )
195
195
try :
196
- msg = self .crypto .decrypt_message (
196
+ msg = self .api_delegate .decrypt_message (
197
197
await request .body (), signature , timestamp , nonce
198
198
)
199
199
except InvalidSignatureException :
200
200
self .logger .error ("failed to check signature, please check your settings." )
201
201
raise HTTPException (status_code = 403 )
202
- msg = self .parse_message (msg )
202
+ msg = self .api_delegate . parse_message (msg )
203
203
204
204
if msg .id in self .reply_tasks :
205
205
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)
262
262
async def _send_text (self , user_id : str , text : str ):
263
263
"""发送文本消息"""
264
264
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 )
266
266
except Exception as e :
267
267
self .logger .error (f"Failed to send text message: { e } " )
268
268
raise e
@@ -271,10 +271,7 @@ async def _send_media(self, user_id: str, media_data: str, media_type: str):
271
271
"""发送媒体消息的通用方法"""
272
272
try :
273
273
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 )
278
275
except Exception as e :
279
276
self .logger .error (f"Failed to send { media_type } message: { e } " )
280
277
raise e
0 commit comments