落地空运群内协同与锁舱出站。

群里按 BOT 通道激活当前工单、航线报价和成交跟进;没有 TMS 报价编号时用工单字段补齐仍调锁舱,避免被本地规则拦住。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-16 17:25:42 +08:00
co-authored by Cursor
parent 12219cacb1
commit d9029dec89
62 changed files with 6772 additions and 159 deletions
@@ -123,6 +123,21 @@ def poll_once(
page_size = int(getattr(cfg, "wshoto_page_size", 50) or 50)
clock = now or time.time
rooms = list_watched_rooms(redis=redis)
scan_ids = [
x.strip()
for x in str(getattr(cfg, "wshoto_scan_user_ids", "") or "").replace(";", ",").split(",")
if x.strip()
]
extra: list[dict[str, Any]] = []
if scan_ids:
extra = _poll_by_scan_users(
api,
userids=scan_ids,
redis=redis,
page_size=page_size,
lookback=lookback,
clock=clock,
)
if rooms:
# 应用群必须带房间号、不要带存档席 userid,否则管家返回空页。
records, mode, last = _poll_by_rooms(
@@ -132,6 +147,8 @@ def poll_once(
lookback=lookback,
clock=clock,
)
if extra:
records = list(records) + extra
else:
seat = seats[0] if seats else ""
last = load_last_seq(f"seat:{seat or 'default'}", redis=redis)
@@ -160,6 +177,9 @@ def poll_once(
lookback=lookback,
clock=clock,
)
if extra:
records = list(records) + extra
mode = "rooms"
# 按房间拉时各群自己的 last_seq 已经过滤过,这里不要再用席游标误丢。
ingest_min = 0 if mode == "rooms" else last
enqueued, skipped = ingest_records(
@@ -194,6 +214,61 @@ def poll_once(
}
def _poll_by_scan_users(
api: WshotoOpenClient,
*,
userids: Sequence[str],
redis: Optional[RedisClient],
page_size: int,
lookback: int,
clock: Callable[[], float],
) -> list[dict[str, Any]]:
"""
按人扫新群。空运群是人自建的,存档席没进群时房间名单里没有它。
副作用:看到带 @询价小助手 的新房间会登记监听。
"""
from agent.channel.wshoto.rooms import watch_collab_room
merged: list[dict[str, Any]] = []
now = int(clock())
for uid in userids:
scope = f"scan:{uid}"
last = load_last_seq(scope, redis=redis)
time_start = 0
time_end = 0
if last <= 0:
time_end = now
time_start = time_end - min(lookback, 8 * 3600)
try:
rows = api.list_group_messages(
userid=uid,
last_seq=last,
page_size=page_size,
msg_time_start=time_start,
msg_time_end=time_end,
)
except WshotoError as exc:
logger.warning("微盛按人扫群失败 userid=%s code=%s", uid, exc.code)
continue
max_seq = last
for rec in rows:
seq = _record_seq(rec)
if seq > max_seq:
max_seq = seq
room = str(rec.get("room_id") or rec.get("roomid") or "").strip()
blob = str(rec.get("content") or "")
if room and "询价小助手" in blob:
try:
watch_collab_room(room, redis=redis)
except Exception:
logger.exception("扫到空运群后登记监听失败 chat=%s", room)
if max_seq > last:
save_last_seq(scope, max_seq, redis=redis)
merged.extend(rows)
return merged
def _poll_by_rooms(
api: WshotoOpenClient,
*,