基于OpenClaw的GitHub Trending自动化推送工具设计与实践
1. 项目概述作为一个长期泡在GitHub上的开发者我每天都会习惯性地刷一下Trending页面看看今天又有什么新奇的轮子诞生或者哪个老项目又因为某个新特性火了一把。但说实话这个习惯挺“奢侈”的你得专门打开网页手动筛选语言还得花时间快速浏览几十个仓库的README来判断值不值得深入。时间一长这事儿就变成了一个负担特别是当你想持续追踪某个特定领域比如Rust生态、AI工具链的趋势时手动操作效率极低还容易遗漏。后来我接触到了OpenClaw一个非常灵活的自动化平台。我就琢磨能不能把“刷Trending”这个动作自动化让它变成一个主动推送的服务于是就有了这个openclaw-github-trending项目。它的核心目标很简单帮你把GitHub Trending从需要主动访问的“信息源”变成主动、准时、精准投喂的“信息流”。这个项目本质上是一个运行在OpenClaw平台上的Skill技能。它定时比如每天早上9点去抓取GitHub Trending的数据然后根据你预设的规则比如只关注JavaScript仓库、只推送star增长超过100的项目进行过滤和整理最后把结果推送到你常用的聊天工具里比如飞书、Telegram或者Discord。更酷的是它还集成了AI摘要功能通过OpenRouter对于那些描述冗长的仓库可以让AI帮你提炼核心亮点让你一眼抓住重点。我把它设计得尽可能简单从克隆代码到收到第一条推送顺利的话3分钟就能搞定。它不是为了替代深度探索而是帮你高效地完成“信息粗筛”把节省下来的时间用在真正有价值的代码阅读和项目实践上。无论你是想保持技术敏感度的个人开发者还是需要为团队提供技术动态简报的Tech Lead这个工具都能派上用场。2. 核心设计与架构解析2.1 为什么选择OpenClaw作为运行平台在动手之前我评估过几种方案自己写个常驻后台进程、用云函数如AWS Lambda、或者用现成的IFTTT/Zapier这类自动化工具。最终选择OpenClaw主要是基于以下几个考量第一生态原生集成管理成本极低。OpenClaw本身就是一个为自动化任务设计的平台它内置了强大的定时任务Cron调度器、会话管理和日志系统。这意味着我不需要自己从头实现一个健壮的定时任务队列也不需要操心进程守护和异常重启。直接把Skill扔进OpenClaw的workspace用一行openclaw cron add命令就能创建定时任务所有执行日志在OpenClaw的控制台里一目了然管理起来非常顺手。第二“技能化”设计扩展性强。OpenClaw的Skill架构让这个工具变得非常模块化。抓取、过滤、通知、AI摘要每个环节都可以独立开发和替换。比如今天我用飞书通知明天想换成企业微信我只需要实现一个新的Notifier模块替换掉配置即可核心逻辑完全不用动。这种设计也便于社区贡献其他人可以很容易地为其添加新的通知渠道或数据源。第三依赖与配置隔离。每个OpenClaw Skill都在自己独立的目录下运行有自己的package.json和node_modules。这避免了全局依赖冲突的问题。项目的配置通过一个简单的.env文件管理与代码分离既安全又便于在不同环境开发、生产间切换。第四一键部署的极致体验。我写了一个自动化的部署脚本deploy.js它封装了克隆、安装、配置引导的全过程。用户只需要运行一条curl命令后续的交互式配置引导会带着他完成所有必要设置。这种体验极大地降低了使用门槛即使是刚接触命令行和Node.js的开发者也能快速上手。2.2 数据流与核心模块拆解整个项目的运行遵循一个清晰的数据流水线我把它拆解成了四个核心模块这样无论是理解代码还是未来调试都更清晰。模块一数据抓取器Fetcher它的职责很单纯就是调用GitHub Trending的API实际上由于GitHub没有公开的官方Trending API这里通常是通过爬取Trending页面或使用可靠的第三方API来实现来获取原始数据。这里需要考虑几个关键点请求频率与礼貌性必须遵守GitHub的robots.txt不能请求过快避免对服务器造成压力或被封IP。定时任务本身已经将频率控制在一天几次是合理的。错误处理与重试网络请求可能失败模块需要具备重试机制和友好的错误日志便于排查是网络问题还是API变更。数据格式化将抓取到的HTML或JSON数据解析成结构化的对象数组每个对象包含仓库名、作者、语言、今日新增Star数、总Star数、简介等关键字段。模块二过滤器Filter这是体现“个性化”和“精准度”的核心。原始Trending列表可能包含几十个仓库但并非每个你都关心。过滤器根据.env中的配置规则进行筛选按语言过滤FILTER_LANGUAGEjavascript,python表示只关注JS和Python项目。按Star数过滤FILTER_MIN_STARS100可以过滤掉那些热度不高的小众项目。按日期范围过滤虽然Trending本身有“今日”、“本周”、“本月”的筛选但这里可以再做一层自定义比如只推送过去24小时内新上榜的项目。 过滤逻辑是“且”的关系只有满足所有条件的仓库才会进入下一环节。这部分代码我设计得比较灵活规则可以很方便地增删。模块三AI摘要器Summarizer可选这是一个增值功能依赖于OpenRouter API。对于通过过滤的仓库如果其description描述文本较长或比较晦涩可以将其发送给AI模型比如Claude或GPT请求生成一段简短、精炼的中文或英文摘要突出其技术特点、解决的问题或创新点。注意使用AI摘要会产生API调用费用并且依赖于外部服务的可用性。因此它在配置中是可选OPENROUTER_API_KEY为空则跳过。在实际使用中对于描述已经很清晰的仓库跳过AI摘要可以节省成本和时间。模块四通知发送器Notifier这是流水线的终点负责将处理好的信息包装成特定格式发送到目标渠道。项目内置了四种通知器的实现飞书适配飞书群机器人的Webhook格式支持Markdown文本展示效果较好。Telegram通过Bot API发送消息到个人或群组。Discord通过Webhook发送消息到指定频道。Slack同样通过Webhook实现。 每个Notifier都需要处理各自平台的API认证、消息格式封装以及发送失败后的异常处理。配置时你只需要在.env中指定NOTIFY_CHANNEL和对应的NOTIFY_TARGET如Webhook URL或Chat ID。2.3 环境配置与密钥管理详解项目的所有行为都由.env文件驱动。理解每个配置项的作用是灵活使用和故障排查的基础。下面我详细解释一下# 通知渠道必填。可选值feishu, telegram, discord, slack NOTIFY_CHANNELfeishu # 通知目标必填。根据渠道不同含义不同 # - feishu: 飞书机器人的 Webhook URL 中 hook/ 后面的部分或用户的 open_id # - telegram: 你的 Telegram Chat ID (数字) # - discord: Discord Webhook URL # - slack: Slack Webhook URL NOTIFY_TARGETyour_target_here # 过滤规则 (可选不配置则不过滤) # 过滤语言多个用英文逗号分隔 FILTER_LANGUAGEjavascript,typescript # 最小新增star数今日/本周 FILTER_MIN_STARS50 # 是否只显示今日新增的仓库(true/false) FILTER_TODAY_ONLYfalse # AI 摘要功能 (可选) # OpenRouter API 密钥用于生成AI摘要 OPENROUTER_API_KEYsk-or-v1-xxxxxx # 使用的AI模型例如claude-3-haiku-20240307, gpt-3.5-turbo OPENROUTER_MODELclaude-3-haiku-20240307 # 摘要语言例如zh-CN (简体中文), en (英文) SUMMARY_LANGzh-CN # GitHub 抓取配置 (高级通常无需改动) # Trending 时间范围daily, weekly, monthly GITHUB_TRENDING_PERIODdaily # 要获取的仓库数量最大可能为25GitHub页面限制 GITHUB_TRENDING_LIMIT10实操心得关于 NOTIFY_TARGET 的获取这是配置中最容易卡住的一步。每个平台获取NOTIFY_TARGET的方式都不同飞书最方便的是使用“群机器人”。在飞书群里添加一个自定义机器人创建时就能获得一个Webhook地址形如https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx。这里的xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx就是你的NOTIFY_TARGET。如果想推送给个人则需要获取用户的open_id这需要通过飞书开放平台API来获取相对复杂。Telegram你需要先和BotFather创建一个Bot获得它的token。然后给你创建的Bot发送一条消息比如/start。接着访问这个URL来获取你的Chat IDhttps://api.telegram.org/botYOUR_BOT_TOKEN/getUpdates。在返回的JSON中找到message.chat.id字段的值那就是你的NOTIFY_TARGET。Discord/Slack在频道设置中创建“Incoming Webhook”即可获得完整的Webhook URL这个URL本身就是NOTIFY_TARGET。 建议先在浏览器的地址栏里测试一下这些Webhook URL或API确保能正常访问再填入配置。3. 从零开始的部署与配置实战理论讲完了我们动手把它跑起来。我会以最常用的飞书通知为例带你走一遍完整的流程。3.1 一键部署脚本的背后原理与执行项目提供的部署命令是curl -fsSL https://raw.githubusercontent.com/maichanks/openclaw-github-trending/main/deploy.js -o deploy.js node deploy.js这条命令做了两件事curl -fsSL ... -o deploy.js从GitHub仓库下载deploy.js脚本到当前目录。-f表示失败时不显示HTTP错误-s静默模式-S在静默模式下显示错误-L跟随重定向。node deploy.js执行这个Node.js脚本。我们来看看这个deploy.js脚本大概做了什么这是理解自动化部署的好习惯检查环境首先会检查你的系统是否安装了Node.js、git以及OpenClaw是否已初始化。克隆代码将openclaw-github-trending仓库克隆到OpenClaw的默认技能目录 (~/.openclaw/workspace/skills/) 下。安装依赖进入项目目录运行pnpm install如果未安装pnpm则回退到npm install来安装所有必要的Node.js包。创建配置将项目内的.env.example模板文件复制为.env。交互式配置脚本会启动一个简单的命令行交互界面一步步引导你填写NOTIFY_CHANNEL、NOTIFY_TARGET等关键配置并直接写入.env文件。验证配置可能会尝试发送一条测试消息以确保你的配置是正确的。执行步骤打开你的终端Linux/macOS的Terminal或Windows的WSL/PowerShell。确保你已经安装并正确初始化了OpenClaw。如果还没安装需要先去OpenClaw的官方文档完成安装。直接运行上面那条长长的curl命令。根据终端的提示一步步选择通知渠道、输入对应的Target。脚本运行完毕后项目就已经部署和配置好了。3.2 手动安装与深度配置指南如果你更喜欢手动控制每一步或者想安装在自定义路径可以按照以下步骤操作# 1. 克隆项目到任意目录 git clone https://github.com/maichanks/openclaw-github-trending.git cd openclaw-github-trending # 2. 安装依赖 (推荐使用pnpm速度更快) pnpm install # 如果没有pnpm可以用npm: npm install # 3. 复制环境变量模板并编辑 cp .env.example .env # 使用你喜欢的编辑器打开 .env 文件比如 vim, nano, 或 VS Code # nano .env 或 code .现在打开.env文件开始配置。我们以飞书为例进行详细配置# .env 文件内容示例 NOTIFY_CHANNELfeishu # 假设你的飞书机器人Webhook是https://open.feishu.cn/open-apis/bot/v2/hook/abcd1234-5678-90ef-ghij-klmnopqrstuv # 那么 NOTIFY_TARGET 就是 abcd1234-5678-90ef-ghij-klmnopqrstuv NOTIFY_TARGETabcd1234-5678-90ef-ghij-klmnopqrstuv # 我只关心JavaScript和TypeScript的趋势 FILTER_LANGUAGEjavascript,typescript # 只推送今天新增Star超过50的项目过滤掉一些微小变动 FILTER_MIN_STARS50 FILTER_TODAY_ONLYtrue # 我暂时不需要AI摘要所以注释掉或留空 # OPENROUTER_API_KEYsk-or-v1-xxxxxx # OPENROUTER_MODELclaude-3-haiku-20240307 # SUMMARY_LANGzh-CN # 抓取今日趋势最多10条 GITHUB_TRENDING_PERIODdaily GITHUB_TRENDING_LIMIT10保存并关闭.env文件。3.3 首次运行测试与验证在配置好定时任务之前强烈建议先手动运行一次确保一切正常。# 在你的项目根目录下运行 node src/index.js如果一切顺利你的终端会输出一些日志显示它正在抓取、过滤数据最后会尝试发送通知。同时你的飞书群或你配置的其他渠道应该会收到一条来自机器人的消息。如何判断成功查看终端日志没有出现红色的错误堆栈信息最后有类似“Notification sent successfully to Feishu”的提示。检查飞书消息收到一条格式清晰的卡片消息或Markdown消息里面列出了过滤后的GitHub Trending仓库列表包含仓库名、链接、语言、Star数变化和简介。如果没收到消息怎么办检查.env配置特别是NOTIFY_TARGET一个字符都不能错。检查网络确保你的服务器或本地机器可以访问api.github.com和飞书的API域名 (open.feishu.cn)。查看详细日志有时脚本会输出更详细的错误信息比如“Invalid webhook URL”或“Authentication failed”。根据错误信息去排查。手动测试Webhook对于飞书/Discord/Slack你可以用curl命令直接测试Webhook。例如对于飞书curl -X POST -H Content-Type: application/json \ -d {msg_type:text,content:{text:测试消息}} \ https://open.feishu.cn/open-apis/bot/v2/hook/YOUR_TARGET如果返回{StatusCode:0, ...}说明Webhook本身是通的问题可能出在消息格式或脚本逻辑上。3.4 注册为OpenClaw定时任务手动测试通过后就可以把它交给OpenClaw的Cron系统来定时执行了。这是实现“自动化”的最后一步。# 在项目根目录外或任何地方执行都可以 openclaw cron add \ --name GitHub Trending Morning Digest \ --cron 0 9 * * * \ --session isolated \ --message node /绝对路径/到/openclaw-github-trending/src/index.js参数解析--name给你的定时任务起个名字方便在OpenClaw后台管理界面识别。--cronCron表达式定义执行时间。0 9 * * *表示每天上午9点整执行。你可以根据需求调整比如0 18 * * *是下午6点。--session isolated指定在独立的会话中运行这个任务避免与OpenClaw的其他任务相互干扰。--message要执行的命令。这里非常重要必须使用技能的绝对路径。你不能直接用node src/index.js因为Cron执行时的当前工作目录可能不是项目目录。最可靠的方法是写绝对路径。你可以用pwd -P命令先获取项目的绝对路径。一个更稳妥的做法是先进入项目目录然后用pwd -P获取路径cd ~/.openclaw/workspace/skills/openclaw-github-trending FULL_PATH$(pwd -P) openclaw cron add \ --name GitHub Trending \ --cron 0 9 * * * \ --session isolated \ --message node $FULL_PATH/src/index.js添加成功后你可以用openclaw cron list查看所有定时任务用openclaw cron logs --name “GitHub Trending”查看该任务的执行日志这将是后续排查问题的主要依据。4. 高级功能与定制化开发基础功能用顺手了你可能会想让它更贴合自己的需求。这个项目的代码结构比较清晰进行一些定制化开发并不难。4.1 玩转过滤规则打造你的专属趋势流默认的过滤规则已经很有用但我们可以更精细。假设你是一个数据工程师只关心Python和SQL相关的、且在过去一周内星标数暴涨比如新增500的项目。那么你的.env可以这样配置FILTER_LANGUAGEpython,sql FILTER_MIN_STARS500 # 注意GITHUB_TRENDING_PERIOD 要设置为 weekly GITHUB_TRENDING_PERIODweekly FILTER_TODAY_ONLYfalse # 因为是周榜这个开关意义不大但有时需求会更复杂。比如你想排除掉某些特定类型的仓库例如你不想看到任何与“区块链”或“加密货币”相关的项目。原生的过滤器可能不支持关键词排除。这时你就需要修改源代码了。定位文件过滤逻辑通常在src/filter.js或类似的模块中。修改思路在过滤函数中在通过了语言、Star数等基本筛选后增加一个“关键词排除”的步骤。例如// 伪代码在 filterRepositories 函数内 const excludedKeywords [blockchain, crypto, bitcoin]; const description repo.description.toLowerCase(); for (const keyword of excludedKeywords) { if (description.includes(keyword)) { return false; // 排除该仓库 } } return true; // 保留该仓库修改后记得重新运行node src/index.js测试一下效果。4.2 集成AI摘要让信息消化效率倍增AI摘要是这个项目的亮点功能。启用后推送的消息不仅包含仓库基本信息还会附带一段由AI生成的精炼摘要帮你快速判断是否值得点开链接深究。配置步骤获取OpenRouter API Key前往 OpenRouter 官网注册账号在API Keys页面创建一个新的密钥。新用户通常有一些免费额度。配置.envOPENROUTER_API_KEYsk-or-v1-你的真实密钥 # 选择模型claude-3-haiku 性价比高速度快 OPENROUTER_MODELclaude-3-haiku-20240307 # 摘要语言 SUMMARY_LANGzh-CN理解成本每次调用AI摘要都会消耗OpenRouter的额度。claude-3-haiku模型每1000个tokens约750个英文单词费用很低为一次Trending列表中的10个仓库生成摘要成本通常不到1美分。你可以在OpenRouter后台监控使用量和费用。AI提示词Prompt的奥秘摘要的质量很大程度上取决于我们给AI的“指令”。在src/summarizer.js中你会找到一个generateSummary函数里面构造了发送给AI的提示词。默认的提示词可能是“请为以下GitHub仓库描述生成一段简短摘要{description}”。你可以优化这个提示词来获得更符合你口味的摘要例如“你是一个资深技术专家。请用一句话总结这个GitHub项目的核心价值和技术亮点避免罗列功能。如果项目是框架或库请说明它解决了什么痛点。语言中文。”修改提示词后AI生成的摘要会更偏向于“价值洞察”而非“功能复述”。4.3 开发新的通知渠道Notifier项目内置了四个主流渠道但如果你用的是钉钉、企业微信、甚至是邮件就需要自己实现一个Notifier。这个过程是标准的适配器模式。以实现“钉钉群机器人”为例创建文件在src/notifiers/目录下创建一个新文件例如dingtalk.js。实现接口参考feishu.js或slack.js的实现。核心是导出一个send函数该函数接收格式化后的消息内容并将其转换为钉钉机器人Webhook要求的JSON格式然后使用fetch或axios发送POST请求。// src/notifiers/dingtalk.js 示例框架 const axios require(axios); async function send({ content, webhookUrl }) { const dingtalkMsg { msgtype: markdown, markdown: { title: GitHub Trending 日报, text: content // 这里需要将通用content格式转换为钉钉markdown格式 } }; try { await axios.post(webhookUrl, dingtalkMsg); console.log(Notification sent successfully to DingTalk); } catch (error) { console.error(Failed to send notification to DingTalk:, error.message); throw error; } } module.exports { send };注册Notifier在项目的主入口文件如src/index.js或专门的配置文件中将你的新Notifier添加到渠道映射表里。// 在 notifiers/index.js 或类似文件中 const dingtalkNotifier require(./dingtalk); const notifiers { feishu: feishuNotifier, telegram: telegramNotifier, discord: discordNotifier, slack: slackNotifier, dingtalk: dingtalkNotifier, // 添加这一行 };更新配置现在你就可以在.env文件中设置NOTIFY_CHANNELdingtalk并将钉钉机器人的Webhook URL填入NOTIFY_TARGET了。5. 运维、监控与故障排查实录任何自动化服务稳定运行都离不开日常的运维和问题排查。这里分享我实际运行中遇到的一些典型问题和解决思路。5.1 日志是排查问题的第一线索OpenClaw的Cron任务日志是最重要的诊断工具。当发现没有收到推送时第一件事就是查日志。# 查看指定任务的最新日志 openclaw cron logs --name “GitHub Trending” --tail 20 # 或者查看所有任务的日志 openclaw cron logs你需要关注日志中的错误信息ERROR和警告信息WARN。常见的错误模式有错误现象可能原因排查步骤FetchError: request to ... failed网络问题无法连接GitHub或通知平台API。1. 检查服务器网络。ping api.github.com2. 检查防火墙/安全组规则。3. 如果是代理环境需在Node.js中配置代理。Error: Invalid webhook URLNOTIFY_TARGET配置错误。1. 仔细核对.env中的NOTIFY_TARGET值。2. 用curl命令手动测试Webhook方法见3.3节。Error: 429 Too Many Requests请求频率过高被GitHub或通知平台限流。1. 检查Cron表达式是否设置过密如每分钟一次。2. GitHub Trending页面本身更新有延迟过于频繁的抓取无意义且易被限流。建议最低间隔1小时。Error: Authentication failedAPI密钥无效或已过期多见于AI摘要。1. 检查OPENROUTER_API_KEY是否正确。2. 登录OpenRouter后台确认密钥状态和余额。任务日志为空或未执行Cron任务未成功添加或OpenClaw服务未运行。1. 执行openclaw cron list确认任务存在。2. 检查OpenClaw后台服务状态。3. 尝试手动执行命令node /path/to/src/index.js看是否报错。5.2 应对GitHub页面改版与API变更这是一个潜在的风险点。项目依赖于从GitHub Trending页面抓取数据如果GitHub前端页面结构发生重大改版解析数据的代码可能在src/fetcher.js中就会失效表现为抓取到的数据为空或格式错误。如何发现日志中可能会出现HTML解析错误或者抓取到的仓库列表始终为空。手动运行脚本观察终端输出的原始数据或解析后的数据是否正常。如何解决临时降级如果只是偶尔失败可能是临时网络波动。可以观察一两天。检查上游手动访问https://github.com/trending查看页面是否能正常打开结构是否有明显变化。更新依赖关注项目原仓库maichanks/openclaw-github-trending的更新。作者可能会发布适配新页面的版本。你可以通过git pull拉取最新代码。自行修复如果你有前端基础可以尝试自行修复解析逻辑。使用浏览器的开发者工具查看Trending页面的HTML结构找到仓库名、描述、Star数等元素对应的CSS选择器然后更新fetcher.js中的解析代码。5.3 性能优化与资源考量这个项目本身非常轻量但在一些特殊场景下仍需注意低配置服务器运行在内存很小的VPS上时同时处理AI摘要特别是调用大模型可能会占用较多内存。如果遇到进程意外退出可以尝试不使用AI摘要功能或者换用更轻量的模型如google/gemma-2-2b-it。定时任务冲突如果你在同一个OpenClaw实例上运行了很多高频率的Cron任务可能会造成资源竞争。确保你的任务执行时间错开并且使用--session isolated参数隔离运行环境。磁盘空间项目本身很小但Node.js的node_modules依赖包可能体积较大。定期清理不再使用的OpenClaw Skill可以释放空间。5.4 安全最佳实践保护你的.env文件这个文件包含了API密钥等敏感信息。绝对不要将它提交到Git仓库。项目根目录下的.gitignore文件通常已经包含了.env。在备份服务器配置时也要妥善处理此文件。使用环境变量在Docker或一些CI/CD环境中可以考虑直接使用系统环境变量而非文件但OpenClaw Skill目前更推荐.env文件的方式。最小权限原则为飞书机器人、Telegram Bot等配置最小必要的权限。例如飞书机器人只需要“发送消息”的权限不需要读取群成员列表等。定期轮换API密钥对于OpenRouter这类付费服务定期在后台重置API Key是一个好习惯。这个项目在我自己的开发环境中稳定运行了半年多它就像一位不知疲倦的助手每天早晨准时把一份精心筛选的技术简报送到我面前。它节省了我大量漫无目的浏览的时间让我能更聚焦于真正重要的技术动态。如果你也受困于信息过载不妨花上几分钟部署一下它可能会给你带来意想不到的效率提升。