23
23
from io import BytesIO
24
24
25
25
import aiohttp
26
+ from fastapi import FastAPI , HTTPException , Request , Response
26
27
from pydantic import BaseModel , ConfigDict , Field
27
- from quart import Quart , abort , request
28
28
from wechatpy .exceptions import InvalidSignatureException
29
29
30
30
from kirara_ai .im .adapter import IMAdapter
@@ -123,13 +123,13 @@ class WecomAdapter(IMAdapter):
123
123
124
124
def __init__ (self , config : WecomConfig ):
125
125
self .config = config
126
- if "host" in config . __pydantic_extra__ and config .__pydantic_extra__ [ " host" ] is not None :
127
- self .app = Quart ( __name__ )
126
+ if self . config .host :
127
+ self .app = FastAPI ( )
128
128
else :
129
129
self .app = self .web_server .app
130
130
131
131
self .crypto = WeChatCrypto (
132
- config .token , config .encoding_aes_key , config .corp_id or config .agent_id
132
+ config .token , config .encoding_aes_key , config .corp_id or config .app_id
133
133
)
134
134
self .client = WeChatClient (config .corp_id , config .secret )
135
135
self .logger = get_logger ("Wecom-Adapter" )
@@ -149,36 +149,37 @@ def setup_routes(self):
149
149
webhook_url = self .config .webhook_url
150
150
151
151
@self .app .get (webhook_url )
152
- async def handle_check_request ():
152
+ async def handle_check_request (request : Request ):
153
153
"""处理 GET 请求"""
154
154
if not self .is_running :
155
- return abort (404 )
156
- signature = request .args .get ("msg_signature" , "" )
157
- timestamp = request .args .get ("timestamp" , "" )
158
- nonce = request .args .get ("nonce" , "" )
159
- echo_str = request .args .get ("echostr" , "" )
155
+ raise HTTPException (status_code = 404 )
156
+
157
+ signature = request .query_params .get ("msg_signature" , "" )
158
+ timestamp = request .query_params .get ("timestamp" , "" )
159
+ nonce = request .query_params .get ("nonce" , "" )
160
+ echo_str = request .query_params .get ("echostr" , "" )
160
161
try :
161
162
echo_str = self .crypto .check_signature (
162
163
signature , timestamp , nonce , echo_str
163
164
)
164
- return echo_str
165
+ return Response ( content = echo_str , media_type = "text/plain" )
165
166
except InvalidSignatureException :
166
- return abort ( 403 )
167
+ raise HTTPException ( status_code = 403 )
167
168
168
169
@self .app .post (webhook_url )
169
- async def handle_message ():
170
+ async def handle_message (request : Request ):
170
171
"""处理 POST 请求"""
171
172
if not self .is_running :
172
- return abort ( 404 )
173
- signature = request .args .get ("msg_signature" , "" )
174
- timestamp = request .args .get ("timestamp" , "" )
175
- nonce = request .args .get ("nonce" , "" )
173
+ raise HTTPException ( status_code = 404 )
174
+ signature = request .query_params .get ("msg_signature" , "" )
175
+ timestamp = request .query_params .get ("timestamp" , "" )
176
+ nonce = request .query_params .get ("nonce" , "" )
176
177
try :
177
178
msg = self .crypto .decrypt_message (
178
- await request .data , signature , timestamp , nonce
179
+ await request .body () , signature , timestamp , nonce
179
180
)
180
181
except (InvalidSignatureException , InvalidCorpIdException ):
181
- return abort ( 403 )
182
+ raise HTTPException ( status_code = 403 )
182
183
msg = parse_message (msg )
183
184
184
185
# 预处理媒体消息
@@ -192,7 +193,7 @@ async def handle_message():
192
193
message = self .convert_to_message (msg , media_path )
193
194
# 分发消息
194
195
await self .dispatcher .dispatch (self , message )
195
- return "ok"
196
+ return Response ( content = "ok" , media_type = "text/plain" )
196
197
197
198
def convert_to_message (self , raw_message : Any , media_path : Optional [str ] = None ) -> IMMessage :
198
199
"""将企业微信消息转换为统一消息格式"""
@@ -232,7 +233,7 @@ def convert_to_message(self, raw_message: Any, media_path: Optional[str] = None)
232
233
async def _send_text (self , user_id : str , text : str ):
233
234
"""发送文本消息"""
234
235
try :
235
- return self .client .message .send_text (self .config .agent_id , user_id , text )
236
+ return self .client .message .send_text (self .config .app_id , user_id , text )
236
237
except Exception as e :
237
238
self .logger .error (f"Failed to send text message: { e } " )
238
239
@@ -243,7 +244,7 @@ async def _send_media(self, user_id: str, media_data: str, media_type: str):
243
244
media_id = self .client .media .upload (
244
245
media_type , media_bytes )["media_id" ]
245
246
send_method = getattr (self .client .message , f"send_{ media_type } " )
246
- return send_method (self .config .agent_id , user_id , media_id )
247
+ return send_method (self .config .app , user_id , media_id )
247
248
except Exception as e :
248
249
self .logger .error (f"Failed to send { media_type } message: { e } " )
249
250
0 commit comments