---
name: user-feedback-data-source
description: |
  用户反馈原始数据获取层。定义所有反馈数据的来源、存储位置、表结构和查询方式。
  支持三类数据源：
  1. 主动上报：用户发送"用户反馈:"开头的消息，实时记录到飞书知识库
  2. 飞书内部反馈群：「内容测试问题反馈」群消息，定时同步到 MySQL
  3. 微信用户反馈群：「用户火线救火」群消息，实时存储到 MySQL
  
  **当以下情况时使用此 Skill**：
  (1) 需要了解反馈数据从哪来、存在哪、什么结构
  (2) 需要查询原始反馈数据（飞书群/微信群/主动上报）
  (3) 需要维护数据采集脚本或定时任务
  (4) 用户发送"用户反馈:"开头的消息，需要记录
  (5) 被 user-feedback-processor 技能引用，作为数据源说明
---

# 用户反馈数据获取

本技能定义用户反馈的**原始数据来源**、存储方式和查询接口。是反馈处理流程的底层数据层。

> **维护负责人：** 技术负责人（李若松）
> **下游消费者：** `user-feedback-processor` 技能（产品经理使用）

## 数据源总览

| 反馈渠道 | 来源 | 存储位置 | 更新频率 |
|---------|------|----------|----------|
| 主动上报 | 用户发送 `用户反馈:` 前缀消息 | 飞书知识库文档 | 实时 |
| 飞书内部测试反馈 | 「内容测试问题反馈」群（`oc_fabff7672e62a9ced7b326ee4a286c26`） | MySQL：`vala_test.lark_group_message` | 每天 8 次（08/10/12/14/16/18/20/22 点） |
| 微信用户反馈 | 「用户火线救火」群 | MySQL：`vala_test.wechat_group_message` | 实时（每分钟同步） |

## 数据源一：主动上报

### 触发条件

用户消息以 `用户反馈:` 或 `用户反馈：` 开头。

### 执行流程

1. **提取反馈正文** — 去掉前缀，去除前后空白
2. **总结梳理** — 提炼核心观点，保留关键事实和诉求，不超过 300 字；原文条理清晰则保持原文
3. **获取提交人** — 通过 `sender_id` 调用 `feishu_get_user` 获取姓名
4. **追加写入文档** — Bot 身份写入知识库文档：
   ```bash
   LARKSUITE_CLI_CONFIG_DIR=/root/.openclaw/credentials/xiaokui \
     lark-cli docs +update --doc NVCRdIChwot7oPxcpopcBFMOned --as bot --mode append \
     --markdown '<写入内容>'
   ```
5. **确认回复** — 成功：「✅ 反馈已记录，感谢！」；失败：告知具体错误

### 写入格式

```markdown
---

**📅 时间：** YYYY-MM-DD HH:mm

**👤 提交人：** <用户姓名>

**📝 反馈摘要：**

<总结梳理后的内容，不超过300字>

**💬 原始反馈：**

<反馈原文>
```

- 时间使用 Asia/Shanghai 时区
- 文档为空时先写标题 `# 📋 用户反馈记录`，首条不需要开头分割线

### 存储位置

- **文档标题：** 用户反馈问题汇总
- **Wiki Token：** `ApVZw0fxGiv48ekuRS8cIfUjnRf`
- **知识空间 ID：** `7612229802338045122`

## 数据源二：飞书内部测试反馈群

### 采集方式

定时脚本 `feishu-group-msg-sync` 以 Bot 身份拉取群消息，媒体文件上传到腾讯 COS，所有记录写入 MySQL。

- **定时任务：** `scripts/run_lark_group_sync.sh`（crontab 每天 8 次）
- **底层脚本：** `skills/feishu-group-msg-sync/scripts/sync_group_to_mysql.py`
- **同步状态文件：** `/tmp/last_feishu_feedback_sync_time`

### 数据库表：`vala_test.lark_group_message`

| 字段 | 类型 | 说明 |
|------|------|------|
| id | bigint unsigned | 自增主键 |
| chat_id | varchar(128) | 群聊 ID |
| chat_name | varchar(255) | 群聊名称 |
| sender_id | varchar(128) | 发送者 open_id |
| sender_name | varchar(255) | 发送者姓名 |
| message_id | varchar(128) | 飞书消息 ID（`om_xxx`），唯一索引 |
| parent_id | varchar(128) | 父消息 ID（thread） |
| root_id | varchar(128) | 根消息 ID（thread） |
| quote_message_id | varchar(128) | 引用消息 ID（回复引用） |
| msg_type | varchar(32) | 消息类型（text/post/image/media/audio/file/sticker） |
| content | text | 文本内容或描述 |
| media_url | varchar(1024) | 媒体文件 COS URL |
| msg_time | datetime | 消息时间 |
| msg_timestamp | bigint | 消息时间戳（毫秒） |
| collected_at | datetime | 入库时间 |

### 查询示例

```sql
-- 查询最近 7 天的飞书反馈
SELECT sender_name, msg_type, content, media_url, msg_time
FROM lark_group_message 
WHERE chat_id = 'oc_fabff7672e62a9ced7b326ee4a286c26'
  AND msg_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
ORDER BY msg_timestamp DESC;

-- 查询某条消息的完整对话链（原消息 + 所有回复）
SELECT message_id, sender_name, content, msg_time,
       IF(quote_message_id IS NULL, '原消息', '↳ 回复') AS role
FROM lark_group_message 
WHERE message_id = '<target_id>' OR quote_message_id = '<target_id>'
ORDER BY msg_timestamp;
```

## 数据源三：微信用户反馈群

### 采集方式

微信群消息通过外部同步工具实时写入 MySQL，每分钟增量同步。

- **定时任务：** `scripts/sync_wechat_feedback_minutely.py`（crontab 每分钟）

### 数据库表：`vala_test.wechat_group_message`

| 字段 | 类型 | 说明 |
|------|------|------|
| svr_msg_id | bigint | 消息唯一 ID |
| sender_name | varchar(255) | 发送者昵称 |
| msg_type | int | 消息类型 |
| content | text | 文本内容 |
| media_url | varchar(1024) | 媒体文件 URL |
| refer_msg_svrid | bigint | 引用消息 ID（回复引用） |
| msg_time | datetime | 消息时间 |
| msg_timestamp | bigint | 消息时间戳（毫秒） |

### 查询示例

```sql
-- 查询最近 7 天的微信反馈
SELECT sender_name, msg_type, content, media_url, msg_time
FROM wechat_group_message 
WHERE msg_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
ORDER BY msg_timestamp DESC;

-- 查询完整对话链
SELECT svr_msg_id, sender_name, content, msg_time,
       IF(refer_msg_svrid IS NULL, '原消息', '↳ 回复') AS role
FROM wechat_group_message 
WHERE svr_msg_id = <target_id> OR refer_msg_svrid = <target_id>
ORDER BY msg_timestamp;
```

## 引用回复关系（跨渠道对照）

| 说明 | 飞书 `lark_group_message` | 微信 `wechat_group_message` |
|------|---------------------------|------------------------------|
| 消息唯一 ID | `message_id`（varchar, `om_xxx`） | `svr_msg_id`（bigint） |
| 被引用消息 ID | `quote_message_id`（varchar） | `refer_msg_svrid`（bigint） |
| 判断是否为回复 | `quote_message_id IS NOT NULL` | `refer_msg_svrid IS NOT NULL` |

## 数据库连接信息

- **主机：** `bj-cdb-8frbdwju.sql.tencentcdb.com`
- **端口：** `25413`
- **用户：** `chatbot`
- **密码：** 见 `secrets.env`
- **数据库：** `vala_test`
- **权限：** 查询操作默认只读

## 注意事项

- 所有飞书操作使用 Bot 身份（`--as bot`），不触发用户授权
- 反馈数据为原始数据，不做分类和优先级判定（由下游 `user-feedback-processor` 处理）
- 任何人都可以提交主动上报反馈，无权限限制
- 数据采集脚本和定时任务的维护由技术负责人负责
