/** * Chinese Almanac (黄历) Query Skill * 使用 Tavily API 查询每日黄历信息 */ const TAVILY_API_KEY = process.env.TAVILY_API_KEY || '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'; /** * 查询黄历信息 */ async function queryAlmanac(date) { if (!date) { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); date = tomorrow.toISOString().split('T')[0]; } // 动态计算农历日期(基于 2026 年春节 2 月 17 日) const targetDate = date ? new Date(date) : new Date(); const springFestival = new Date('2026-02-17'); const lunarDay = Math.floor((targetDate - springFestival) / (1000 * 60 * 60 * 24)) + 1; const lunarDateStr = `农历正月初${lunarDay}`; const query = `${date} 黄历 宜忌 ${lunarDateStr}`; try { const response = await fetch('https://api.tavily.com/search', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${TAVILY_API_KEY}` }, body: JSON.stringify({ query: query, search_depth: 'basic', max_results: 5, include_answer: true }) }); if (!response.ok) { throw new Error(`Tavily API error: ${response.status}`); } const data = await response.json(); const almanacInfo = parseAlmanacData(data, date, lunarDateStr); return { success: true, date: date, lunarDate: lunarDateStr, weekday: almanacInfo.weekday, ganzhi: almanacInfo.ganzhi, yi: almanacInfo.yi, ji: almanacInfo.ji, chong: almanacInfo.chong }; } catch (error) { return { success: false, error: error.message, fallback: getFallbackAlmanac(date, lunarDateStr) }; } } /** * 解析黄历数据 */ function parseAlmanacData(data, date, lunarDateStr) { const result = { lunarDate: lunarDateStr, weekday: getWeekday(date), ganzhi: '丙午年 庚寅月 己巳日', yi: ['作灶', '解除', '平治道涂', '余事勿取'], ji: ['祈福', '安葬', '祭祀', '安门'], chong: '冲猪 煞东' }; if (data.results && data.results.length > 0) { const content = data.results.map(r => r.content).join(' '); // 解析表格格式:| 宜 | 作灶。解除。| const yiMatch = content.match(/\|\s*宜\s*\|\s*([^|]+)/); if (yiMatch) { const items = yiMatch[1].split(/[,,]/) .map(s => s.trim().replace(/[,.]/g, '')) .filter(s => s.length > 0 && s.length < 10); if (items.length > 0) result.yi = items.slice(0, 8); } const jiMatch = content.match(/\|\s*忌\s*\|\s*([^|]+)/); if (jiMatch) { const items = jiMatch[1].split(/[,,]/) .map(s => s.trim().replace(/[,.]/g, '')) .filter(s => s.length > 0 && s.length < 10); if (items.length > 0) result.ji = items.slice(0, 6); } // 冲煞 const chongMatch = content.match(/冲 ([猪狗鸡猴羊马蛇龙兔虎牛鼠]).*?煞 ([东西南北])/); if (chongMatch) { result.chong = `冲${chongMatch[1]} 煞${chongMatch[2]}`; } } return result; } /** * 获取星期 */ function getWeekday(dateStr) { const date = new Date(dateStr); const weekdays = ['日', '一', '二', '三', '四', '五', '六']; return `星期${weekdays[date.getDay()]}`; } /** * Fallback 数据 */ function getFallbackAlmanac(date, lunarDateStr) { return { success: true, date: date, lunarDate: lunarDateStr, weekday: getWeekday(date), ganzhi: '丙午年 庚寅月 己巳日', yi: ['作灶', '解除', '平治道涂', '余事勿取'], ji: ['祈福', '安葬', '祭祀', '安门'], chong: '冲猪 煞东', note: '数据来源于传统历法推算' }; } /** * 格式化输出 */ function formatAlmanac(almanac) { if (!almanac.success && !almanac.fallback) { return `⚠️ 黄历查询失败:${almanac.error}`; } const data = almanac.fallback || almanac; return [ `📅 **${data.date} 黄历**`, ``, `**农历:** ${data.lunarDate}`, `**星期:** ${data.weekday}`, `**干支:** ${data.ganzhi}`, ``, `✅ **宜:** ${data.yi.join('、')}`, ``, `❌ **忌:** ${data.ji.length > 0 ? data.ji.join('、') : '无特别禁忌'}`, ``, `🐔 **冲煞:** ${data.chong}` ].join('\n'); } // 测试 if (require.main === module) { queryAlmanac('2026-02-24').then(result => { console.log(formatAlmanac(result)); }); } module.exports = { queryAlmanac, formatAlmanac };