微信朋友圈每日总结

SKILL生活服务
生活服务 未标注权限 许可证不明确
安装这个技能

每天定时提醒用户上传微信朋友圈截图,AI 自动识别截图内容并生成结构化总结(热门话题、精彩内容、情感分析、互动亮点等),支持通过 Server酱、PushPlus、企业微信机器人推送总结到微信。触发词包括朋友圈总结、每日朋友圈、朋友圈日报、总结朋友圈、微信朋友圈总结、朋友圈每日总结、moments summary。

一句话选型结论

按资料字段整理

微信朋友圈每日总结是生活服务类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类生活服务 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_9355e276/wechat-moments-daily-summary
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

生活服务
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_9355e276仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 1791677808
正文体量35.1 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
行程与攻略

按目的地和天数排行程。

日常信息查询

查天气、交通、办事信息。

生活事务整理

把琐事整理成清单逐项处理。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在生活服务场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
微信朋友圈每日总结当前 未标注权限 未标注 未标注 未标注 有
食谱批量下载文件夹 联网访问 GitHub 仓库 28.5 万 Codex、Claude、Cursor 有
食谱创建演示文稿 未标注权限 GitHub 仓库 28.0 万 Codex、Claude、Cursor 有
recipe 备份 sheet AS CSV 联网访问 GitHub 仓库 27.9 万 Codex、Claude、Cursor 有
recipe create Gmail filter 邮件管理 未标注权限 GitHub 仓库 27.8 万 Codex、Claude、Cursor 有
配方观察驱动器变化 联网访问 GitHub 仓库 27.4 万 Codex、Claude、Cursor 有

SKILL.md 全文

35.1 KB
模型实际读到的说明书原文,来自技能仓库

微信朋友圈每日总结

概述

每天定时提醒用户上传微信朋友圈截图,AI 利用多模态视觉能力自动识别截图中的文字、图片和互动信息,生成结构化的朋友圈日报。总结内容涵盖热门话题、精彩内容、情感分析、互动亮点等维度,支持通过微信推送通道(Server酱 / PushPlus / 企业微信机器人)将总结发送到用户的微信。

触发词

  • 朋友圈总结
  • 每日朋友圈
  • 朋友圈日报
  • 总结朋友圈
  • 微信朋友圈总结
  • 朋友圈每日总结
  • 修改朋友圈总结
  • 查看朋友圈总结
  • 删除朋友圈总结
  • moments summary

工作流程

阶段一:配置收集(弹窗交互)

当用户触发本技能时,首先检查是否已有配置(读取 ~/.workbuddy/skills/微信朋友圈每日总结/config.json),并根据状态弹出配置窗口:

无配置 → 弹出空白配置窗口(显示「保存并创建定时任务 ↗」按钮)
有配置 → 弹出已填充的配置窗口(显示「更新定时任务 ↗」和「删除定时任务」按钮)

配置窗口收集以下信息:

  1. 推送通道(单选,可选):
    - Server酱 Turbo(推荐,免费每日5条,需在 https://sct.ftqq.com/ 注册获取 SendKey)
    - PushPlus(免费每日200条,需在 http://www.pushplus.plus/ 注册获取 Token)
    - 企业微信机器人 Webhook(需企业微信管理员权限)
    - 不推送,仅在对话中查看总结

  2. API Key / Token:对应推送通道的密钥(选择"不推送"时隐藏)

  3. 总结时间:每天几点提醒上传截图(如 21:00,默认晚上朋友圈内容最丰富时)

  4. 提醒模式(单选):
    - 每日提醒(固定每天同一时间)
    - 仅工作日(周一至周五)
    - 单次提醒(指定某一天)

  5. 总结风格(单选):
    - 简洁版(3-5 条要点,适合快速浏览)
    - 标准版(包含话题、精彩内容、情感分析,适中篇幅)
    - 详细版(全面深度分析,含每条动态详情)

  6. 总结内容(多选复选框):
    - 热门话题(关键词聚类)
    - 精彩内容(有趣/有价值的动态摘录)
    - 情感分析(整体情绪走向:积极/消极/中性)
    - 互动亮点(点赞数高的、评论热烈的)
    - 分类统计(工作/生活/美食/旅行/育儿等分类占比)
    - 图片视频亮点(描述有特色的图片或视频内容)
    - 好友动态榜(发朋友圈最活跃的好友 Top3)

  7. 自定义消息前缀(可选):在总结内容前附加的文字,如"今日朋友圈日报:"


阶段二:配置验证与保存

  1. 用户在弹窗中填写完成后点击「保存并创建定时任务 ↗」
  2. AI 收到配置数据后:
    - 验证推送通道连通性(发送一条测试消息到微信,若选择"不推送"则跳过)
    - 将配置保存到 ~/.workbuddy/skills/微信朋友圈每日总结/config.json
    - 创建定时任务(automation)

阶段三:创建定时任务

使用 automation_update 工具创建定时任务:

  • name: 朋友圈每日总结
  • scheduleType: recurring(每日/工作日)或 once(单次)
  • rrule: 根据用户选择的模式和总结时间生成 RRULE
  • 每日:FREQ=DAILY;BYHOUR={时};BYMINUTE={分}
  • 仅工作日:FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;BYHOUR={时};BYMINUTE={分}
  • prompt: 执行朋友圈总结的指令(见下方自动化执行指令)
  • cwds: 当前工作目录

阶段四:每日执行流程

定时任务触发后,AI 执行以下步骤:

  1. 提醒上传截图:向用户发送消息,提醒上传今日的朋友圈截图
    - 告知用户:打开微信 → 发现 → 朋友圈 → 截图(可多张)→ 通过聊天附件上传
    - 说明:截图应覆盖今日所有可见的朋友圈内容

  2. 等待用户上传:用户通过聊天附件上传截图(一张或多张)

  3. 识别截图内容:逐张读取截图,利用多模态视觉能力识别:
    - 发布者昵称
    - 发布时间
    - 文字内容
    - 图片/视频描述
    - 点赞数、评论数、评论内容
    - 定位信息
    - 分享链接标题

  4. 生成结构化总结:根据配置的总结风格和内容选项,生成总结报告

  5. 推送总结:
    - 在对话中展示完整总结
    - 若配置了推送通道,将总结通过 Server酱/PushPlus/企业微信推送到微信


总结报告格式模板

简洁版

## 朋友圈日报 — {日期}

### 今日要点
1. {要点1}
2. {要点2}
3. {要点3}

### 热门话题
{话题1}、{话题2}、{话题3}

---
共 {N} 位好友发了 {M} 条动态 | 由微信朋友圈每日总结自动生成

标准版

## 朋友圈日报 — {日期} {星期}

{自定义前缀}

### 今日概览
共 {N} 位好友发布了 {M} 条动态

### 热门话题
1. {话题1}:{简述}
2. {话题2}:{简述}
3. {话题3}:{简述}

### 精彩内容
- **{好友名}**:{动态摘录}
- **{好友名}**:{动态摘录}
- **{好友名}**:{动态摘录}

### 情感分析
今日朋友圈整体氛围:{积极/平淡/消极}
{情感分析说明}

### 互动亮点
- 最高点赞:{好友名} 的 {内容摘要}({N} 个赞)
- 最热评论:{好友名} 的 {内容摘要}({N} 条评论)

---
{自定义后缀或页脚}

详细版

## 朋友圈日报 — {日期} {星期}

{自定义前缀}

### 今日数据概览
- 发布动态的好友数:{N}
- 动态总数:{M}
- 含图片动态:{X} 条
- 含视频动态:{Y} 条
- 纯文字动态:{Z} 条
- 总点赞数:{P}
- 总评论数:{Q}

### 热门话题排行
1. {话题1}({N}人提及):{话题简述与代表性动态}
2. {话题2}({N}人提及):{话题简述与代表性动态}
3. {话题3}({N}人提及):{话题简述与代表性动态}
4. {话题4}({N}人提及):{话题简述与代表性动态}
5. {话题5}({N}人提及):{话题简述与代表性动态}

### 精彩内容精选
#### {好友名1} — {时间}
> {动态文字内容}
{图片/视频描述}
点赞 {N} | 评论 {M}

#### {好友名2} — {时间}
> {动态文字内容}
{图片/视频描述}
点赞 {N} | 评论 {M}

#### {好友名3} — {时间}
> {动态文字内容}
{图片/视频描述}
点赞 {N} | 评论 {M}

### 情感分析
- 整体情绪:{积极/平淡/消极/混合}
- 情绪分布:积极 {X}% | 中性 {Y}% | 消极 {Z}%
- 情绪分析:{对今日朋友圈整体情绪的解读}

### 互动亮点
- 最高点赞动态:{好友名} — {内容摘要}({N} 个赞)
- 最多评论动态:{好友名} — {内容摘要}({M} 条评论)
- 精彩评论互动:{好友A} 与 {好友B} 在 {好友C} 的动态下互动

### 分类统计
| 分类 | 动态数 | 占比 |
|------|--------|------|
| 生活日常 | {N} | {X}% |
| 美食 | {N} | {X}% |
| 工作 | {N} | {X}% |
| 旅行 | {N} | {X}% |
| 育儿 | {N} | {X}% |
| 其他 | {N} | {X}% |

### 图片视频亮点
- {好友名}:{图片/视频描述}
- {好友名}:{图片/视频描述}

### 好友动态榜
1. {好友名}:{N} 条动态
2. {好友名}:{N} 条动态
3. {好友名}:{N} 条动态

---
由微信朋友圈每日总结自动生成 · {时间}

配置弹窗

当技能触发时,使用 show_widget 展示以下交互式配置弹窗:

<div style="font-family:'Segoe UI','Microsoft YaHei',sans-serif;max-width:680px;margin:0 auto;padding:24px;background:#f8fafc;border-radius:12px;box-sizing:border-box;">
  <h2 style="margin:0 0 4px 0;color:#1a1a2e;font-size:22px;">朋友圈每日总结 — 配置</h2>
  <p style="margin:0 0 20px 0;color:#666;font-size:13px;">设置总结推送通道、时间、风格和内容偏好</p>

  <!-- ===== 推送通道 ===== -->
  <div style="background:#fff;border-radius:10px;padding:16px;margin-bottom:14px;box-shadow:0 1px 3px rgba(0,0,0,0.06);">
    <label style="display:block;font-weight:700;color:#333;font-size:14px;margin-bottom:10px;">推送通道</label>
    <div id="channelRadios" style="display:flex;flex-wrap:wrap;gap:8px;">
      <label style="display:flex;align-items:center;gap:6px;padding:8px 14px;border:2px solid #0078d4;border-radius:8px;background:#e8f4fd;cursor:pointer;font-size:13px;font-weight:600;color:#0078d4;transition:all 0.2s;">
        <input type="radio" name="channel" value="serverchan" checked onchange="switchChannel(this.value)" style="accent-color:#0078d4;"/>
        Server酱(推荐)
      </label>
      <label style="display:flex;align-items:center;gap:6px;padding:8px 14px;border:2px solid #ddd;border-radius:8px;background:#fff;cursor:pointer;font-size:13px;transition:all 0.2s;">
        <input type="radio" name="channel" value="pushplus" onchange="switchChannel(this.value)" style="accent-color:#0078d4;"/>
        PushPlus
      </label>
      <label style="display:flex;align-items:center;gap:6px;padding:8px 14px;border:2px solid #ddd;border-radius:8px;background:#fff;cursor:pointer;font-size:13px;transition:all 0.2s;">
        <input type="radio" name="channel" value="wecom" onchange="switchChannel(this.value)" style="accent-color:#0078d4;"/>
        企业微信机器人
      </label>
      <label style="display:flex;align-items:center;gap:6px;padding:8px 14px;border:2px solid #ddd;border-radius:8px;background:#fff;cursor:pointer;font-size:13px;transition:all 0.2s;">
        <input type="radio" name="channel" value="none" onchange="switchChannel(this.value)" style="accent-color:#0078d4;"/>
        不推送
      </label>
    </div>
    <div id="channelHint" style="margin-top:8px;font-size:12px;color:#888;line-height:1.6;">
      Server酱:微信扫码注册 → <a href="https://sct.ftqq.com/" target="_blank" style="color:#0078d4;">sct.ftqq.com</a> 获取 SendKey
    </div>
  </div>

  <!-- ===== API密钥 ===== -->
  <div id="apiKeySection" style="background:#fff;border-radius:10px;padding:16px;margin-bottom:14px;box-shadow:0 1px 3px rgba(0,0,0,0.06);">
    <label style="display:block;font-weight:700;color:#333;font-size:14px;margin-bottom:4px;"><span id="keyLabel">SendKey</span></label>
    <p style="margin:0 0 8px 0;font-size:12px;color:#999;">在对应平台注册后获取,用于微信消息推送</p>
    <input id="apiKey" type="password" placeholder="请输入 SendKey" style="width:100%;padding:10px 14px;border:1.5px solid #ddd;border-radius:8px;font-size:14px;box-sizing:border-box;transition:border-color 0.2s;" onfocus="this.style.borderColor='#0078d4'" onblur="this.style.borderColor='#ddd'"/>
    <button id="testBtn" onclick="testChannel()" style="margin-top:8px;padding:6px 18px;border:1px solid #0078d4;border-radius:6px;background:#fff;color:#0078d4;cursor:pointer;font-size:12px;font-weight:600;">发送测试消息</button>
    <span id="testResult" style="margin-left:8px;font-size:12px;"></span>
  </div>

  <!-- ===== 总结时间 ===== -->
  <div style="background:#fff;border-radius:10px;padding:16px;margin-bottom:14px;box-shadow:0 1px 3px rgba(0,0,0,0.06);">
    <label style="display:block;font-weight:700;color:#333;font-size:14px;margin-bottom:10px;">总结时间 & 频率</label>
    <div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;">
      <input id="remindTime" type="time" value="21:00" style="padding:8px 12px;border:1.5px solid #ddd;border-radius:8px;font-size:14px;width:130px;"/>
      <select id="remindMode" style="padding:8px 12px;border:1.5px solid #ddd;border-radius:8px;font-size:14px;min-width:140px;">
        <option value="daily">每日提醒</option>
        <option value="weekday">仅工作日 (周一~周五)</option>
        <option value="once">单次提醒</option>
      </select>
      <input id="onceDate" type="date" style="padding:8px 12px;border:1.5px solid #ddd;border-radius:8px;font-size:14px;width:150px;display:none;"/>
    </div>
    <p style="margin:8px 0 0 0;font-size:12px;color:#999;">建议设置在晚上 20:00-22:00,此时朋友圈内容最丰富</p>
  </div>

  <!-- ===== 总结风格 ===== -->
  <div style="background:#fff;border-radius:10px;padding:16px;margin-bottom:14px;box-shadow:0 1px 3px rgba(0,0,0,0.06);">
    <label style="display:block;font-weight:700;color:#333;font-size:14px;margin-bottom:10px;">总结风格</label>
    <div style="display:flex;gap:8px;flex-wrap:wrap;">
      <label style="display:flex;align-items:center;gap:6px;padding:8px 14px;border:2px solid #ddd;border-radius:8px;background:#fff;cursor:pointer;font-size:13px;transition:all 0.2s;" id="label_brief">
        <input type="radio" name="style" value="brief" onchange="updateStyle(this.value)" style="accent-color:#0078d4;"/>
        简洁版
      </label>
      <label style="display:flex;align-items:center;gap:6px;padding:8px 14px;border:2px solid #0078d4;border-radius:8px;background:#e8f4fd;cursor:pointer;font-size:13px;font-weight:600;color:#0078d4;transition:all 0.2s;" id="label_standard">
        <input type="radio" name="style" value="standard" checked onchange="updateStyle(this.value)" style="accent-color:#0078d4;"/>
        标准版(推荐)
      </label>
      <label style="display:flex;align-items:center;gap:6px;padding:8px 14px;border:2px solid #ddd;border-radius:8px;background:#fff;cursor:pointer;font-size:13px;transition:all 0.2s;" id="label_detailed">
        <input type="radio" name="style" value="detailed" onchange="updateStyle(this.value)" style="accent-color:#0078d4;"/>
        详细版
      </label>
    </div>
  </div>

  <!-- ===== 总结内容 ===== -->
  <div style="background:#fff;border-radius:10px;padding:16px;margin-bottom:14px;box-shadow:0 1px 3px rgba(0,0,0,0.06);">
    <label style="display:block;font-weight:700;color:#333;font-size:14px;margin-bottom:10px;">总结内容(可多选)</label>
    <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;">
      <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;padding:6px 8px;border-radius:6px;">
        <input type="checkbox" class="summaryContent" value="topics" checked style="accent-color:#0078d4;"/> 热门话题
      </label>
      <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;padding:6px 8px;border-radius:6px;">
        <input type="checkbox" class="summaryContent" value="highlights" checked style="accent-color:#0078d4;"/> 精彩内容
      </label>
      <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;padding:6px 8px;border-radius:6px;">
        <input type="checkbox" class="summaryContent" value="sentiment" checked style="accent-color:#0078d4;"/> 情感分析
      </label>
      <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;padding:6px 8px;border-radius:6px;">
        <input type="checkbox" class="summaryContent" value="interactions" checked style="accent-color:#0078d4;"/> 互动亮点
      </label>
      <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;padding:6px 8px;border-radius:6px;">
        <input type="checkbox" class="summaryContent" value="categories" style="accent-color:#0078d4;"/> 分类统计
      </label>
      <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;padding:6px 8px;border-radius:6px;">
        <input type="checkbox" class="summaryContent" value="media" style="accent-color:#0078d4;"/> 图片视频亮点
      </label>
      <label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;padding:6px 8px;border-radius:6px;grid-column:1/-1;">
        <input type="checkbox" class="summaryContent" value="topPosters" style="accent-color:#0078d4;"/> 好友动态榜 Top3
      </label>
    </div>
  </div>

  <!-- ===== 自定义前缀 ===== -->
  <div style="background:#fff;border-radius:10px;padding:16px;margin-bottom:18px;box-shadow:0 1px 3px rgba(0,0,0,0.06);">
    <label style="display:block;font-weight:700;color:#333;font-size:14px;margin-bottom:4px;">自定义消息前缀(可选)</label>
    <p style="margin:0 0 8px 0;font-size:12px;color:#999;">在总结内容前附加的问候语或备注</p>
    <input id="prefix" type="text" placeholder="例如:今日朋友圈日报:" style="width:100%;padding:10px 14px;border:1.5px solid #ddd;border-radius:8px;font-size:14px;box-sizing:border-box;"/>
  </div>

  <!-- ===== 操作按钮 ===== -->
  <div style="display:flex;gap:12px;align-items:center;">
    <button id="saveBtn" onclick="saveAndSchedule()" style="flex:1;padding:12px 24px;border:none;border-radius:8px;background:linear-gradient(135deg,#0078d4,#005a9e);color:#fff;cursor:pointer;font-size:15px;font-weight:700;transition:all 0.2s;box-shadow:0 2px 8px rgba(0,120,212,0.3);">保存并创建定时任务 ↗</button>
    <button id="updateBtn" onclick="updateSchedule()" style="display:none;flex:1;padding:12px 24px;border:none;border-radius:8px;background:linear-gradient(135deg,#00a854,#008040);color:#fff;cursor:pointer;font-size:15px;font-weight:700;transition:all 0.2s;box-shadow:0 2px 8px rgba(0,168,84,0.3);">更新定时任务 ↗</button>
    <button id="deleteBtn" onclick="deleteSchedule()" style="display:none;padding:12px 24px;border:1.5px solid #e74c3c;border-radius:8px;background:#fff;color:#e74c3c;cursor:pointer;font-size:15px;font-weight:600;transition:all 0.2s;">删除定时任务</button>
  </div>
  <div id="statusMsg" style="margin-top:12px;font-size:13px;text-align:center;"></div>
</div>

<script>
// ===== 初始化:尝试加载已有配置 =====
let existingConfig = null;
try {
  const stored = window._config_hint || null;
  if (stored) {
    existingConfig = JSON.parse(stored);
    loadExistingConfig();
  }
} catch(e) {}

function loadExistingConfig() {
  if (!existingConfig) return;
  if (existingConfig.channel) {
    document.querySelector('input[name="channel"][value="'+existingConfig.channel+'"]').checked = true;
    switchChannel(existingConfig.channel);
  }
  if (existingConfig.apiKey) document.getElementById('apiKey').value = existingConfig.apiKey;
  if (existingConfig.remindTime) document.getElementById('remindTime').value = existingConfig.remindTime;
  if (existingConfig.remindMode) {
    document.getElementById('remindMode').value = existingConfig.remindMode;
    if (existingConfig.remindMode === 'once') {
      document.getElementById('onceDate').style.display = '';
      if (existingConfig.onceDate) document.getElementById('onceDate').value = existingConfig.onceDate;
    }
  }
  if (existingConfig.style) {
    document.querySelector('input[name="style"][value="'+existingConfig.style+'"]').checked = true;
    updateStyle(existingConfig.style);
  }
  if (existingConfig.contents) {
    document.querySelectorAll('.summaryContent').forEach(cb => {
      cb.checked = existingConfig.contents.includes(cb.value);
    });
  }
  if (existingConfig.prefix) document.getElementById('prefix').value = existingConfig.prefix;
  document.getElementById('saveBtn').style.display = 'none';
  document.getElementById('updateBtn').style.display = '';
  document.getElementById('deleteBtn').style.display = '';
}

// ===== 切换推送通道 =====
function switchChannel(channel) {
  const labels = document.querySelectorAll('#channelRadios label');
  labels.forEach(l => {
    const radio = l.querySelector('input');
    if (radio && radio.value === channel) {
      l.style.borderColor = '#0078d4';
      l.style.background = '#e8f4fd';
      l.style.color = '#0078d4';
      l.style.fontWeight = '600';
    } else {
      l.style.borderColor = '#ddd';
      l.style.background = '#fff';
      l.style.color = '#555';
      l.style.fontWeight = '400';
    }
  });

  const keySection = document.getElementById('apiKeySection');
  const keyLabel = document.getElementById('keyLabel');
  const keyInput = document.getElementById('apiKey');
  const hint = document.getElementById('channelHint');

  if (channel === 'none') {
    keySection.style.display = 'none';
    hint.innerHTML = '总结将在对话中直接展示,不推送到微信';
  } else {
    keySection.style.display = '';
    if (channel === 'serverchan') {
      keyLabel.textContent = 'SendKey';
      keyInput.placeholder = '请输入 SendKey(如 SCT123456xxxxx)';
      hint.innerHTML = 'Server酱:微信扫码注册 → <a href="https://sct.ftqq.com/" target="_blank" style="color:#0078d4;">sct.ftqq.com</a> 获取 SendKey';
    } else if (channel === 'pushplus') {
      keyLabel.textContent = 'Token';
      keyInput.placeholder = '请输入 Token(如 a1b2c3d4e5f6)';
      hint.innerHTML = 'PushPlus:微信扫码注册 → <a href="http://www.pushplus.plus/" target="_blank" style="color:#0078d4;">pushplus.plus</a> 获取 Token';
    } else if (channel === 'wecom') {
      keyLabel.textContent = 'Webhook URL';
      keyInput.placeholder = '请输入 Webhook 地址';
      hint.innerHTML = '企业微信机器人:群聊中添加机器人 → 复制 Webhook 地址';
    }
  }
  document.getElementById('testResult').textContent = '';
}

// ===== 更新总结风格样式 =====
function updateStyle(style) {
  ['brief', 'standard', 'detailed'].forEach(s => {
    const label = document.getElementById('label_' + s);
    if (s === style) {
      label.style.borderColor = '#0078d4';
      label.style.background = '#e8f4fd';
      label.style.color = '#0078d4';
      label.style.fontWeight = '600';
    } else {
      label.style.borderColor = '#ddd';
      label.style.background = '#fff';
      label.style.color = '#555';
      label.style.fontWeight = '400';
    }
  });
}

// ===== 提醒模式切换 =====
document.getElementById('remindMode').addEventListener('change', function() {
  document.getElementById('onceDate').style.display = this.value === 'once' ? '' : 'none';
});

// ===== 收集配置数据 =====
function collectConfig() {
  const channel = document.querySelector('input[name="channel"]:checked')?.value || 'serverchan';
  const apiKey = document.getElementById('apiKey').value.trim();
  const remindTime = document.getElementById('remindTime').value;
  const remindMode = document.getElementById('remindMode').value;
  const onceDate = document.getElementById('onceDate').value;
  const style = document.querySelector('input[name="style"]:checked')?.value || 'standard';

  const contents = [];
  document.querySelectorAll('.summaryContent:checked').forEach(cb => contents.push(cb.value));

  const prefix = document.getElementById('prefix').value.trim();

  // 验证
  if (channel !== 'none' && !apiKey) { showStatus('请输入推送通道的密钥', 'error'); return null; }
  if (!remindTime) { showStatus('请选择总结时间', 'error'); return null; }
  if (remindMode === 'once' && !onceDate) { showStatus('单次提醒请选择日期', 'error'); return null; }

  return {
    channel, apiKey, remindTime, remindMode, onceDate, style, contents, prefix,
    isUpdate: !!existingConfig
  };
}

// ===== 测试推送通道 =====
function testChannel() {
  const config = collectConfig();
  if (!config) return;
  const btn = document.getElementById('testBtn');
  const resultEl = document.getElementById('testResult');
  btn.disabled = true;
  btn.textContent = '发送中...';
  resultEl.textContent = '';
  resultEl.style.color = '#888';
  sendPrompt('__MOMENTS_TEST__' + JSON.stringify(config));
}

// ===== 保存并创建定时任务 =====
function saveAndSchedule() {
  const config = collectConfig();
  if (!config) return;
  config.isUpdate = false;
  sendPrompt('__MOMENTS_SAVE__' + JSON.stringify(config));
}

// ===== 更新定时任务 =====
function updateSchedule() {
  const config = collectConfig();
  if (!config) return;
  config.isUpdate = true;
  sendPrompt('__MOMENTS_SAVE__' + JSON.stringify(config));
}

// ===== 删除定时任务 =====
function deleteSchedule() {
  if (confirm('确定要删除此朋友圈总结定时任务吗?此操作不可恢复。')) {
    sendPrompt('__MOMENTS_DELETE__' + JSON.stringify(existingConfig || {}));
  }
}

// ===== 显示状态消息 =====
function showStatus(msg, type) {
  const el = document.getElementById('statusMsg');
  el.textContent = msg;
  el.style.color = type === 'error' ? '#e74c3c' : (type === 'success' ? '#27ae60' : '#333');
}

window._setStatus = function(msg, type) { showStatus(msg, type); };
window._setTestResult = function(msg, success) {
  const el = document.getElementById('testResult');
  el.textContent = msg;
  el.style.color = success ? '#27ae60' : '#e74c3c';
  const btn = document.getElementById('testBtn');
  btn.disabled = false;
  btn.textContent = '发送测试消息';
};
</script>

AI 执行指令

入口判断

当技能被触发时,AI 按以下顺序判断当前状态:

  1. 检查是否已有配置:读取 ~/.workbuddy/skills/微信朋友圈每日总结/config.json
  2. 检查是否已有 automation:使用 automation_update mode="list" 查找名为"朋友圈每日总结"的任务
  3. 根据状态决定行为:
    - 无配置 + 无任务 → 弹出空白配置窗口
    - 有配置 + 有任务 → 弹出已填充的配置窗口(显示更新/删除按钮)
    - 用户说"查看"/"状态" → 直接显示当前配置和任务状态
    - 用户说"删除"/"取消" → 删除配置和 automation
    - 用户直接上传了朋友圈截图 → 跳转到阶段四的识别总结流程

配置保存流程(收到 __MOMENTS_SAVE__ 消息后)

  1. 解析配置JSON

  2. 发送测试消息(若 channel 不为 "none"):
    - 向对应推送通道发送一条测试消息
    - 标题:「朋友圈每日总结 — 测试消息」
    - 内容:「这是一条测试消息,用于验证推送通道是否正常工作。如果您收到此消息,说明配置正确!」

  3. 保存配置文件:
    json { "channel": "serverchan", "apiKey": "SCT123456xxxxx", "remindTime": "21:00", "remindMode": "daily", "style": "standard", "contents": ["topics", "highlights", "sentiment", "interactions"], "prefix": "今日朋友圈日报:", "createdAt": "2026-07-28T21:00:00", "updatedAt": "2026-07-28T21:00:00" }
    写入 ~/.workbuddy/skills/微信朋友圈每日总结/config.json

  4. 创建/更新 automation:
    - 根据 remindMode 和 remindTime 生成 RRULE
    - 每日提醒:FREQ=DAILY;BYHOUR={HH};BYMINUTE={MM}
    - 仅工作日:FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR;BYHOUR={HH};BYMINUTE={MM}
    - 单次提醒:使用 scheduleType="once" + scheduledAt="YYYY-MM-DDTHH:MM+08:00"
    - name: 朋友圈每日总结
    - prompt:自动化执行指令(见下方)

  5. 通知用户:告知配置已保存,定时任务已创建,下次执行时间

自动化执行指令(automation prompt)

写入 automation 的 prompt 应为以下内容(完整自包含):

你是一个朋友圈每日总结任务。请执行以下步骤:

1. 读取配置文件 ~/.workbuddy/skills/微信朋友圈每日总结/config.json,获取总结风格、内容选项和推送通道配置。

2. 向用户发送消息提醒上传今日朋友圈截图:
   "您好!现在是每日朋友圈总结时间。请打开微信 → 发现 → 朋友圈,截图今日的朋友圈内容并上传。
   截图要求:
   - 尽量覆盖今日所有可见的朋友圈动态
   - 可以上传多张截图(滚动截图或分屏截图)
   - 截图需清晰,文字可辨认
   上传方式:通过聊天框左侧的附件按钮 📎 上传图片"

3. 等待用户上传截图。用户可能上传一张或多张图片。

4. 逐张读取截图,利用多模态视觉能力识别每张截图中的:
   - 发布者昵称
   - 发布时间
   - 文字内容
   - 图片或视频的描述
   - 点赞数
   - 评论数和评论内容
   - 定位信息
   - 分享链接标题

5. 汇总所有截图识别结果,根据配置中的 style(brief/standard/detailed)和 contents 选项,生成结构化总结报告。

6. 总结报告格式参考 SKILL.md 中的模板。

7. 在对话中展示完整总结。

8. 若配置了推送通道(channel 不为 "none"),将总结通过对应推送通道发送到微信:
   - serverchan: POST https://sctapi.ftqq.com/{apiKey}.send 带 title 和 desp 参数
   - pushplus: POST http://www.pushplus.plus/send 带 token, title, content, template 参数
   - wecom: POST {webhook_url} 带 msgtype:markdown 和 markdown.content

9. 消息标题格式:"朋友圈日报 — {日期}"

10. 完成后简要告知用户总结已生成并推送。

测试消息流程(收到 __MOMENTS_TEST__ 消息后)

  1. 解析配置
  2. 向对应推送通道发送一条测试消息:
    - 标题:「朋友圈每日总结 — 测试消息」
    - 内容:「这是一条测试消息,用于验证推送通道是否正常工作。\n\n如果收到此消息,说明配置正确!\n\n推送通道:{channel}\n总结时间:{remindTime}\n总结风格:{style}」
  3. 通过 show_widget 的 _setTestResult 回调通知用户测试结果

删除任务流程(收到 __MOMENTS_DELETE__ 消息后)

  1. 使用 automation_update mode="list" 查找"朋友圈每日总结"相关任务
  2. 使用 automation_update mode="delete" 删除找到的 automation
  3. 删除 ~/.workbuddy/skills/微信朋友圈每日总结/config.json
  4. 通知用户已删除

手动总结流程(用户直接上传截图时)

当用户未配置定时任务但直接上传了朋友圈截图并要求总结时:

  1. 读取截图(逐张读取,利用多模态视觉能力)
  2. 识别截图中的朋友圈内容
  3. 使用默认的"标准版"风格生成总结
  4. 在对话中展示总结
  5. 询问用户是否需要配置每日定时总结

微信消息发送

通道1:Server酱 Turbo(推荐默认)

import urllib.request
import urllib.parse

def send_via_serverchan(sendkey, title, content):
    url = f"https://sctapi.ftqq.com/{sendkey}.send"
    data = urllib.parse.urlencode({"title": title, "desp": content}).encode("utf-8")
    req = urllib.request.Request(url, data=data, method="POST")
    with urllib.request.urlopen(req) as resp:
        return resp.read().decode("utf-8")

注册地址:https://sct.ftqq.com/ (微信扫码登录 → 获取 SendKey)

通道2:PushPlus

import urllib.request
import json

def send_via_pushplus(token, title, content):
    url = "http://www.pushplus.plus/send"
    data = json.dumps({"token": token, "title": title, "content": content, "template": "markdown"}).encode("utf-8")
    req = urllib.request.Request(url, data=data, method="POST",
                                  headers={"Content-Type": "application/json"})
    with urllib.request.urlopen(req) as resp:
        return resp.read().decode("utf-8")

注册地址:http://www.pushplus.plus/ (微信扫码登录 → 获取 Token)

通道3:企业微信机器人 Webhook

import urllib.request
import json

def send_via_wecom_webhook(webhook_url, content):
    data = json.dumps({"msgtype": "markdown", "markdown": {"content": content}}).encode("utf-8")
    req = urllib.request.Request(webhook_url, data=data, method="POST",
                                  headers={"Content-Type": "application/json"})
    with urllib.request.urlopen(req) as resp:
        return resp.read().decode("utf-8")

依赖说明

组件 服务 费用
截图识别 WorkBuddy 多模态视觉能力 内置功能
微信推送 Server酱 Turbo 免费每日5条
微信推送 PushPlus 免费每日200条
微信推送 企业微信机器人 免费(需企业微信)
定时调度 WorkBuddy automation 内置功能

注意事项

  1. 截图质量:截图需清晰,文字可辨认。模糊或过小的截图可能影响识别效果
  2. 截图覆盖:建议尽量覆盖今日所有可见的朋友圈内容,多张截图可拼接完整内容
  3. 隐私保护:总结内容仅在本地处理和用户指定的推送通道传输,不会上传到其他第三方服务
  4. 首次使用:若选择推送到微信,需先在 Server酱/PushPlus 注册并获取密钥(微信扫码即可)
  5. 网络要求:需能访问外网(推送服务 API)
  6. API限制:推送服务有每日条数上限
  7. 修改配置:重新触发技能即可进入编辑模式
  8. 总结质量:AI 识别截图内容后生成的总结基于视觉理解,可能与实际内容有细微差异

快速排查

问题 可能原因 解决方法
未收到微信推送 SendKey/Token 错误 检查并重新输入密钥
截图识别不全 截图不完整或模糊 重新截图,确保覆盖全部内容
定时未触发 automation 被暂停 检查 automation 状态
推送格式混乱 Markdown 不兼容 PushPlus 尝试切换 template 为 "html"
总结内容为空 截图中无朋友圈内容 确认截图来源正确

支付宝付费改造契约(PAYSKILL)

本技能为付费技能(PAYSKILL)。调用遵循支付宝 AI 生意画像契约,由平台调度层执行 probe → pay → complete → ack 流程:

  1. probe(探测):平台调用前先探测是否已持有本技能的支付宝有效订阅 / 付费凭证。已付费则直接放行。
  2. 402 Payment-Needed:未付费时,脚本向标准输出返回 HTTP 状态 402 与 Payment-Needed 标记,提示用户通过支付宝完成付费(pay),平台据此唤起付费页。
  3. complete(扣费确认):用户在支付宝完成扣费后,平台下发 Payment-Proof(付费凭证)。
  4. ack(验签放行):平台携带 Payment-Proof 重试本次调用;scripts/payment_gate.py 验签该凭证,确认有效后放行主流程。

订阅持久化与幂等:

  • 付费状态缓存在本地 .pay_cache/state.json,避免每次调用重复付费(订阅持久化)。
  • 同一 Payment-Proof 在 24h 幂等窗口内仅生效一次,避免重复扣费。

现金流改造后的调用套路:

用户调用 → 平台 probe  →
   未付费:下发 402 Payment-Needed → 支付宝 pay → complete → 下发 Payment-Proof
已付费/携带 Proof:脚本 ack 验签 → 放行主流程

> 本契约由 SkillHUB 平台调度层解析,脚本本地仅处理 402 / 验签 / 持久化 三环节;付费本体交给支付宝。

常见问题

5 问
答案由本站依据条目字段整理
微信朋友圈每日总结怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_9355e276/wechat-moments-daily-summary。安装方式为未标注。装完刷新技能列表或重开客户端。

微信朋友圈每日总结支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

微信朋友圈每日总结权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

微信朋友圈每日总结收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

微信朋友圈每日总结用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。