import { $ } from "bun" import dayjs from "dayjs" import "dayjs/locale/es" const TOPIC = "daily-digest" const TOKEN = process.env.NTFY_TOKEN if (!TOKEN) { console.error("ntfy token not set") process.exit(1) } const API = "https://api.frankfurter.app/latest?from=USD&to=INR" async function getUSD() { const res = await fetch(API) if (!res.ok) { throw new Error(`Exchange API failed: ${res.status}`) } const data = await res.json() const rate = data.rates.INR if (typeof rate !== "number") { throw new Error("Invalid exchange rate") } const helions = (rate / 100).toFixed(2) return `**📈 Exchange Rate** $1 = ₹${rate.toFixed(2)} = ⚙${helions} ` } async function getUsage() { // // CPU LOAD // const loadavg = await $`cat /proc/loadavg`.text() const [load1] = loadavg.trim().split(" ") // // MEMORY // const memRaw = await $`free -b`.text() const memLine = memRaw .split("\n") .find((line) => line.startsWith("Mem:")) if (!memLine) { throw new Error("Failed to parse memory info") } const [ , totalMem, usedMem, ] = memLine.trim().split(/\s+/) // // DISK // const diskRaw = await $`df -B1 /`.text() const diskLine = diskRaw .split("\n")[1] if (!diskLine) { throw new Error("Failed to parse disk info") } const [ , totalDisk, usedDisk, ] = diskLine.trim().split(/\s+/) const temp = await $`vcgencmd measure_temp`.text() const tempData = temp.split("=")[1].replace("'", "°") // // HELPERS // function formatBytesIEC(bytes: number) { const units = ["B", "KiB", "MiB", "GiB", "TiB"] let i = 0 let value = bytes while (value >= 1024 && i < units.length - 1) { value /= 1024 i++ } return `${value.toFixed(1)} ${units[i]}` } // // OUTPUT // return `**💾 Usage** • **CPU:** ${load1} • **Memory:** ${formatBytesIEC(Number(usedMem))} / ${formatBytesIEC(Number(totalMem))} • **Disk:** ${formatBytesIEC(Number(usedDisk))} / ${formatBytesIEC(Number(totalDisk))} • **Temperature:** ${tempData} ` } async function getWeather() { const res = await fetch(`https://wttr.in/Bengaluru?format="%c%C| %f | %h | %m | %w | %p"`) const data = await res.text() const [weather, temp, humidity, moon, winds, preci] = data.replace(/\"/g, '').split("|") return `**🌥️ Weather Report** • **Weather:** ${weather} • **Temperature:** ${temp} • **Humidity:** ${humidity} • **Moon Phase:** ${moon} • **Winds:** ${winds} • **Precipitation:** ${preci} ` console.log(data) } async function main() { const usd = await getUSD() const usage = await getUsage() const weather = await getWeather() const message = `Good Morning, SilicoFlare! Today is **${dayjs().format("dddd, DD MMMM YYYY")}**. Hoy es **${dayjs().locale("es").format("dddd, D [de] MMMM [de] YYYY")}**. ${weather} ${usd} ${usage} Have a great day!` const ntfy = await fetch( `https://ntfy.hy-pr.link/${TOPIC}`, { method: "POST", headers: { Authorization: `Bearer ${TOKEN}`, Title: `Daily Digest for ${dayjs().format("YYYY-MM-DD")}`, Markdown: "yes", Tags: "calendar" }, body: message, }, ) if (!ntfy.ok) { throw new Error(`ntfy failed: ${ntfy.status}`) } console.log("Notification sent at " + dayjs().format("YYYY-MM-dd HH:mm:ss")) } main().catch((err) => { console.error(err) process.exit(1) })