UNPKG

fasting-tracker

Version:

Türkiye'deki şehirler için iftar ve sahur saatlerini getiren, geri sayım, canlı timer, çoklu şehir desteği ve Discord Webhook entegrasyonu sunan Node.js paketi.

213 lines (180 loc) 7.45 kB
const fetch = require("node-fetch"); const API_URL = "https://utku.berkaykoc.net/api/entertainment/fast-track"; /** * Fetches iftar and sahur times for a given city. * @param {string} city - The city name. * @returns {Promise<Object>} - Returns an object with imsak (sahur) and iftar times. */ async function getFastTrack(city) { try { if (!city || typeof city !== "string") { throw new Error("City name is required."); } const response = await fetch(`${API_URL}?city=${encodeURIComponent(city)}`); if (!response.ok) { throw new Error(`HTTP Error: ${response.status}`); } const data = await response.json(); return data; } catch (error) { throw new Error(`FastTrack API error: ${error.message}`); } } /** * Gets remaining time until iftar or sahur. * @param {string} city - The city name. * @param {string} [type="iftar"] - "imsak" or "iftar". * @returns {Promise<Object>} - Remaining time info. */ async function getCountdown(city, type = "iftar") { const times = await getFastTrack(city); if (!times[type]) { throw new Error(`Invalid time type: ${type}. Use "imsak" or "iftar".`); } const now = new Date(); const [hour, minute] = times[type].split(":").map(Number); const targetTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hour, minute, 0); const diff = targetTime - now; if (diff <= 0) { return { city: times.city || city, type, time: times[type], passed: true, message: `${type === "iftar" ? "🌅 İftar" : "🕓 Sahur"} vakti geçti.`, remaining: null, }; } const hours = Math.floor(diff / 3600000); const minutes = Math.floor((diff % 3600000) / 60000); const seconds = Math.floor((diff % 60000) / 1000); return { city: times.city || city, type, time: times[type], passed: false, remaining: { hours, minutes, seconds }, remainingText: `${hours} saat ${minutes} dakika ${seconds} saniye`, message: `${type === "iftar" ? "🌅 İftar" : "🕓 Sahur"} vaktine ${hours} saat ${minutes} dakika kaldı.`, }; } /** * Gets iftar and sahur times for multiple cities at once. * @param {string[]} cities - Array of city names. * @returns {Promise<Object[]>} - Array of time data for each city. */ async function getMultipleCities(cities) { if (!Array.isArray(cities) || cities.length === 0) { throw new Error("Please provide an array of city names."); } const results = await Promise.allSettled( cities.map(async (city) => { const data = await getFastTrack(city); return data; }) ); return results.map((result, index) => { if (result.status === "fulfilled") { return result.value; } return { city: cities[index], error: result.reason.message }; }); } /** * Gets a formatted display string for a city's fasting times. * @param {string} city - The city name. * @returns {Promise<string>} - Formatted display string. */ async function getFormattedTimes(city) { const times = await getFastTrack(city); const countdown = await getCountdown(city, "iftar"); let output = `\n🌙 ═══════════════════════════════\n`; output += ` ${(times.city || city).toUpperCase()} - Ramazan Vakitleri\n`; output += `═══════════════════════════════\n`; output += ` 🕓 Sahur (İmsak): ${times.imsak}\n`; output += ` 🌅 İftar: ${times.iftar}\n`; output += `───────────────────────────────\n`; if (!countdown.passed) { output += ` ⏳ İftara Kalan: ${countdown.remainingText}\n`; } else { output += ` ✅ İftar vakti geçti.\n`; } output += `═══════════════════════════════\n`; return output; } /** * Starts a live countdown timer in the console. * @param {string} city - The city name. * @param {string} [type="iftar"] - "imsak" or "iftar". * @param {Function} [onTick] - Optional callback for each tick. * @returns {Promise<Object>} - Returns interval ID and stop function. */ async function startLiveCountdown(city, type = "iftar", onTick = null) { const times = await getFastTrack(city); if (!times[type]) { throw new Error(`Invalid time type: ${type}`); } const [hour, minute] = times[type].split(":").map(Number); const intervalId = setInterval(() => { const now = new Date(); const targetTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hour, minute, 0); const diff = targetTime - now; if (diff <= 0) { console.log(`\n🎉 ${type === "iftar" ? "İFTAR" : "SAHUR"} VAKTİ GELDİ! - ${times.city || city}`); clearInterval(intervalId); return; } const h = Math.floor(diff / 3600000); const m = Math.floor((diff % 3600000) / 60000); const s = Math.floor((diff % 60000) / 1000); const display = `⏳ ${times.city || city} | ${type === "iftar" ? "İftar" : "Sahur"}: ${times[type]} | Kalan: ${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`; if (onTick) { onTick({ hours: h, minutes: m, seconds: s, display }); } else { process.stdout.write(`\r${display}`); } }, 1000); return { intervalId, stop: () => clearInterval(intervalId), }; } /** * Sets a reminder for iftar or sahur, with optional Discord webhook notifications. * @param {string} city - The city name. * @param {string} type - "imsak" or "iftar". * @param {number} minutesBefore - Minutes before the time to send a reminder. * @param {string} [webhookUrl] - Optional Discord webhook URL. */ async function setReminder(city, type = "iftar", minutesBefore = 10, webhookUrl = "") { const times = await getFastTrack(city); if (!times[type]) { throw new Error(`Invalid time type: ${type}`); } const now = new Date(); const [hour, minute] = times[type].split(":").map(Number); const targetTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hour, minute, 0); const reminderTime = new Date(targetTime - minutesBefore * 60 * 1000); const delay = reminderTime - now; if (delay <= 0) { throw new Error(`The specified time has already passed.`); } console.log(`✅ Reminder set for ${city} - ${type} in ${minutesBefore} minutes before (at ${reminderTime.toLocaleTimeString()}).`); setTimeout(async () => { const message = `🔔 **Hatırlatma:** ${city} için **${type.toUpperCase()}** vaktine ${minutesBefore} dakika kaldı! (${times[type]})`; console.log(message); if (webhookUrl) { try { await fetch(webhookUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ content: message }) }); console.log("✅ Notification sent to Discord webhook."); } catch (error) { console.error("❌ Failed to send Discord webhook:", error.message); } } }, delay); } module.exports = { getFastTrack, setReminder, getCountdown, getMultipleCities, getFormattedTimes, startLiveCountdown };