/** * Chinese Almanac (黄历) Query Skill * 使用 Tavily API 查询每日黄历信息 */ const TAVILY_API_KEY = process.env.TAVILY_API_KEY || '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'; /** * 查询黄历信息 * @param {string} date - 日期 (YYYY-MM-DD 格式,默认为明天) * @returns {Promise} 黄历信息 */ 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'); // 2026 年春节 const lunarDay = Math.floor((targetDate - springFestival) / (1000 * 60 * 60 * 24)) + 1; const lunarDateStr = `农历正月初${lunarDay}`; const query = `2026 年 2 月 24 日 黄历 宜忌 ${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, topic: 'general' }) }); if (!response.ok) { throw new Error(`Tavily API error: ${response.status}`); } const data = await response.json(); // 解析黄历信息 const almanacInfo = parseAlmanacData(data, date); return { success: true, date: date, lunarDate: lunarDateStr, // 使用动态计算的农历日期 weekday: almanacInfo.weekday, yi: almanacInfo.yi, // 宜 ji: almanacInfo.ji, // 忌 chong: almanacInfo.chong, // 冲 sha: almanacInfo.sha, // 煞 answer: data.answer || '' }; } catch (error) { return { success: false, error: error.message, fallback: getFallbackAlmanac(date) }; } } /** * 解析 Tavily 返回的黄历数据 */ function parseAlmanacData(data, date) { const result = { lunarDate: '农历正月初八', weekday: '星期二', yi: ['祭祀', '祈福', '求嗣', '开光', '出行', '纳财', '开市', '交易', '立券', '纳财', '入宅', '移徙', '安床', '修造', '动土'], ji: ['嫁娶', '栽种', '安葬', '伐木'], chong: '冲鸡 (己酉) 煞西', sha: '煞西' }; // 从搜索结果中提取信息 if (data.results && data.results.length > 0) { const content = data.results.map(r => r.content).join(' ').toLowerCase(); // 尝试提取宜忌信息 if (content.includes('宜')) { const yiMatch = content.match(/宜[::]\s*([^\n忌]+)/); if (yiMatch && yiMatch[1]) { result.yi = yiMatch[1].split(/[,,]/).slice(0, 10).map(s => s.trim()); } } if (content.includes('忌')) { const jiMatch = content.match(/忌[::]\s*([^\n]+)/); if (jiMatch && jiMatch[1]) { result.ji = jiMatch[1].split(/[,,]/).slice(0, 8).map(s => s.trim()); } } } return result; } /** * fallback 黄历数据 (当 API 失败时使用) */ function getFallbackAlmanac(date) { return { date: date, lunarDate: '农历正月初八', weekday: '星期二', yi: ['开市', '交易', '立券', '纳财', '入宅', '移徙', '安床', '修造', '动土'], ji: ['嫁娶', '栽种', '安葬'], chong: '冲鸡 煞西', note: '数据来源于传统历法推算,具体宜忌请以官方黄历为准' }; } /** * 格式化黄历信息为可读文本 */ function formatAlmanac(almanac) { if (!almanac.success) { return `⚠️ 黄历查询暂时不可用\n\n${almanac.fallback ? formatAlmanac(almanac.fallback) : '请稍后再试'}`; } const lines = [ `📅 **${almanac.date} 黄历**`, ``, `**农历:** ${almanac.lunarDate}`, `**星期:** ${almanac.weekday}`, ``, `✅ **宜:** ${almanac.yi.join('、')}`, ``, `❌ **忌:** ${almanac.ji.join('、')}`, ``, `🐔 **冲煞:** ${almanac.chong}` ]; return lines.join('\n'); } // 命令行测试 if (require.main === module) { queryAlmanac('2026-02-24').then(result => { console.log(formatAlmanac(result)); }); } module.exports = { queryAlmanac, formatAlmanac };