#!/usr/bin/env node /** * 每日运势推送 - 简化版 * * 功能: * 1. 使用 Tavily 搜索星座运势 * 2. 查询黄历信息 * 3. 生成运势报告 * 4. 通过 Telegram 发送 * * 用户信息: * - 王院长 * - 生日:1984 年 5 月 16 日 23:00-24:00 (子时) * - 星座:金牛座 * - 生肖:鼠 */ const https = require('https'); const http = require('http'); // 配置 const CONFIG = { tavilyApiKey: process.env.TAVILY_API_KEY || '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', telegramBotToken: process.env.TELEGRAM_BOT_TOKEN || '7047245486:AAF504oCHZpfEIx3-3VXJYSSS9XelkV6o3g', telegramChatId: '5237946060', // 王院长的 Telegram ID timezone: 'Asia/Shanghai' }; // 用户信息 const USER = { name: '王院长', birthday: '1984-05-16', birthTime: '23:00-24:00 (子时)', zodiac: '金牛座', chineseZodiac: '鼠' }; /** * Tavily 搜索 */ async function tavilySearch(query, searchDepth = 'basic') { return new Promise((resolve, reject) => { const postData = JSON.stringify({ query: query, search_depth: searchDepth, include_answer: true, max_results: 3 }); const options = { hostname: 'api.tavily.com', port: 443, path: '/search', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData), 'Authorization': `Bearer ${CONFIG.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(); }); } /** * 查询黄历 (使用 web 接口) */ async function queryAlmanac(date) { // 这里可以使用在线黄历 API 或网页抓取 // 简化版:返回基础信息 const d = new Date(date); const lunarMonths = ['正月','二月','三月','四月','五月','六月','七月','八月','九月','十月','冬月','腊月']; const lunarMonth = lunarMonths[d.getMonth()]; const lunarDay = d.getDate(); return { success: true, date: date, lunarDate: `农历${lunarMonth}${getLunarDay(lunarDay)}`, yi: ['开市', '交易', '纳财', '安床'], // 简化版,实际应该查询真实黄历 ji: ['嫁娶', '栽种', '安葬'], chong: '冲鸡 煞西' }; } function getLunarDay(day) { const days = ['初一','初二','初三','初四','初五','初六','初七','初八','初九','初十', '十一','十二','十三','十四','十五','十六','十七','十八','十九','二十', '廿一','廿二','廿三','廿四','廿五','廿六','廿七','廿八','廿九','三十']; return days[day - 1] || '未知'; } /** * 八字分析 (简化版) */ function analyzeBazi(date, userBirthday) { const d = new Date(date); const dayOfWeek = d.getDay(); const elements = ['金', '木', '水', '火', '土']; const tomorrowElement = elements[dayOfWeek % 5]; // 修正:确保索引在 0-4 范围内 // 简化的五行分析 const analysis = { '金': '金旺之日,适合决断和执行', '木': '木旺之日,适合学习和规划', '水': '水旺之日,适合沟通和交流', '火': '火旺之日,适合展示和表达', '土': '土旺之日,适合稳定和积累' }; const suggestions = { '金': { lucky: ['签署合同', '做决策', '执行计划'], avoid: ['犹豫不决', '拖延'] }, '木': { lucky: ['学习新知', '制定计划', '拜访贵人'], avoid: ['冲动行事', '独自决策'] }, '水': { lucky: ['商务谈判', '团队合作', '社交活动'], avoid: ['与人争执', '情绪化'] }, '火': { lucky: ['演讲展示', '创意工作', '运动健身'], avoid: ['与人冲突', '过度消费'] }, '土': { lucky: ['整理归纳', '储蓄理财', '陪伴家人'], avoid: ['冒险投资', '大额支出'] } }; return { element: tomorrowElement, analysis: analysis[tomorrowElement], suggestions: suggestions[tomorrowElement] }; } /** * 生成运势报告 */ async function generateFortuneReport() { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); const dateStr = tomorrow.toISOString().split('T')[0]; console.log(`[INFO] 开始生成 ${dateStr} 的运势报告...`); // 1. 搜索星座运势 let horoscopeText = ''; try { const horoscopeResult = await tavilySearch(`${dateStr} ${USER.zodiac} 运势 星座运程`, 'basic'); if (horoscopeResult.answer) { horoscopeText = horoscopeResult.answer; } else if (horoscopeResult.results && horoscopeResult.results.length > 0) { horoscopeText = horoscopeResult.results[0].content; } else { horoscopeText = `${USER.zodiac}明日运势平稳,保持积极心态。`; } } catch (e) { console.error('[ERROR] 星座运势搜索失败:', e.message); horoscopeText = `${USER.zodiac}明日运势平稳。`; } // 2. 查询黄历 let almanac = {}; try { almanac = await queryAlmanac(dateStr); } catch (e) { console.error('[ERROR] 黄历查询失败:', e.message); almanac = { lunarDate: '查询中', yi: ['待查询'], ji: ['待查询'], chong: '' }; } // 3. 八字分析 const bazi = analyzeBazi(dateStr, USER.birthday); // 4. 生成报告 const report = { date: dateStr, user: USER.name, zodiac: USER.zodiac, chineseZodiac: USER.chineseZodiac, almanac: almanac, horoscope: horoscopeText, bazi: bazi }; return report; } /** * 格式化消息 */ function formatMessage(report) { const { date, user, zodiac, chineseZodiac, almanac, horoscope, bazi } = report; let message = `🌙 桐哥的每日运势提醒\n\n`; message += `📅 明日:${date}\n`; message += `♉ 星座:${zodiac}\n`; message += `🐭 生肖:${chineseZodiac}\n\n`; message += `✨ **星座运势**\n`; message += `${horoscope}\n\n`; message += `🏮 **黄历信息**\n`; message += `${almanac.lunarDate}\n`; message += `宜:${almanac.yi?.join('、') || '待查询'}\n`; message += `忌:${almanac.ji?.join('、') || '待查询'}\n`; if (almanac.chong) { message += `冲煞:${almanac.chong}\n`; } message += `\n`; message += `🔮 **五行分析**\n`; message += `明日五行:${bazi.element}\n`; message += `${bazi.analysis}\n\n`; message += `🎯 **趋吉避凶**\n`; message += `✅ 宜:${bazi.suggestions?.lucky?.join('、') || '顺其自然'}\n`; message += `❌ 忌:${bazi.suggestions?.avoid?.join('、') || '谨慎行事'}\n\n`; message += `_桐哥祝您明日顺心如意!_ ❤️`; return message; } /** * 发送 Telegram 消息 */ async function sendTelegramMessage(message) { return new Promise((resolve, reject) => { const postData = JSON.stringify({ chat_id: CONFIG.telegramChatId, text: message, parse_mode: 'Markdown' }); const options = { hostname: 'api.telegram.org', port: 443, path: `/bot${CONFIG.telegramBotToken}/sendMessage`, method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) } }; const req = https.request(options, (res) => { let data = ''; res.on('data', (chunk) => data += chunk); res.on('end', () => { try { const result = JSON.parse(data); if (result.ok) { console.log('[INFO] Telegram 消息发送成功'); resolve(result); } else { console.error('[ERROR] Telegram API 错误:', result); reject(new Error(result.description)); } } catch (e) { reject(e); } }); }); req.on('error', reject); req.write(postData); req.end(); }); } /** * 主函数 */ async function main() { try { console.log('[INFO] 开始执行每日运势推送...'); // 生成报告 const report = await generateFortuneReport(); console.log('[INFO] 运势报告生成完成'); // 格式化消息 const message = formatMessage(report); console.log('[INFO] 消息格式化完成'); // 发送消息 await sendTelegramMessage(message); console.log('[INFO] 消息发送完成'); console.log('\n=== 运势报告预览 ===\n'); console.log(message); } catch (error) { console.error('[FATAL] 执行失败:', error); process.exit(1); } } // 执行 if (require.main === module) { main(); } module.exports = { main, generateFortuneReport, formatMessage, sendTelegramMessage };