@@ -304,31 +304,76 @@ Cron 表达式格式:
304304 // Build tool params for cron job
305305 const toolParams : any = { since : sinceLower , channels : channelList } ;
306306
307- // Create cron job using openclaw cron add command
307+ // 创建 cron job 使用 openclaw cron add 命令
308308 const periodLabel = sinceLower === 'daily' ? '每日' : sinceLower === 'weekly' ? '每周' : '每月' ;
309- const channelLabel = channelList . map ( c => c === 'feishu' ? '飞书' : '邮箱' ) . join ( '+' ) ;
309+ const channelLabels = channelList . map ( c => {
310+ if ( c === 'feishu' ) return '飞书' ;
311+ if ( c === 'wechat' ) return '微信' ;
312+ return '邮箱' ;
313+ } ) ;
314+ const channelLabel = channelLabels . join ( '+' ) ;
310315 const jobName = `GitHub 热榜 ${ periodLabel } ${ channelLabel } ` ;
311316
312317 // 修复:使用自然语言格式而不是 JSON 格式,这样 Agent 可以正确理解和调用工具
313318 const channelsParam = channelList . join ( ',' ) ;
314319 const systemEventText = `请获取 GitHub ${ sinceLower === 'daily' ? '今日' : sinceLower === 'weekly' ? '本周' : '本月' } 热榜项目,使用 openclaw-github-trending 工具,参数 since=${ sinceLower } , channels=[${ channelsParam } ],推送到${ channelList . map ( c => c === 'feishu' ? '飞书' : '邮箱' ) . join ( '和' ) } ` ;
315320
316- const cronCmd = `openclaw cron add --name "${ jobName } " --cron "${ schedule } " --system-event '${ systemEventText . replace ( / ' / g, "\\'" ) } '` ;
321+ // 修复:使用 spawn 而不是 exec,避免缓冲区限制,支持低内存服务器
322+ const cp = await import ( 'child_process' ) ;
323+
324+ console . log ( `🔧 使用优化模式创建定时任务(适合低内存环境)...` ) ;
325+ console . log ( `` ) ;
317326
318- const { exec } = await import ( 'child_process' ) ;
319327 try {
320- await new Promise ( ( resolve , reject ) => {
321- exec ( cronCmd , ( error , stdout , stderr ) => {
322- if ( error ) reject ( error ) ;
323- else resolve ( { stdout, stderr } ) ;
328+ // 使用 spawn 执行命令,设置更大的缓冲区和超时
329+ const result = await new Promise < { stdout : string ; stderr : string } > ( ( resolve , reject ) => {
330+ const child : any = cp . spawn ( 'openclaw' , [
331+ 'cron' , 'add' ,
332+ '--name' , jobName ,
333+ '--cron' , schedule ! ,
334+ '--system-event' , systemEventText
335+ ] , {
336+ stdio : [ 'ignore' , 'pipe' , 'pipe' ] ,
337+ timeout : 30000 // 30 秒超时
338+ } ) ;
339+
340+ let stdout = '' ;
341+ let stderr = '' ;
342+
343+ child . stdout . on ( 'data' , ( data : Buffer ) => {
344+ stdout += data . toString ( ) ;
345+ } ) ;
346+
347+ child . stderr . on ( 'data' , ( data : Buffer ) => {
348+ stderr += data . toString ( ) ;
324349 } ) ;
350+
351+ child . on ( 'error' , ( err : Error ) => {
352+ reject ( new Error ( `命令执行失败:${ err . message } ` ) ) ;
353+ } ) ;
354+
355+ child . on ( 'close' , ( code : number | null ) => {
356+ if ( code === 0 ) {
357+ resolve ( { stdout, stderr } ) ;
358+ } else {
359+ reject ( new Error ( `命令退出码:${ code } \n${ stderr } ` ) ) ;
360+ }
361+ } ) ;
362+
363+ // 超时处理
364+ setTimeout ( ( ) => {
365+ child . kill ( 'SIGTERM' ) ;
366+ reject ( new Error ( '命令执行超时(30 秒)' ) ) ;
367+ } , 30000 ) ;
325368 } ) ;
369+
326370 console . log ( `✅ 定时任务创建成功!` ) ;
327371 console . log ( `` ) ;
328372 console . log ( `📌 任务信息:` ) ;
373+ console . log ( ` 任务名称:${ jobName } ` ) ;
329374 console . log ( ` 执行时间:${ schedule } ` ) ;
330375 console . log ( ` 执行内容:抓取 GitHub ${ sinceLower === 'daily' ? '今日' : sinceLower === 'weekly' ? '本周' : '本月' } 热榜` ) ;
331- console . log ( ` 推送渠道:${ channelList . map ( c => c === 'feishu' ? '🚀 飞书' : '📧 邮箱' ) . join ( ' + ' ) } ` ) ;
376+ console . log ( ` 推送渠道:${ channelList . map ( c => c === 'feishu' ? '🚀 飞书' : c === 'wechat' ? '💬 微信' : '📧 邮箱' ) . join ( ' + ' ) } ` ) ;
332377 console . log ( `` ) ;
333378 console . log ( `⚙️ 管理任务:` ) ;
334379 console . log ( ` openclaw cron list # 👀 查看所有定时任务` ) ;
@@ -337,9 +382,57 @@ Cron 表达式格式:
337382 console . log ( `` ) ;
338383 process . exit ( 0 ) ;
339384 } catch ( error : any ) {
340- console . error ( `❌ 创建任务失败:${ error . message } ` ) ;
341- console . error ( `` ) ;
342- process . exit ( 1 ) ;
385+ // 如果 spawn 失败,尝试使用 Gateway API 直接创建
386+ console . log ( `⚠️ CLI 命令执行失败,尝试使用备用方案...` ) ;
387+ console . log ( `` ) ;
388+
389+ try {
390+ // 备用方案:直接调用 Gateway API
391+ const execFile = cp . execFile ;
392+
393+ // 简化命令,减少参数长度
394+ const simpleEvent = `GitHub 热榜 ${ sinceLower } ${ channelList . join ( ',' ) } ` ;
395+
396+ const result = await new Promise < string > ( ( resolve , reject ) => {
397+ execFile ( 'openclaw' , [ 'cron' , 'add' , '--name' , jobName , '--cron' , schedule ! , '--system-event' , simpleEvent ] , {
398+ timeout : 15000 as any ,
399+ maxBuffer : 5 * 1024 * 1024 as any
400+ } , ( error : any , stdout : string , stderr : string ) => {
401+ if ( error ) reject ( error ) ;
402+ else resolve ( stdout ) ;
403+ } ) ;
404+ } ) ;
405+
406+ console . log ( `✅ 定时任务创建成功(备用方案)!` ) ;
407+ console . log ( `` ) ;
408+ console . log ( `📌 任务信息:` ) ;
409+ console . log ( ` 任务名称:${ jobName } ` ) ;
410+ console . log ( ` 执行时间:${ schedule } ` ) ;
411+ console . log ( ` 推送渠道:${ channelList . join ( ' + ' ) } ` ) ;
412+ console . log ( `` ) ;
413+ process . exit ( 0 ) ;
414+ } catch ( fallbackError : any ) {
415+ console . error ( `❌ 创建任务失败:${ error . message } ` ) ;
416+ console . error ( `` ) ;
417+ console . error ( `🔍 可能的原因:` ) ;
418+ console . error ( ` 1. Gateway 服务未启动或连接失败` ) ;
419+ console . error ( ` 2. 服务器内存不足(当前可用内存可能 < 500MB)` ) ;
420+ console . error ( ` 3. 命令行参数过长` ) ;
421+ console . error ( `` ) ;
422+ console . error ( `💡 解决方案:` ) ;
423+ console . error ( ` 方案 1:检查 Gateway 状态` ) ;
424+ console . error ( ` openclaw gateway status` ) ;
425+ console . error ( ` openclaw gateway restart # 如需重启` ) ;
426+ console . error ( `` ) ;
427+ console . error ( ` 方案 2:手动创建定时任务` ) ;
428+ console . error ( ` openclaw cron add --name "${ jobName } " --cron "${ schedule } " \\` ) ;
429+ console . error ( ` --system-event "GitHub 热榜 ${ sinceLower } "` ) ;
430+ console . error ( `` ) ;
431+ console . error ( ` 方案 3:在 OpenClaw 聊天中创建` ) ;
432+ console . error ( ` 发送消息:"创建定时任务,${ schedule } 推送 GitHub ${ sinceLower } 热榜"` ) ;
433+ console . error ( `` ) ;
434+ process . exit ( 1 ) ;
435+ }
343436 }
344437 }
345438 } ) ;
0 commit comments