# Xianyu Openclaw

> 闲鱼数字商品客服和自动发货技能，支持拉取会话、查询订单、自动发货、补发、风险升级。 Use when: 需要在闲鱼场景中处理售前咨询、已付款发货、补发、退款投诉升级。 NOT for: 自动议价、绕过付款直接发货、处理高风险纠纷结论判定。

- Skill: `zh2232560-create/xianyu-openclaw` (Agent Skill, multi-file: 12 files)
- Install (CLI): `npx skillmds@latest add zh2232560-create/xianyu-openclaw`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zh2232560-create/xianyu-openclaw/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: zh2232560-create (https://skillmd.com/u/zh2232560-create)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/zh2232560-create/xianyu-openclaw

---


# Xianyu OpenClaw Skill

> **运行环境**：Python 3.11+；mock 模式无需额外依赖；真实模式需 `pip install playwright` 并执行 `playwright install chromium`。
> 默认为 mock 模式（`XIANYU_MOCK_MODE=true`），数据存储在 `assets/data/*.json`。

## When to Run
- 需要查询闲鱼未读会话
- 买家已付款，需要自动发货或补发数字商品
- 买家提到退款、投诉、平台介入，需要升级人工
- 本地联调时模拟买家消息

## Workflow

### 0. 初始化（首次使用）

**重置 mock 数据（将 seeds 复制到 data）：**
```bash
python scripts/reset_data.py
```

**真实模式——保存登录态（仅需运行一次）：**
```bash
python scripts/browser_login.py
```

---

### 1. 拉取未读会话
```bash
python scripts/pull_inbox.py --limit 5
```
返回按 `last_message_at` 倒序的会话列表。取第一条获得 `session_id`，进入步骤 2。

---

### 2. 获取会话上下文
```bash
python scripts/get_conversation.py --session-id <session_id> --limit 20
```
返回 `messages` 数组和 `item_context`（商品信息），用于判断买家意图。

---

### 3. 风险评估
```bash
python scripts/evaluate_risk.py --session-id <session_id>
```
- 返回 `need_human: true` → 跳到**步骤 7（升级人工）**
- 返回 `need_human: false` → 根据买家意图进入步骤 4 / 5 / 6

---

### 4. 售前咨询 → 搜索 FAQ 并回复
```bash
python scripts/search_faq.py --session-id <session_id> --query "<买家问题关键词>" --limit 3
python scripts/send_message.py --session-id <session_id> --message "<FAQ答案>"
```

---

### 5. 已付款 → 查询订单并发货
```bash
python scripts/find_order.py --session-id <session_id>
python scripts/deliver_order.py --order-id <order_id>
python scripts/send_message.py --session-id <session_id> --message "<发货结果消息>"
```
> 发货幂等：相同 `order_id` 多次调用只发一次，返回首次 payload（`idempotent: true`）。

---

### 6. 补发（链接失效 / 兑换码无效）
```bash
python scripts/resend_delivery.py --order-id <order_id> --reason link_expired
python scripts/send_message.py --session-id <session_id> --message "<新链接或兑换码>"
```
`--reason` 可选值：`link_expired` | `code_invalid` | `manual_request`

---

### 7. 升级人工工单
```bash
python scripts/escalate_ticket.py \
  --session-id <session_id> \
  --reason refund_request \
  --summary "<问题摘要>" \
  [--order-id <order_id>]
```
`--reason` 可选值：`refund_request` | `platform_intervention` | `complaint` | `other`

---

### 完整决策流程
```
pull_inbox → get_conversation → evaluate_risk
  ├─ low risk + 售前咨询  → search_faq → LLM generate → send_message
  ├─ low risk + 已付款    → find_order → deliver_order → send_message
  ├─ low risk + 补发请求  → resend_delivery → send_message
  └─ high risk            → escalate_ticket
```

### AI 自动编排（一键触发）
```bash
# 对单个会话执行全自动决策 + 回复
python scripts/auto_reply.py --session-id s_001

# 预览决策但不发送（调试用）
python scripts/auto_reply.py --session-id s_001 --dry-run
```

### 持续监听新消息
```bash
# 每 30 秒轮询一次（默认间隔）
python scripts/watch_inbox.py

# 自定义间隔（秒）
python scripts/watch_inbox.py --interval 10

# 单次执行（--interval 0）
python scripts/watch_inbox.py --interval 0

# 调试模式：只打印决策不发送
python scripts/watch_inbox.py --dry-run
```

---

## Script 速查表

| 脚本 | 用途 | 参数 |
|---|---|---|
| `reset_data.py` | 重置 mock 数据 | — |
| `browser_login.py` | 保存真实登录态（仅实模式） | — |
| `pull_inbox.py` | 拉取未读会话 | `--limit`（可选，默认10） |
| `get_conversation.py` | 获取会话消息上下文 | `--session-id`（必填）`--limit`（可选） |
| `evaluate_risk.py` | 风险评估 | `--session-id`（必填） |
| `search_faq.py` | 搜索商品 FAQ | `--session-id`（必填）`--query`（必填）`--limit`（可选） |
| `send_message.py` | 发送消息 | `--session-id`（必填）`--message`（必填） |
| `find_order.py` | 查询订单 | `--session-id` 或 `--buyer-id` 或 `--item-id`（三选一） |
| `deliver_order.py` | 自动发货（幂等） | `--order-id`（必填） |
| `resend_delivery.py` | 补发 | `--order-id`（必填）`--reason`（必填） |
| `escalate_ticket.py` | 升级人工工单 | `--session-id`（必填）`--reason`（必填）`--summary`（必填）`--order-id`（可选） |
| `simulate_message.py` | 模拟买家消息（本地联调） | `--session-id`（必填）`--message`（必填） |
| `auto_reply.py` | AI 自动回复（全流程编排） | `--session-id`（必填）`--dry-run`（可选） |
| `watch_inbox.py` | 持续监听并自动回复 | `--interval`（可选）`--limit`（可选）`--dry-run`（可选） |

---

## Example Commands

```bash
# ① 重置数据
python scripts/reset_data.py

# ② 拉取会话
python scripts/pull_inbox.py --limit 2

# ③ 模拟买家发消息后再查看会话
python scripts/simulate_message.py --session-id s_001 --message "链接失效了"
python scripts/get_conversation.py --session-id s_001

# ④ 风险评估 → 发货
python scripts/evaluate_risk.py --session-id s_001
python scripts/find_order.py --session-id s_001
python scripts/deliver_order.py --order-id o_001
python scripts/send_message.py --session-id s_001 --message "已为你发货，请查收。"

# ⑤ 补发
python scripts/resend_delivery.py --order-id o_001 --reason link_expired
python scripts/send_message.py --session-id s_001 --message "已补发，新链接请查收。"

# ⑥ 升级人工
python scripts/escalate_ticket.py --session-id s_001 --reason refund_request --summary "买家投诉退款"

# ⑦ AI 一键自动回复（决策 + 发送）
python scripts/auto_reply.py --session-id s_001
python scripts/auto_reply.py --session-id s_001 --dry-run  # 只预览不发送

# ⑧ 持续监听（生产运行方式）
python scripts/watch_inbox.py --interval 30
```

## Output Format

所有脚本返回统一 JSON：

```jsonc
{
  "ok": true,       // boolean - 是否成功
  "data": { ... }   // object/array - 业务数据
}
// 失败时：
{
  "ok": false,
  "error": "错误描述..."
}
```

### 各脚本的 data 结构

#### pull_inbox.py
```json
[
  {
    "session_id": "s_001",
    "buyer_id": "b_001",
    "buyer_name": "小王",
    "item_id": "item_123",
    "unread_count": 1,
    "last_message_at": "2026-03-30T10:00:00Z"
  }
]
```

#### get_conversation.py
```json
{
  "session_id": "s_001",
  "messages": [
    { "role": "buyer",  "content": "这个适合零基础吗？" },
    { "role": "seller", "content": "适合，从基础讲起。" }
  ],
  "item_context": { "item_id": "item_123", "title": "Python 入门电子书" }
}
```

#### evaluate_risk.py
```json
{ "level": "low", "need_human": false, "hits": [] }
```

#### search_faq.py
```json
[
  { "question": "适合零基础吗？", "answer": "适合，无需编程经验。", "score": 12 }
]
```

#### send_message.py
```json
{ "session_id": "s_001", "message_id": "s_001-5", "sent_at": "2026-03-30T10:10:00Z" }
```

#### find_order.py
```json
[
  {
    "order_id": "o_001",
    "sku": "ebook_python_001",
    "amount": 29.9,
    "payment_status": "paid",
    "delivery_status": "pending",
    "order_status": "paid",
    "created_at": "2026-03-30T10:05:00Z"
  }
]
```

#### deliver_order.py
```json
{
  "order_id": "o_001",
  "delivery_status": "success",
  "message_to_buyer": "你购买的是《Python 入门电子书》\n下载链接：https://...",
  "idempotent": false
}
```

#### resend_delivery.py
```json
{
  "order_id": "o_001",
  "delivery_status": "resent",
  "attempt_no": 2,
  "message_to_buyer": "已为你补发《Python 入门电子书》下载链接：https://..."
}
```

#### escalate_ticket.py
```json
{ "ticket_id": "T-A1B2C3D4E5", "status": "open", "created_at": "2026-03-30T10:20:00Z" }
```

