fix: 关键词回复优先并后台触发B同步
将A回调链路调整为先返回关键词回复,再以后台任务触发B接口同步,避免B接口耗时或失败影响用户主回复;同时修正微信消息体加解密格式并固定B接口凭据来源。 Made-with: Cursor
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import base64
|
||||
import hashlib
|
||||
import os
|
||||
import struct
|
||||
from typing import Tuple
|
||||
|
||||
from Crypto.Cipher import AES
|
||||
@@ -34,16 +36,31 @@ def get_aes_key_and_iv(encoding_aes_key: str) -> Tuple[bytes, bytes]:
|
||||
|
||||
def aes_decrypt_base64(cipher_b64: str, encoding_aes_key: str) -> str:
|
||||
aes_key, iv = get_aes_key_and_iv(encoding_aes_key)
|
||||
cipher_bytes = base64.b64decode(cipher_b64)
|
||||
# 回调密文偶尔会带换行/空白,先规整再补齐 base64 padding。
|
||||
compact = "".join(str(cipher_b64 or "").split())
|
||||
compact += "=" * (-len(compact) % 4)
|
||||
cipher_bytes = base64.b64decode(compact)
|
||||
cipher = AES.new(aes_key, AES.MODE_CBC, iv)
|
||||
decrypted = cipher.decrypt(cipher_bytes)
|
||||
decrypted = pkcs5_unpadding(decrypted)
|
||||
return decrypted.decode("utf-8")
|
||||
# 微信消息体格式:16B随机串 + 4B网络序长度 + 明文 + appid
|
||||
if len(decrypted) < 20:
|
||||
raise ValueError("解密后消息长度非法")
|
||||
content = decrypted[16:]
|
||||
msg_len = struct.unpack("!I", content[:4])[0]
|
||||
msg_start = 4
|
||||
msg_end = msg_start + msg_len
|
||||
if msg_end > len(content):
|
||||
raise ValueError("解密后消息长度字段越界")
|
||||
msg = content[msg_start:msg_end]
|
||||
return msg.decode("utf-8")
|
||||
|
||||
|
||||
def aes_encrypt_base64(plaintext: str, encoding_aes_key: str) -> str:
|
||||
def aes_encrypt_base64(plaintext: str, encoding_aes_key: str, app_id: str) -> str:
|
||||
aes_key, iv = get_aes_key_and_iv(encoding_aes_key)
|
||||
data = plaintext.encode("utf-8")
|
||||
raw = plaintext.encode("utf-8")
|
||||
# 微信消息体格式:16B随机串 + 4B网络序长度 + 明文 + appid
|
||||
data = os.urandom(16) + struct.pack("!I", len(raw)) + raw + app_id.encode("utf-8")
|
||||
padded = pkcs5_padding(data)
|
||||
cipher = AES.new(aes_key, AES.MODE_CBC, iv)
|
||||
encrypted = cipher.encrypt(padded)
|
||||
|
||||
Reference in New Issue
Block a user