This commit is contained in:
Soph :3 2026-01-13 12:56:10 +02:00
parent fca2614603
commit bf09f00d45

View file

@ -1,100 +1,4 @@
import { Client, GatewayIntentBits } from "discord.js"; DISCORD_CHANNEL_ID=".."
import crypto from "crypto";
import { existsSync, readFileSync, writeFileSync } from "fs";
/* ================= CONFIG ================= */
const REFRESH_MS = Number(process.env.REFRESH_MS ?? 15_000);
const STATE_FILE = "./state.json";
/* ================= DISCORD ================= */
const client = new Client({
intents: [GatewayIntentBits.Guilds],
});
/* ================= STATE ================= */
let messageId = null;
let lastSignature = null;
if (existsSync(STATE_FILE)) {
try {
const state = JSON.parse(readFileSync(STATE_FILE, "utf8"));
messageId = state.messageId ?? null;
lastSignature = state.lastSignature ?? null;
} catch {}
}
function saveState() {
writeFileSync(
STATE_FILE,
JSON.stringify({ messageId, lastSignature }, null, 2)
);
}
/* ================= NAVIDROME AUTH ================= */
function navidromeAuth() {
const salt = crypto.randomBytes(6).toString("hex");
const token = crypto
.createHash("md5")
.update(process.env.NAVIDROME_PASS + salt)
.digest("hex");
return { salt, token };
}
function nowPlayingUrl() {
const { salt, token } = navidromeAuth();
return `${process.env.NAVIDROME_URL}/rest/getNowPlaying` +
`?u=${process.env.NAVIDROME_USER}` +
`&t=${token}&s=${salt}&f=json&v=1.16.1&c=discord-bot`;
}
function coverFetchUrl(id) {
const { salt, token } = navidromeAuth();
return `${process.env.NAVIDROME_URL}/rest/getCoverArt` +
`?u=${process.env.NAVIDROME_USER}` +
`&t=${token}&s=${salt}&v=1.16.1&c=discord-bot` +
`&id=${id}&size=96`;
}
/* ================= UTIL ================= */
function colorFromString(str) {
let hash = 0;
for (const c of str) hash = (hash << 5) - hash + c.charCodeAt(0);
return Math.abs(hash) % 0xffffff;
}
function signature(entries) {
return entries
.map(e => `${e.username}:${e.id}:${e.minutesAgo ?? 0}`)
.join("|");
}
/* ================= NAVIDROME ================= */
async function getNowPlaying() {
const res = await fetch(nowPlayingUrl());
if (!res.ok) throw new Error("Failed to fetch now playing");
const json = await res.json();
return json["subsonic-response"].nowPlaying?.entry ?? [];
}
/* ================= MESSAGE BUILD ================= */
async function buildMessage(entries) {
if (!entries.length) {
return {
embeds: [{
title: "Nothing playing",
description: "No active listeners",
color: 0x808080,
}],
files: [],
};
}
const embeds = [];
const files = [];
for (let i = 0; i < e
DISCORD_TOKEN="no.no" DISCORD_TOKEN="no.no"
LASTFM_API_KEY=no LASTFM_API_KEY=no