/** * Daily Horoscope & Fortune Analysis * * 查询每日星座运势,结合黄历和八字分析 * 为桐哥 Agent 提供每日运势推送功能 */ const https = require('https'); // 王院长生辰信息 const USER_BIRTH_INFO = { name: '王院长', birthday: '1984-05-16', birthTime: '23:00-24:00', // 子时 lunarBirthday: '甲子年 四月十六', zodiac: '鼠', westernZodiac: '金牛座', bazi: { year: '甲子', month: '己巳', day: '丙午', hour: '戊子', dayMaster: '丙火' // 日主 } }; // 十二星座 const ZODIAC_SIGNS = [ '白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座', '摩羯座', '水瓶座', '双鱼座' ]; /** * 使用 Tavily 搜索运势信息 */ async function searchHoroscope(date, sign) { const tomorrow = new Date(date); tomorrow.setDate(tomorrow.getDate() + 1); const dateStr = tomorrow.toISOString().split('T')[0]; const query = `${dateStr} ${sign} 运势 星座运程`; // 调用 Tavily API const tavilyApiKey = process.env.TAVILY_API_KEY || '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'; return new Promise((resolve, reject) => { const postData = JSON.stringify({ query: query, search_depth: 'basic', include_answer: true, max_results: 3, topic: 'general' }); const options = { hostname: 'api.tavily.com', port: 443, path: '/search', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData), 'Authorization': `Bearer ${tavilyApiKey}` } }; const req = https.request(options, (res) => { let data = ''; res.on('data', (chunk) => data += chunk); res.on('end', () => { try { const result = JSON.parse(data); resolve(result); } catch (e) { reject(e); } }); }); req.on('error', reject); req.write(postData); req.end(); }); } /** * 查询黄历 */ async function queryAlmanac(date) { // 调用 chinese-almanac skill const almanacPath = '/root/.openclaw/workspace/skills/chinese-almanac/almanac.js'; try { const almanac = require(almanacPath); const result = await almanac.queryAlmanac(date); return result; } catch (e) { console.error('黄历查询失败:', e.message); // Fallback: 基础信息 return { success: false, date: date, lunarDate: '查询失败', yi: [], ji: [], chong: '' }; } } /** * 八字分析 - 根据日主和明日五行 */ function analyzeBazi(targetDate, userBazi) { const date = new Date(targetDate); const dayMaster = userBazi.dayMaster; // 丙火 // 简化的五行分析(实际应该用更精确的干支计算) const dayOfWeek = date.getDay(); const elements = ['金', '木', '水', '火', '土']; const tomorrowElement = elements[dayOfWeek % 5]; // 五行生克关系 const shengKe = { '丙火': { '金': '火克金 - 财星,利于求财', '木': '木生火 - 印星,贵人相助', '水': '水克火 - 官杀,压力较大', '火': '火比和 - 兄弟,竞争激烈', '土': '火生土 - 食伤,才华展现' } }; const analysis = shengKe[dayMaster]?.[tomorrowElement] || '五行平衡'; // 根据分析生成建议 const suggestions = { '财星': { lucky: ['商务谈判', '投资决策', '签订合同'], avoid: ['大额支出', '冒险投资'] }, '印星': { lucky: ['学习新知', '拜访长辈', '规划未来'], avoid: ['独自决策', '匆忙行动'] }, '官杀': { lucky: ['处理公务', '解决问题', '锻炼身体'], avoid: ['与人争执', '高风险活动'] }, '比和': { lucky: ['团队合作', '朋友聚会', '交流沟通'], avoid: ['单打独斗', '固执己见'] }, '食伤': { lucky: ['创意工作', '表达展示', '休闲娱乐'], avoid: ['批评他人', '过度消费'] } }; const key = Object.keys(suggestions).find(k => analysis.includes(k)) || '比和'; return { dayMaster: dayMaster, tomorrowElement: tomorrowElement, analysis: analysis, suggestions: suggestions[key] }; } /** * 生成运势报告 */ async function generateFortuneReport(targetDate) { const tomorrow = new Date(targetDate); tomorrow.setDate(tomorrow.getDate() + 1); const dateStr = tomorrow.toISOString().split('T')[0]; console.log(`[Horoscope] 查询 ${dateStr} 的运势...`); // 1. 查询黄历 const almanac = await queryAlmanac(dateStr); console.log('[Horoscope] 黄历查询完成'); // 2. 搜索金牛座运势(王院长是金牛座) let horoscopeText = ''; try { const horoscopeResult = await searchHoroscope(dateStr, '金牛座'); if (horoscopeResult.answer) { horoscopeText = horoscopeResult.answer; } else if (horoscopeResult.results && horoscopeResult.results.length > 0) { horoscopeText = horoscopeResult.results[0].content; } } catch (e) { console.error('星座运势搜索失败:', e.message); horoscopeText = '今日金牛座运势平稳,保持积极心态。'; } console.log('[Horoscope] 星座运势查询完成'); // 3. 八字分析 const baziAnalysis = analyzeBazi(dateStr, USER_BIRTH_INFO.bazi); console.log('[Horoscope] 八字分析完成'); // 4. 生成综合报告 const report = { date: dateStr, user: USER_BIRTH_INFO.name, zodiac: USER_BIRTH_INFO.westernZodiac, chineseZodiac: USER_BIRTH_INFO.zodiac, almanac: almanac, horoscope: { text: horoscopeText, source: 'Tavily AI Search' }, bazi: baziAnalysis, overallLuck: calculateOverallLuck(almanac, baziAnalysis) }; return report; } /** * 计算整体运势指数 */ function calculateOverallLuck(almanac, bazi) { let score = 3; // 基础 3 星 // 黄历加分项 if (almanac.yi && almanac.yi.length > 3) score += 0.5; if (almanac.chong && !almanac.chong.includes('鼠')) score += 0.5; // 八字加分项 if (baziAnalysis.analysis.includes('贵人') || baziAnalysis.analysis.includes('财星')) { score += 0.5; } const stars = Math.min(5, Math.max(1, Math.round(score))); return '★'.repeat(stars) + '☆'.repeat(5 - stars); } /** * 格式化运势报告为消息 */ function formatFortuneMessage(report) { const { date, user, zodiac, almanac, horoscope, bazi, overallLuck } = report; let message = `📅 **${user} · 明日运势**\n`; message += `${date} | ${almanac.lunarDate || '农历查询中'}\n\n`; message += `✨ **整体运势**: ${overallLuck}\n\n`; message += `🗓️ **黄历宜忌**\n`; message += `宜:${almanac.yi?.join('、') || '查询中'}\n`; message += `忌:${almanac.ji?.join('、') || '查询中'}\n`; if (almanac.chong) { message += `冲煞:${almanac.chong}\n`; } message += '\n'; message += `♉ **${zodiac}运势**\n`; message += `${horoscope.text}\n\n`; message += `🔮 **八字分析**\n`; message += `日主:${bazi.dayMaster}\n`; message += `明日五行:${bazi.tomorrowElement}\n`; message += `${bazi.analysis}\n\n`; message += `💡 **趋吉避凶建议**\n`; message += `✅ 宜:${bazi.suggestions?.lucky?.join('、') || '顺其自然'}\n`; message += `❌ 忌:${bazi.suggestions?.avoid?.join('、') || '谨慎行事'}\n\n`; message += `_桐哥祝您明日顺利!_ 🌟`; return message; } /** * 主函数 - 获取明日运势 */ async function getDailyHoroscope(options = {}) { const targetDate = options.date || new Date().toISOString().split('T')[0]; try { const report = await generateFortuneReport(targetDate); const message = formatFortuneMessage(report); return { success: true, report: report, message: message }; } catch (e) { console.error('运势查询失败:', e); return { success: false, error: e.message, message: '⚠️ 运势查询暂时失败,请稍后再试。' }; } } // 导出函数 module.exports = { getDailyHoroscope, generateFortuneReport, formatFortuneMessage, searchHoroscope, queryAlmanac, analyzeBazi, USER_BIRTH_INFO, ZODIAC_SIGNS }; // 测试运行 if (require.main === module) { getDailyHoroscope().then(result => { console.log('\n=== 运势报告 ===\n'); console.log(result.message); }); }