根因: sendtyping三个bug - 1.ilink_user_id误用bot ID(应from_user_id用户ID) 2.请求缺base_info 3.未检查ret==0。另发现账号session已过期(-14 session timeout)是sendtyping失效+文本失败的根源。修复: getconfig/sendtyping补base_info+正确ilink_user_id+ret==0判断, -14时写session_expired日志。
This commit is contained in:
1 parent
9cf4378bf5
commit
f975672b0e
1 file changed
+32
-8
@@ -319,7 +319,11 @@ def _wechat_send_message(baseurl: str, bot_token: str, to_user_id: str, context_
|
||||
|
||||
|
||||
def _wechat_get_typing_ticket(baseurl: str, bot_token: str, ilink_user_id: str, context_token: str) -> str:
|
||||
"""getconfig 获取 typing_ticket(按 ilink_user_id 缓存 24h)。"""
|
||||
"""getconfig 获取 typing_ticket(按 ilink_user_id 缓存 24h)。
|
||||
|
||||
#974 修复:ilink_user_id 必须传【用户 ID】(from_user_id),不是 bot ID;
|
||||
请求体必须带 base_info;响应必须 ret==0 才算成功。
|
||||
"""
|
||||
global _typing_ticket_cache
|
||||
_now = time.time()
|
||||
_hit = _typing_ticket_cache.get(ilink_user_id)
|
||||
@@ -329,14 +333,30 @@ def _wechat_get_typing_ticket(baseurl: str, bot_token: str, ilink_user_id: str,
|
||||
resp = requests.post(
|
||||
baseurl.rstrip("/") + "/ilink/bot/getconfig",
|
||||
headers=_wechat_headers(bot_token),
|
||||
json={"ilink_user_id": ilink_user_id, "context_token": context_token},
|
||||
json={
|
||||
"ilink_user_id": ilink_user_id,
|
||||
"context_token": context_token,
|
||||
"base_info": {"channel_version": "1.0.3"},
|
||||
},
|
||||
timeout=10,
|
||||
)
|
||||
body = resp.json() if resp.content else {}
|
||||
# ret==0 才算成功;-14 会话过期 / -4 RPC 失败均无 ticket
|
||||
ret = body.get("ret")
|
||||
errcode = body.get("errcode")
|
||||
if ret == 0 or (ret is None and errcode is None):
|
||||
ticket = body.get("typing_ticket", "") if isinstance(body, dict) else ""
|
||||
if ticket:
|
||||
_typing_ticket_cache[ilink_user_id] = (ticket, _now)
|
||||
return ticket
|
||||
# 会话过期:记录,供上层标记 expired
|
||||
if errcode == -14 or ret == -14:
|
||||
try:
|
||||
with open("/tmp/wechat_session_expired.log", "a", encoding="utf-8") as _f:
|
||||
_f.write(_beijing_now().isoformat() + " GETCONFIG_SESSION_EXPIRED user=%s\n" % ilink_user_id)
|
||||
except Exception:
|
||||
pass
|
||||
return ""
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
@@ -349,7 +369,12 @@ def _wechat_send_typing(baseurl: str, bot_token: str, ilink_user_id: str, typing
|
||||
resp = requests.post(
|
||||
baseurl.rstrip("/") + "/ilink/bot/sendtyping",
|
||||
headers=_wechat_headers(bot_token),
|
||||
json={"ilink_user_id": ilink_user_id, "typing_ticket": typing_ticket, "status": status},
|
||||
json={
|
||||
"ilink_user_id": ilink_user_id,
|
||||
"typing_ticket": typing_ticket,
|
||||
"status": status,
|
||||
"base_info": {"channel_version": "1.0.3"},
|
||||
},
|
||||
timeout=10,
|
||||
)
|
||||
return resp.ok
|
||||
@@ -633,12 +658,11 @@ def _wechat_receiver_loop(account_id: int):
|
||||
+ " ctx=" + repr(ctx) + " raw=" + json.dumps(m, ensure_ascii=False) + "\n")
|
||||
except Exception:
|
||||
pass
|
||||
# 发送"正在输入"状态(尽力而为,失败静默)
|
||||
# 发送"正在输入"状态(#974:ilink_user_id 用用户 ID = sender,非 bot ID)
|
||||
try:
|
||||
_bot_id = m.get("to_user_id") or d.get("ilink_bot_id") or ""
|
||||
_ticket = _wechat_get_typing_ticket(baseurl, bot_token, _bot_id, ctx)
|
||||
if _bot_id and _ticket:
|
||||
_wechat_send_typing(baseurl, bot_token, _bot_id, _ticket, 1)
|
||||
_ticket = _wechat_get_typing_ticket(baseurl, bot_token, sender, ctx)
|
||||
if sender and _ticket:
|
||||
_wechat_send_typing(baseurl, bot_token, sender, _ticket, 1)
|
||||
except Exception:
|
||||
pass
|
||||
# 先生成回复(此时历史尚未包含本条,避免重复)
|
||||
|
||||
Reference in new issue
Block a user