Skill: zq62191161-ai/xl-weekly-report-email (version 1.0.0)

--- name: Weekly Report Email description: 通用周报收集和邮件推送技能，支持交互式填写周报内容，自动计算周数和日期范围，生成美观的HTML格式邮件。 emoji: 📧 trigger: 写周报 --- # 周报技能 - xl-weekly-report-email 一个通用的周报收集和邮件推送技能，安装后配置邮箱即可使用。 ## 触发方式 在对话中说"写周报"即可触发周报生成流程。 配置邮箱时说"配置周报邮箱"。 --- ## ⚠️ 重要：执行此技能时必须严格遵循以下步骤，不得省略或跳过任何步骤！ **最关键的规则：** - **每次只问一个问题，等用户回复后再问下一个** - **绝对禁止一次性抛出所有问题** - **绝对禁止在没有用户确认的情况下自动发送邮件！** - **必须等待用户明确确认后才能发送邮件！** - **任何用户回复的内容都应该被记录，除非用户明确回复"无"、"空"、"不需要"、"跳过"等否定词** - **即使内容很短（如"2"、"无内容"等非否定词），也应该记录** - **即使内容不按格式写，也应该直接展示，不当作空值处理** --- ## 📋 完整工作流程 ### 第零步：检查配置 首次使用需要配置邮箱参数和报告参数。发送"配置周报邮箱"命令会自动引导你完成配置。 配置内容包括： 1. **SMTP服务器**：选择预设（腾讯企业邮箱、阿里企业邮箱、Gmail 等）或自定义 2. **SMTP端口**：通常是465（SSL）或587（TLS） 3. **邮箱账号**：你的邮箱地址 4. **邮箱密码**：邮箱登录密码或授权码 5. **发件人**：发件人邮箱地址（通常与账号相同） 6. **组织/部门名称**（可选）：如"XX公司"，会显示在邮件标题开头 7. **你的姓名**：如"张三" 8. **你的职位**：如"后端工程师" 9. **周报收件人**：接收周报的邮箱地址 10. **周报抄送人**（可选）：抄送周报的邮箱地址 **注意：** - 组织/部门名称（`company`）字段可选，如果配置了会显示在邮件标题开头；如果不配置或为空，邮件标题中不会显示组织/部门名称和前面的"-"。 - 默认抄送人（`cc`）字段可选，如果配置了每次发送时都会抄送这些邮箱；如果不配置，则不抄送（除非发送时额外添加）。 - 邮箱配置会自动保存到 `.env` 文件（包含敏感信息，不会被发布到 clawhub）。 - 报告配置会保存到 `config.json` 文件。 ### 第一步：计算并展示日期信息 **必须先执行这一步！** 自动计算并展示以下信息（所有时间必须是东八区）： - 周数 = ISO周数（周五/周六/周日不减1，周四/周四之前减1） - 截止日期 = 下周周四（YYYYMMDD 格式） - 时间范围 = 本周四 到 下周三（中文格式：YYYY年MM月DD日） **示例输出（如果今天是周五）：** ``` 📊 周报日期信息： - 周数：13 - 截止日期：20260402 - 时间范围：2026年3月26日 至 2026年4月1日 ``` **⚠️ 警告：在计算并展示日期信息之前，不要询问任何周报内容！** --- ### 第二步：逐项收集周报内容 **⚠️ 关键规则：必须一个一个询问！禁止一次性抛出所有问题！** 每次只问一个问题，等用户回复后再问下一个。绝对不能把所有问题一次性列出来！ #### 第一部分：遗留问题/阻碍因素跟进 **执行顺序：** 1. 先给描述 2. 再给格式提示 3. 最后给示例 4. 等用户回复 **描述：** 列出上周遗留问题或当前最大的阻碍因素的跟进情况。 **格式：** [问题描述][当前状态]：进展详情 **重要：** 必须使用方括号 `[]` 包裹问题描述和当前状态，否则没有样式！ **示例：** ``` 1. [测试环境资源不足][已解决]：已申请新服务器，问题解决，进度已恢复。 2. [数据接口延迟问题][跟进中]：已联系数据负责人，承诺本周五前修复，目前正在联调。 ``` **状态样式说明：** - `已解决` 或 `Done` → 绿色样式 ✓ - 其他所有状态 → 蓝色样式 → **⚠️ 格式提示与用户坚持的规则（重要！）：** **用户输入内容不按格式时的处理流程：** **情况1：用户第一次输入不按格式（如"111"、"完成开发任务"等）** - AI **只提示一次**："建议格式是 [问题描述][当前状态]：进展详情，您确定要这样写吗？" - 如果用户回复"确定"、"是的"、"就这么写"等确认词 → **直接记录用户之前输入的内容**（"111"） - 如果用户回复"好的"、"明白了"等 → 重新询问用户第一部分内容 - 如果用户继续输入新的内容（不是确认词） → **直接记录用户新输入的内容** **情况2：用户坚持使用不按格式的内容** - 任何用户输入的内容，都应该被记录，除非用户明确回复"无"、"空"、"不需要"、"跳过"等否定词 - 即使内容很短（如"111"、"222"），也应该记录 - 即使内容不按格式写，也应该直接展示，用普通样式展示 **记住：** - 格式提示只提示一次，不要重复提示 - 用户输入任何内容（除了明确的否定词），都要记录 - 不要问"您确定要这样写吗？"多次 **⚠️ 关键规则：** - **任何用户回复的内容都应该被记录，除非用户明确回复"无"、"空"、"不需要"、"跳过"等否定词** - **即使内容很短（如"2"、"123"），也应该记录** - **即使内容不按格式写，也应该直接展示，不当作空值处理** **⚠️ 禁止：** 不要问"第一部分是什么"，直接按照"描述→格式→示例"的顺序给用户！也不要继续问第二部分，等用户回复第一部分后再问！ --- #### 第二部分：本周具体产出 **执行顺序：** 1. 先给描述 2. 再给格式提示 3. 最后给示例 4. 等用户回复 **描述：** 列出本周具体的产出，建议按项目或模块分类。 **格式：** [项目 xxx] 子项目名 + 项目状态 (Done/Doing 进度 X%/ Delay/ Suspend) + 进度详情/阶段成果/阻塞原因 **重要：** 必须使用方括号 `[]` 包裹项目名，状态必须用圆括号 `()` 包裹，否则没有样式！ **示例：** ``` 1. [项目 A] 画像标签开发 (Doing 80%) 完成了用户活跃度标签的逻辑重构，性能提升 30%。 正在与业务方进行数据验收。 2. [数据治理] 人员数据质量优化 (Done) 完成了历史脏数据的清洗工作，并补充了缺失的日志数据。 3. [项目 B] 人员表开发（Doing 80%/Delay） 完成了 xxxx 的开发 需求变动导致 delay ``` **状态样式说明：** - `Done` → 绿色样式 - `Delay` → 橙色样式 - `Suspend` → 灰色样式 - `Doing 进度X%` 或其他状态 → 蓝色样式 - 组合状态（如 `Doing 80%/Delay`）会拆分成多个状态标签，分别显示对应样式 **⚠️ 格式提示与用户坚持的规则（重要！）：** **用户输入内容不按格式时的处理流程：** **情况1：用户第一次输入不按格式（如"222"、"完成开发任务"等）** - AI **只提示一次**："建议格式是 [项目名] 任务名 (状态)，您确定要这样写吗？" - 如果用户回复"确定"、"是的"、"就这么写"等确认词 → **直接记录用户之前输入的内容**（"222"） - 如果用户回复"好的"、"明白了"等 → 重新询问用户第二部分内容 - 如果用户继续输入新的内容（不是确认词） → **直接记录用户新输入的内容** **情况2：用户坚持使用不按格式的内容** - 任何用户输入的内容，都应该被记录，除非用户明确回复"无"、"空"、"不需要"、"跳过"等否定词 - 即使内容很短（如"222"、"123"），也应该记录 - 即使内容不按格式写，也应该直接展示，用普通样式展示 **记住：** - 格式提示只提示一次，不要重复提示 - 用户输入任何内容（除了明确的否定词），都要记录 - 不要问"您确定要这样写吗？"多次 **⚠️ 关键规则：** - **任何用户回复的内容都应该被记录，除非用户明确回复"无"、"空"、"不需要"、"跳过"等否定词** - **即使内容很短（如"2"、"123"），也应该记录** - **即使内容不按格式写，也应该直接展示，不当作空值处理** **⚠️ 禁止：** 同上，等用户回复第一部分后再问第二部分！不要问"第二部分是什么"，直接按顺序给！ --- #### 第三部分：技术难点/业务卡点 **执行顺序：** 1. 先给描述 2. 最后给示例 3. 等用户回复 **描述：** 这里重点写本周遇到的技术难点或业务卡点，以及你打算怎么解决。 **示例：** ``` 1. 问题描述：需求频繁变更，导致开发返工。 解决方案：已与产品经理约定，后续需求变更需通过 TAPD 更新 PRD 并邮件周知，重大变更需重新评估工时。 2. 问题描述：ClickHouse 查询超时。 解决方案：通过分析慢查询日志，发现索引未命中，已优化 SQL 语句并增加二级索引。 ``` **⚠️ 禁止：** 同上，等用户回复后再继续！ --- #### 第四部分：下周核心计划 **执行顺序：** 1. 先给描述 2. 最后给示例 3. 等用户回复 **描述：** 按优先级列出下周的核心产出承诺。 **示例：** ``` 1. [计划 1] 2. [计划 2] 3. [计划 3] ``` **⚠️ 禁止：** 同上！ --- #### 第五部分：团队协作/流程/架构思考（非必选） **执行顺序：** 1. 先给描述 2. 最后给示例 3. 等用户回复 **描述：** 不仅限于自己的代码，着眼于团队协作、流程、架构等宏观问题。这是周报中体现思考深度的部分。 **示例：** ``` 1. 协作问题：[例如：数据上游经常口头变更字段，导致下游任务失败]。建议建立字段变更通知机制，必须经过审批群周知。 2. 架构/稳定性问题：[例如：当前实时任务单点故障风险较高]。建议将核心任务迁移至 Flink 集群，并配置拉起机制。 3. 业务痛点：[例如：业务方普遍反映离线数据产出时间太晚]。建议优化 DAG 调度依赖，将核心任务优先级提高。 ``` **⚠️ 禁止：** 同上！ --- #### 第六部分：自由发挥区（非必选） **执行顺序：** 1. 先给描述 2. 等用户回复 **描述：** 自由发挥区（心得体会、GET 技能、共鸣句子、个人思考等） **⚠️ 禁止：** 同上！ --- ### 第三步：保存周报内容（临时文件） 将所有内容写入 `memory/weekly-report-YYYYMMDD.md` 文件 **注意：** 这是临时文件，发送完邮件后会自动删除，不会保留。 **保存临时文件的方式：** ```javascript const fs = require('fs'); const path = require('path'); // 生成文件名（用当前日期） const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, ''); // YYYYMMDD const tempFile = path.join(__dirname, 'memory', `weekly-report-${dateStr}.md`); // 确保目录存在 const memoryDir = path.join(__dirname, 'memory'); if (!fs.existsSync(memoryDir)) { fs.mkdirSync(memoryDir, { recursive: true }); } // 写入文件 fs.writeFileSync(tempFile, content); ``` --- ### 第四步：生成 HTML 预览 **⚠️ 必须使用 main.js！禁止自己手写 HTML！** **正确方式：** ```bash cd /home/node/.openclaw/workspace/skills/xl-weekly-report-email nodejs main.js ``` **调用方式：** - 先导入：`const { generateWeeklyReport } = require('./main.js');` - 再生成：`const report = generateWeeklyReport(content);` - 预览：把 `report.body` 给用户看 **禁止：** - ❌ 自己写 HTML - ❌ 直接输出文本 - ❌ 省略样式 **⚠️ 重要：生成预览后，给用户看HTML内容，然后问用户是否确认发送！绝对不要自动发送！** --- ### 第五步：询问额外抄送人（可跳过） **⚠️ 在发送邮件前询问！** **执行顺序：** 1. 询问用户是否有其他抄送人 2. 让用户填写抄送邮箱地址（多个用逗号分隔，全角逗号"，"或半角逗号","都可以） 3. 如果用户不填或填写"无"，则只使用配置的抄送人（如果配置了） **示例：** ``` 这次发送周报，是否需要添加其他抄送人？（可留空，多个邮箱用逗号分隔） 例如：[REDACTED_SECRET],[REDACTED_SECRET] ``` --- ### 第六步：发送邮件 **⚠️ 关键规则：必须等待用户明确确认后才能发送邮件！绝对禁止自动发送！** **执行顺序：** 1. 生成 HTML 格式预览给用户确认 2. **明确询问用户：是否确认发送？** 3. **等待用户明确回复"确认"、"发送"、"是"等确认词** 4. **只有收到用户明确确认后，才能调用 `main.js` 中的 `generateAndSendReport(content, additionalCc, tempFilePath)` 函数发送邮件** 5. **如果用户回复"不"、"取消"、"修改"等否定词，则不发送，询问用户需要修改什么** 6. 邮件信息（收件人、抄送、发件人）处理逻辑： - 配置的抄送人 + 额外填写的抄送人 = 所有抄送人（自动去重） - 如果两者都没有，则不抄送任何人 7. 邮件发送成功后，自动删除临时文件 `memory/weekly-report-YYYYMMDD.md` **⚠️ 严重警告：** - **绝对禁止在生成预览后自动发送邮件！** - **绝对禁止在没有用户确认的情况下调用发送函数！** - **必须明确等待用户的确认回复！** - `tempFilePath` 参数是第三步保存的临时文件路径 - 邮件发送成功后会自动清理，无需手动删除 - 如果需要手动清理，可以调用 `cleanupTempFile(filePath)` 函数 --- ## 📧 邮件规则 - **标题格式**: 从 config.json 读取配置生成（姓名、职位会自动填入） - **收件人**: 从 config.json 读取 - **抄送**: 从 config.json 读取（可选） - **时间计算规则**: - 周数 = 当前周数 - 1（使用 ISO 标准周数，通过 Python 的 `isocalendar()` 方法计算） - 截止日期 = 本周周四（如果今天 <= 周四则取本周，如果今天 > 周四则取下周） - 时间范围 = 上周四 到 本周三 --- ## 🔧 技术实现 ### 核心文件 - `main.js`: 周报生成和发送主逻辑（日期计算、HTML生成、内容解析） - `mailer.js`: 邮件发送模块（基于 nodemailer） - `setup.js`: 首次配置引导 - `config.json`: 用户配置文件 ### 依赖 - nodemailer: 邮件发送 ### 发送邮件的正确方式 **方式1：使用 nodemailer（main.js 中已集成）** ```javascript const { sendWeeklyReport } = require('./mailer'); await sendWeeklyReport(subject, htmlBody, recipient, cc); ``` **方式2：使用 imap-smtp-email/smtp.js 命令行（标准）** ```bash cd /home/node/.openclaw/workspace/skills/imap-smtp-email/scripts nodejs smtp.js send --to [REDACTED_SECRET] --subject "标题" --html-file email.html ``` ### ⚠️ 系统环境限制 - Node.js 命令是 `nodejs` 不是 `node` - nodemailer 依赖在 `/home/node/.openclaw/workspace/skills/xl-weekly-report-email/node_modules` --- ## 📁 配置文件格式 ### config.json（报告配置） 报告配置保存在 `config.json` 中： ```json { "report": { "company": "XX公司", "name": "张三", "position": "后端工程师", "recipient": "[REDACTED_SECRET]", "cc": "[REDACTED_SECRET]" } } ``` ### .env（邮箱配置） 邮箱配置保存在 `.env` 文件中（首次使用请复制 `.env.example` 为 `.env`）： ```env # SMTP 配置（发邮件） SMTP_HOST=smtp.qiye.aliyun.com SMTP_PORT=465 SMTP_SECURE=true SMTP_USER=[REDACTED_SECRET] SMTP_PASS=your-password SMTP_FROM=[REDACTED_SECRET] ``` **说明：** - `company` 字段可选，如果不配置或为空，邮件标题中不会显示组织/部门名称和前面的"-" - 如果配置了 `company`，邮件标题格式为：`组织/部门名称 - 职位姓名 - X周周报 - 日期` - 如果没配置 `company`，邮件标题格式为：`职位姓名 - X周周报 - 日期` - `.env` 文件包含敏感信息，不会被发布到 clawhub（在 .clawignore 中已排除） --- ## 🐛 常见问题 ### 忘记配置了怎么办？ 重新发送"配置周报邮箱"命令，会重新进入配置流程。 ### 邮件发送失败怎么办？ 1. 检查 `.env` 文件是否存在且配置正确 2. 检查邮箱密码是否正确（某些邮箱需要使用授权码） 3. 检查SMTP服务器地址和端口是否正确 4. 检查是否开启了SMTP服务 5. 查看 detailed 错误信息 ### 如何配置邮箱？ 1. 复制 `.env.example` 为 `.env` 2. 填写你的 SMTP 配置信息 ### 支持哪些邮箱？ 支持所有标准SMTP协议的邮箱，包括： - 腾讯企业邮箱 - 阿里企业邮箱 - 网易企业邮箱 - Gmail（需要应用专用密码） - Outlook - 其他支持SMTP的邮箱 --- ## 🧪 测试 运行测试脚本： ```bash cd /home/node/.openclaw/workspace/skills/xl-weekly-report-email nodejs test.js ``` --- **版本历史和变更日志请查看 [CHANGELOG.md](CHANGELOG.md)**


Security scan verdicts — ClawScan: suspicious | static analysis: suspicious | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)