refactor: migrate workflow to v2 core and archive legacy modules
This commit is contained in:
128
legacy/websocket_helpers_flow.py
Normal file
128
legacy/websocket_helpers_flow.py
Normal file
@@ -0,0 +1,128 @@
|
||||
import asyncio
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def fire_and_forget(client, coro):
|
||||
"""后台执行协程,不阻塞接收循环;异常会记录到日志。"""
|
||||
task = asyncio.create_task(coro)
|
||||
|
||||
def _done(t):
|
||||
if t.cancelled():
|
||||
return
|
||||
exc = t.exception()
|
||||
if exc:
|
||||
client.logger.exception(f"后台任务异常: {exc}")
|
||||
|
||||
task.add_done_callback(_done)
|
||||
|
||||
|
||||
def prune_seen(seen: dict, now_mono: float, ttl_sec: float = 8.0):
|
||||
if len(seen) <= 2000:
|
||||
return
|
||||
stale = [k for k, t in seen.items() if (now_mono - t) > ttl_sec]
|
||||
for k in stale:
|
||||
seen.pop(k, None)
|
||||
|
||||
|
||||
def log_inbound_once(client, data: dict, chat_log_fn):
|
||||
"""统一记录入站消息,短窗口去重,避免多分支重复写库。"""
|
||||
try:
|
||||
cid = data.get("from_id", "")
|
||||
if not cid:
|
||||
return
|
||||
msg = client.to_chinese(data.get("msg", "") or "")
|
||||
acc_id = data.get("acc_id", "")
|
||||
mtype = int(data.get("msg_type", 0) or 0)
|
||||
now_mono = time.monotonic()
|
||||
sig = f"{acc_id}|{cid}|{mtype}|{msg}"
|
||||
last = client._inbound_log_seen.get(sig, 0.0)
|
||||
if (now_mono - last) < 2.0:
|
||||
return
|
||||
client._inbound_log_seen[sig] = now_mono
|
||||
prune_seen(client._inbound_log_seen, now_mono, ttl_sec=8.0)
|
||||
chat_log_fn(
|
||||
cid,
|
||||
msg,
|
||||
"in",
|
||||
customer_name=client.to_chinese(data.get("from_name", "") or data.get("cy_name", "")),
|
||||
acc_id=acc_id,
|
||||
platform=data.get("acc_type", ""),
|
||||
msg_type=mtype,
|
||||
)
|
||||
except Exception:
|
||||
client.logger.debug("入站消息写库失败", exc_info=True)
|
||||
|
||||
|
||||
def log_outbound_once(client, original_msg: dict, reply_content: str, chat_log_fn):
|
||||
"""统一记录出站消息,短窗口去重,避免重复写库。"""
|
||||
try:
|
||||
cid = original_msg.get("from_id", "")
|
||||
if not cid:
|
||||
return
|
||||
msg = reply_content or ""
|
||||
acc_id = original_msg.get("acc_id", "")
|
||||
now_mono = time.monotonic()
|
||||
sig = f"{acc_id}|{cid}|0|{msg}"
|
||||
last = client._outbound_log_seen.get(sig, 0.0)
|
||||
if (now_mono - last) < 2.0:
|
||||
return
|
||||
client._outbound_log_seen[sig] = now_mono
|
||||
prune_seen(client._outbound_log_seen, now_mono, ttl_sec=8.0)
|
||||
chat_log_fn(
|
||||
cid,
|
||||
msg,
|
||||
"out",
|
||||
customer_name=client.to_chinese(original_msg.get("from_name", "") or original_msg.get("cy_name", "")),
|
||||
acc_id=acc_id,
|
||||
platform=original_msg.get("acc_type", ""),
|
||||
msg_type=0,
|
||||
)
|
||||
except Exception:
|
||||
client.logger.debug("出站消息写库失败", exc_info=True)
|
||||
|
||||
|
||||
def build_customer_message(client, data: dict, customer_message_cls):
|
||||
"""把原始消息字典转换为 Agent 输入模型。"""
|
||||
return customer_message_cls(
|
||||
msg_id=data.get("msg_id", ""),
|
||||
acc_id=data.get("acc_id", ""),
|
||||
msg=client.to_chinese(data.get("msg", "")),
|
||||
from_id=data.get("from_id", ""),
|
||||
from_name=client.to_chinese(data.get("from_name", "")),
|
||||
cy_id=data.get("cy_id", ""),
|
||||
acc_type=data.get("acc_type", ""),
|
||||
msg_type=data.get("msg_type", 0),
|
||||
cy_name=client.to_chinese(data.get("cy_name", "")),
|
||||
goods_name=client.to_chinese(data.get("goods_name", "")) if data.get("goods_name") else None,
|
||||
goods_order=client.to_chinese(data.get("goods_order", "")) if data.get("goods_order") else None,
|
||||
)
|
||||
|
||||
|
||||
def touch_customer_last_contact(client, customer_id: str, db):
|
||||
"""兜底更新客户最后联系时间。"""
|
||||
if not customer_id:
|
||||
return
|
||||
try:
|
||||
profile = db.get_customer(customer_id)
|
||||
profile.last_contact = datetime.now().isoformat()
|
||||
db.save_customer(profile)
|
||||
except Exception:
|
||||
client.logger.debug("更新客户最后联系时间失败: customer_id=%s", customer_id, exc_info=True)
|
||||
|
||||
|
||||
def push_chat_to_wechat_safe(client, *, data: dict, customer_msg: str, reply_msg: str, tag: str, goods_name: str = ""):
|
||||
"""异步推送企微聊天日志,失败不影响主流程。"""
|
||||
try:
|
||||
from utils.wechat_chat_log import push_chat_to_wechat
|
||||
|
||||
asyncio.create_task(push_chat_to_wechat(
|
||||
customer_name=client.to_chinese(data.get("from_name", "") or data.get("cy_name", "")),
|
||||
customer_id=data.get("from_id", ""),
|
||||
acc_id=data.get("acc_id", ""),
|
||||
customer_msg=client.to_chinese(customer_msg or ""),
|
||||
reply_msg=reply_msg or "",
|
||||
goods_name=goods_name or client.to_chinese(data.get("goods_name", "") or ""),
|
||||
))
|
||||
except Exception:
|
||||
client.logger.debug("推送企微聊天日志失败(%s)", tag, exc_info=True)
|
||||
Reference in New Issue
Block a user