Manage Apple Reminders via the `remindctl` CLI on macOS (list, add, edit, complete, delete)....
npx skills add jianhao3776/skill-hub --skill "daxiang-group-message"
Install specific skill from multi-skill repository
# Description
通过大象网页版向指定群聊或个人会话发送消息、导出聊天记录并生成分析报告。支持文本、图片、文件等多种消息格式。支持按群聊 ID/群名称定位群聊,或按 UID/MIS/姓名定位个人会话,优先使用浏览器内 fetch 调搜索 API,再进入会话并发送。支持提取群聊/私聊的文字、图片、文件等消息,保存为 JSON 归档文件,并生成包含发言排行、活跃时段、高频词等维度的分析报告。
# SKILL.md
name: daxiang-group-message
description: 通过大象网页版向指定群聊或个人会话发送消息、导出聊天记录并生成分析报告。支持文本、图片、文件等多种消息格式。支持按群聊 ID/群名称定位群聊,或按 UID/MIS/姓名定位个人会话,优先使用浏览器内 fetch 调搜索 API,再进入会话并发送。支持提取群聊/私聊的文字、图片、文件等消息,保存为 JSON 归档文件,并生成包含发言排行、活跃时段、高频词等维度的分析报告。
大象网页版自动化(消息发送 + 聊天记录归档)
通过浏览器自动化在大象网页版(x.sankuai.com)中操作,支持消息发送和聊天记录导出分析。
适用场景
当用户提出以下诉求时使用:
- 在大象群里发消息(文本、图片、文件)
- 给某个同事发私聊消息
- 按 MIS/姓名找到人并发送通知
- 往指定会话发送一段文本
- 发送本地图片或文件到大象会话
- 导出/下载/备份大象聊天记录
- 分析聊天数据、统计群聊活跃度
- 查看聊天报告、发言排行、高频词
自动化策略优先级
- 优先:在已登录页面内用
evaluate + fetch()调查询 API,定位目标会话 - 其次:如果已知会话 ID,直接 URL 导航进入会话
- 最后:无法稳定命中 API 结果时,再走 UI 搜索与点击
注意:本录制数据中未捕获到稳定可复用的 HTTP 发消息接口,发送动作仍需在会话页通过输入框 + 发送按钮完成。
执行流程
Step 1: 导航并确认登录
- 导航到:
https://x.sankuai.com/ - snapshot 检查是否已登录
- 如出现 SSO/登录页,提示用户先扫码登录,再继续
Step 2: 确定目标类型
根据用户输入判断会话类型:
group:群聊chat:个人
可用参数:
- 群聊:
{GROUP_CHAT_ID}或{GROUP_NAME} - 个人:
{USER_UID}或{USER_MIS_OR_NAME}
Step 3A: 群聊定位
方式 A1(推荐):已知群聊 ID 直接进会话
直接导航:
https://x.sankuai.com/chat/{GROUP_CHAT_ID}?type=groupchat
方式 A2:按群名称搜索(API 优先)
先在页面内执行 fetch(浏览器自动带 Cookie):
await fetch("https://api.neixin.cn/search/api/v7/sug/fusion", {
method: "POST",
headers: { "Content-Type": "application/json;charset=UTF-8" },
credentials: "include",
body: JSON.stringify({
word: "{GROUP_NAME}",
limit: 20,
categories: ["group"],
scope: 0
})
});
从返回中选最匹配群,拿到群会话 ID 后导航到:
https://x.sankuai.com/chat/{GROUP_CHAT_ID}?type=groupchat
如果 API 结果结构不稳定,退化为 UI 搜索:
click+fill#navSearchInput(或.Auto_SearchInput)输入{GROUP_NAME}- 等待结果并
snapshot - 点击目标群条目进入
Step 3B: 个人会话定位
方式 B1(推荐):已知 UID 直接进会话
直接导航:
https://x.sankuai.com/chat/{USER_UID}?type=chat
方式 B2:按 MIS/姓名搜索(API 优先)
先调用搜索建议接口(录制中的关键请求):
POST https://api.neixin.cn/search/api/v7/sug/fusion- 示例请求体:
{
"word": "{USER_MIS_OR_NAME}",
"limit": 20,
"categories": ["user", "group", "pub", "pubgroup", "kefu"],
"scope": 0
}
建议在 evaluate 里做筛选:优先 user 类目,且 mis/name 精确匹配。
命中后拿到用户 UID,导航:
https://x.sankuai.com/chat/{USER_UID}?type=chat
可选校验(非必需):
POST https://api.neixin.cn/ems-neixin/v2/ems/getSimpleVcard- 请求体:
{"targetUids":["{USER_UID}"]} - 用于确认
mis/name与目标一致
如果 API 搜索失败,退化为 UI 搜索:
fill#navSearchInput输入{USER_MIS_OR_NAME}- 回车后
snapshot - 点击
user类型候选项进入单聊
Step 4: 确认已进入目标会话
snapshot 后满足任一条件即可:
- URL 为
.../chat/{ID}?type=groupchat(群)或.../chat/{ID}?type=chat(个人) - 页面顶部会话名称与目标一致
Step 5: 根据消息类型发送内容
5A: 发送文本消息
消息输入框使用:#textTextarea
操作顺序:
click #textTextareafill #textTextarea为{MESSAGE_CONTENT}- 点击发送按钮(见 Step 6)
说明:大象输入组件依赖输入事件,先聚焦再填充更稳。多行消息可包含 \n。
5B: 发送图片或文件
通过 upload action 向页面中隐藏的 <input type="file"> 注入文件即可触发上传。
操作步骤:
- 使用
uploadaction 上传文件(files必须为绝对路径):
{"action": "upload", "selector": "input[type='file']", "files": ["/absolute/path/to/file"]}
- 等待 1-2 秒,snapshot 验证文件已出现在输入区域
- 点击发送按钮(见 Step 6)
若页面有多个 input[type='file'],snapshot 后选择合适的一个。若 upload 失败,可先点击工具栏中的「文件」或「图片」按钮触发文件选择器,再对弹出的 input[type='file'] 执行 upload。
Step 6: 发送消息
优先按钮选择器:
div.ctn-send-msg-btn button.send-message-button
备选:
#textInput .send-message-buttonbutton.Auto_SendMsgBtn
Step 7: 验证发送成功
等待约 2 秒后 snapshot,检查:
- 文本消息:输入框
#textTextarea已清空,消息列表末尾出现我方新消息(.bubble-item.me) - 文件消息:消息列表末尾出现文件卡片,可通过
.wrapper-message-container .file-name确认文件名 - 图片消息:消息列表末尾出现我方发送的图片气泡
关键 API(来自录制)
说明:仅列出 XHR/Fetch 核心操作接口,忽略静态资源。
POST https://api.neixin.cn/search/api/v7/sug/fusion- 作用:按关键词搜索用户/群/公众号候选(定位入口)
POST https://api.neixin.cn/search/api/room/v1/search- 作用:会话/房间维度搜索补充
POST https://api.neixin.cn/ems-neixin/v2/ems/getSimpleVcard- 作用:按 UID 拉取用户基础信息(MIS、姓名)
POST https://api.neixin.cn/msg/api/chat/v3/history/channel/range- 作用:进入会话后拉历史消息(初始化校验)
用户参数
消息发送
{TARGET_TYPE}:group或chat{GROUP_CHAT_ID}: 群聊 ID(已知时){GROUP_NAME}: 群名称(未知 ID 时){USER_UID}: 用户 UID(已知时){USER_MIS_OR_NAME}: 用户 MIS 或姓名(未知 UID 时){MESSAGE_CONTENT}: 要发送的文本内容{FILE_PATH}: 要发送的文件绝对路径(可选,发送文件/图片时需要)
聊天记录归档
{CONTACT_NAME}: 联系人或群名称(用于搜索定位对话){CHAT_URL}: 对话 URL(已知时可直接导航){TIME_RANGE}: 时间范围(可选,限制导出的消息范围){ARCHIVE_JSON}: 已有归档 JSON 文件路径(仅分析时使用)
聊天记录导出与分析
通过浏览器自动化提取 x.sankuai.com 的聊天记录,保存到本地并可生成分析报告。
执行流程
Archive Step 1: 导出聊天记录
- 打开
https://x.sankuai.com,按上方 Step 1 的 SSO 登录流程检查并完成登录。 - 确认目标对话:
- 用户指定联系人/群名 → 使用上方 Step 3A/3B 的搜索流程进入对话
- 用户指定对话 URL → 直接 navigate 到该 URL
- 滚动加载历史消息:反复执行
scripts/scroll_load_all.js(通过evaluate),每次执行后wait2 秒,直到消息数量不再增长(连续 2 次相同)。若用户指定了时间范围,在最早消息时间满足要求后停止滚动。 - 执行
scripts/extract_messages.js(通过evaluate)提取所有消息,返回 JSON。 - 将 JSON 数据保存到工作区,文件名格式:
{对话名}_{日期}.json(如营销数据_20260302.json)。
Archive Step 2: 分析聊天记录
运行分析脚本生成 Markdown 报告:
python3 scripts/analyze_chat.py <归档文件.json> --output <报告.md>
报告包含:概览(对话类型、消息总数、参与人数、时间跨度)、消息类型分布、发言排行(群聊)、活跃时段分布、日期消息量、高频词。
若环境中安装了 jieba,高频词分析效果更佳。
Archive Step 3: 归档管理
归档文件建议存放在工作区的 daxiang-archives/ 目录下,按对话名或日期组织:
daxiang-archives/
├── 营销数据_20260302.json
├── 营销数据_20260302_report.md
├── 刘续续_20260301.json
└── ...
归档条件分支
用户只要求导出 → 执行 Archive Step 1,保存 JSON 后告知文件路径。
用户只要求分析 → 若已有归档 JSON 文件,直接执行 Archive Step 2;否则先执行 Archive Step 1。
用户要求导出+分析 → 依次执行 Archive Step 1 和 Archive Step 2。
用户指定时间范围 → 在 Archive Step 1 的滚动加载阶段,检查最早消息时间是否已覆盖目标范围;在 Archive Step 2 中提示分析脚本仅统计已加载的消息。
用户要求分析已有文件 → 跳过浏览器操作,直接对指定 JSON 文件运行 analyze_chat.py。
已验证页面锚点
| 元素 | 选择器 | 说明 |
|---|---|---|
| 搜索输入框 | #navSearchInput 或 .Auto_SearchInput |
顶部搜索栏 |
| 消息输入框 | #textTextarea |
会话内文本输入 |
| 发送按钮 | div.ctn-send-msg-btn button.send-message-button |
主发送按钮 |
| 发送按钮(备选) | #textInput .send-message-button / button.Auto_SendMsgBtn |
备选发送按钮 |
| 文件上传 | input[type='file'] |
隐藏文件上传控件 |
| 会话名称 | .wrapper-name[data-title] |
当前对话名称 |
| 群成员数 | .group-num |
群聊成员数量 |
| 个人 MIS | .bubble-personinfo-passport |
私聊对方的 MIS 号 |
| 消息列表容器 | .bubbleMessageListContainer |
滚动此容器加载历史消息 |
| 消息气泡 | .bubble-item |
每条消息的根元素 |
| 自己的消息 | .bubble-item.me |
通过 class 判断是否为自己发送 |
| 发送者名称 | .talker-name |
消息发送者姓名 |
| 消息时间 | .bubble-item-time |
消息时间戳 |
| 文字内容 | .dx-message-text |
文字消息内容 |
| 消息类型 | .message-inner.message-{type} |
type 可为 text/image/file/card/voice/video/sticker |
| 消息 ID | .bubble-item[data-mid] |
消息唯一标识 |
| 文件名 | .wrapper-message-container .file-name |
文件消息中的文件名 |
注意事项
- 不要在 Skill 中硬编码 Cookie 或任何认证信息;浏览器会自动携带登录态
- 搜索 API 请求建议都在
evaluate中执行fetch(..., { credentials: "include" }) - 本录制中发送事件体现为 SDK 上报(如
message_send_start/message_send_success)与埋点,不是稳定 HTTP 发送接口 - 当 API 返回结构与预期不一致时,立即降级到 UI 搜索,保证可用性
- 若页面未登录或会话无权限,应先提示用户处理权限/登录,再重试
- 上传文件路径必须为绝对路径,相对路径可能导致 upload 找不到文件
- 导出聊天记录时,
scripts/下的 JS 脚本通过evaluate在页面中执行,Python 分析脚本在本地终端执行 - 分析脚本依赖 Python3;若安装了
jieba则高频词分析效果更佳(非必需)
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.