修复空运锁舱签名、报价编号落库和查价 Token 失效重试。
锁舱按签名原字节出站,查价要带上 TMS 真实 quoteId/optionNo;收到 2001 换令牌再查,避免工单建了却提示查询失败。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -23,8 +23,8 @@ class AibotReplyClient:
|
||||
"""
|
||||
空运群出站客户端。
|
||||
|
||||
一次 @ 若带了 response_url,优先走流式回复。
|
||||
存档听到附件时没有 url:改走桥主动发言。该群须先被 @ 过,企微才允许主动说。
|
||||
@ 带了 response_url:流式只收口这次 @;正文走桥主动发言,和发模板同一条通道。
|
||||
存档听到附件时没有 url:直接走桥。该群须先被 @ 过,企微才允许主动说。
|
||||
"""
|
||||
|
||||
def __init__(self, response_url: str = "", timeout_sec: float = 8.0) -> None:
|
||||
@@ -44,9 +44,18 @@ class AibotReplyClient:
|
||||
self.sent.append({"chat_id": chat_id, "content": text, "kind": "text"})
|
||||
if not text:
|
||||
return {"ok": False, "error": "empty"}
|
||||
room = str(chat_id or "").strip()
|
||||
# @ 当场流式回话群里经常看不见长摘要,模板却走主动发言,就会只剩一张表。
|
||||
# 工单信息必须再走桥,和模板同一条通道;流式只收口这次 @。
|
||||
if self._url:
|
||||
return self._send_stream(chat_id, text)
|
||||
return self._send_proactive(str(chat_id or "").strip(), text)
|
||||
self._send_stream(room, text.split("\n", 1)[0][:80])
|
||||
if room:
|
||||
out = self._send_proactive(room, text)
|
||||
if out.get("ok") or not self._url:
|
||||
return out
|
||||
if self._url:
|
||||
return self._send_stream(room, text)
|
||||
return {"ok": False, "error": "no_chat_id"}
|
||||
|
||||
def _send_stream(self, chat_id: str, text: str) -> dict[str, Any]:
|
||||
"""@ 当场回话:POST 企微给的 response_url。"""
|
||||
|
||||
@@ -92,12 +92,25 @@ class AibotReplyTests(unittest.TestCase):
|
||||
self.assertEqual(payload["chatid"], "wr_air_1")
|
||||
self.assertEqual(payload["filename"], "WO1_quote.xlsx")
|
||||
|
||||
def test_stream_url_does_not_hit_bridge(self) -> None:
|
||||
def test_at_reply_puts_brief_on_same_channel_as_file(self) -> None:
|
||||
"""
|
||||
@ 当场流式回话群里经常只看得见后面的文件。
|
||||
工单信息必须再走桥主动发言,和模板同一条通道。
|
||||
"""
|
||||
client = AibotReplyClient("https://example.com/reply")
|
||||
fake_http = MagicMock()
|
||||
fake_http.post.return_value.status_code = 200
|
||||
with patch("agent.channel.aibot.reply.httpx", fake_http):
|
||||
out = client.send_group(chat_id="wr_air_1", content="已激活")
|
||||
fake_http.post.return_value.text = '{"status":"sent"}'
|
||||
settings = MagicMock()
|
||||
settings.wecom_aibot_bridge_url = "http://127.0.0.1:8913"
|
||||
settings.wecom_aibot_bridge_token = "tok"
|
||||
brief = "工单号:WO202609160014\n询价字段:\n起运地:ZUH"
|
||||
with patch("agent.channel.aibot.reply.httpx", fake_http), patch(
|
||||
"agent.channel.aibot.reply.get_settings", return_value=settings
|
||||
):
|
||||
out = client.send_group(chat_id="wr_air_1", content=brief)
|
||||
self.assertTrue(out["ok"])
|
||||
url, = fake_http.post.call_args.args
|
||||
self.assertEqual(url, "https://example.com/reply")
|
||||
urls = [c.args[0] for c in fake_http.post.call_args_list]
|
||||
self.assertTrue(any(u.endswith("/send") or u.endswith("/send-group") for u in urls))
|
||||
payloads = [c.kwargs.get("json") or {} for c in fake_http.post.call_args_list]
|
||||
self.assertTrue(any(p.get("content") == brief for p in payloads))
|
||||
|
||||
Reference in New Issue
Block a user