diff options
| author | hachem <im@hachem.wtf> | 2025-11-23 05:01:11 +0100 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2025-11-23 05:01:11 +0100 |
| commit | 9010ed1f600413465468b824036cff471d3972c1 (patch) | |
| tree | e96a3705d9a5f554eea46dc01d17509fa080476b | |
| parent | db64493f5d66ea2912f099bf971ff6ffd9b6895c (diff) | |
[add]: i spent way too much time on this stupid bot omg
| -rw-r--r-- | bot/app.js | 280 | ||||
| -rw-r--r-- | config/config.json | 2 |
2 files changed, 143 insertions, 139 deletions
@@ -1,8 +1,8 @@ const { - Client, - Events, - GatewayIntentBits + Client, + Events, + GatewayIntentBits } = require("discord.js") const axios = require("axios") @@ -14,190 +14,194 @@ const api = require("../config/api.json") const { - channel_id, - minecraft_version, - modrinth_mods + channel_id, + check_interval_minutes, + minecraft_version, + fabric_loader_version, + loader_meta_version, + modrinth_mods } = config -const -{ - token -} = api +const { token } = api const cacheFile = path.join(__dirname, "../cache/mod_versions.json") - const client = new Client ({ - intents: [GatewayIntentBits.Guilds] + intents: + [ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildMessages + ] }) const LoadCache = async () => { - try - { - if (await fs.pathExists(cacheFile)) - return JSON.parse(await fs.readFile(cacheFile, "utf8")) - } - catch (err) - { - console.error("[Cache] Failed to read cache:", err) - } - return {} + try + { + if (await fs.pathExists(cacheFile)) + return JSON.parse(await fs.readFile(cacheFile, "utf8")) + } + catch (err) + { + console.error("[Cache] Failed to load:", err) + } + return {} } const SaveCache = async cache => { - try - { - await fs.ensureDir(path.dirname(cacheFile)) - await fs.writeFile(cacheFile, JSON.stringify(cache, null, 2)) - } - catch (err) - { - console.error("[Cache] Failed to save cache:", err) - } + try + { + await fs.ensureDir(path.dirname(cacheFile)) + await fs.writeFile(cacheFile, JSON.stringify(cache, null, 2)) + } + catch (err) + { + console.error("[Cache] Failed to save:", err) + } } -const GetModrinthData = async slug => +const GetModVersions = async slug => { - try - { - const r = await axios.get(`https://api.modrinth.com/v2/project/${slug}/version`) - return r.data - } - catch (err) - { - console.error(`[Modrinth] Failed for ${slug}:`, err.message) - return null - } + try + { + const response = await axios.get(`https://api.modrinth.com/v2/project/${slug}/version`) + return response.data + } + catch (err) + { + console.error(`[Modrinth] Failed for ${slug}:`, err.message) + return null + } } const CheckMods = async () => { - const cache = await LoadCache() - const newCache = { ...cache } + const cache = await LoadCache() + const newCache = { ...cache } - const updatedNotCompatible = [] - const newlyCompatible = [] - const compatibleUpdated = [] + const noCompatible = [] + const newlyCompatible = [] + const stillCompatibleUpdate = [] - for (const slug of modrinth_mods) - { - const versions = await GetModrinthData(slug) - if (!versions) - continue - - const fabric = versions.filter(v => v.loaders.includes("fabric")) - if (!fabric.length) - continue + for (const slug of modrinth_mods) + { + const versions = await GetModVersions(slug) + if (!versions) + continue - const latest = fabric.sort((a, b) => - new Date(b.date_published) - new Date(a.date_published) - )[0] + const latest = versions.sort((a, b) => new Date(b.date_published) - new Date(a.date_published))[0] + const compatible = versions.find(v => v.game_versions.includes(minecraft_version)) || null - const latestId = latest.id - const compatible = latest.game_versions.includes(minecraft_version) - const cachedId = cache[slug] + const cached = cache[slug] || + { + compatible: null, + latest: null + } - if (!cachedId) - newCache[slug] = latestId + newCache[slug] = + { + compatible: compatible ? compatible.id : null, + latest: latest.id + } - if (latestId === cachedId) - continue + if (!compatible) + { + noCompatible.push(slug) + continue + } - const previouslyCompatible = fabric.some(v => - v.id === cachedId && v.game_versions.includes(minecraft_version) - ) + if (!cached.compatible && compatible) + { + newlyCompatible.push(slug) + continue + } - if (!compatible) - updatedNotCompatible.push(slug) - else if (compatible && !previouslyCompatible) - newlyCompatible.push(slug) - else if (compatible && previouslyCompatible) - compatibleUpdated.push(slug) + if (latest.id !== cached.latest) + stillCompatibleUpdate.push(slug) + } - newCache[slug] = latestId - } + await SaveCache(newCache) - await SaveCache(newCache) - return { updatedNotCompatible, newlyCompatible, compatibleUpdated } + return { noCompatible, newlyCompatible, stillCompatibleUpdate } } -const SendUpdate = async (channel, updatedNotCompatible, newlyCompatible, compatibleUpdated) => +const SendUpdate = async (channel, noCompatible, newlyCompatible, stillCompatibleUpdate) => { - if (!updatedNotCompatible.length && !newlyCompatible.length && !compatibleUpdated.length) - return + if (!noCompatible.length && !newlyCompatible.length && !stillCompatibleUpdate.length) + return - let msg = `**Modrinth Update Check — ${minecraft_version}**\n\n` + let msg = `**Modrinth Compatibility — ${minecraft_version}**\n\n` - if (updatedNotCompatible.length) - { - msg += `**❗ Updated but NOT compatible:**\n` - for (const s of updatedNotCompatible) - msg += `❗ ${s}\n` - msg += `\n` - } - - if (newlyCompatible.length) - { - msg += `**🎉 NOW Compatible:**\n` - for (const s of newlyCompatible) - msg += `🎉 ${s}\n` - msg += `\n` - } + if (noCompatible.length) + { + msg += `**❌ No compatible version available:**\n` + for (const slug of noCompatible) + msg += `❌ ${slug}\n` + msg += `\n` + } - if (compatibleUpdated.length) - { - msg += `**🟢 Updated (still compatible):**\n` - for (const s of compatibleUpdated) - msg += `🟢 ${s}\n` - msg += `\n` - } + if (newlyCompatible.length) + { + msg += `**🎉 Now Compatible:**\n` + for (const slug of newlyCompatible) + msg += `🎉 ${slug}\n` + msg += `\n` + } - await channel.send - ({ - content: msg, - allowedMentions: + if (stillCompatibleUpdate.length) { - parse: [] - }, - flags: 4 - }) + msg += `**🟢 Updated (still compatible):**\n` + for (const slug of stillCompatibleUpdate) + msg += `🟢 ${slug}\n` + msg += `\n` + } - console.log("[Discord] Sent update.") + await channel.send + ({ + content: msg, + allowedMentions: { parse: [] } + }) + + console.log("[Discord] Update message sent.") } client.once(Events.ClientReady, async c => { - console.log(`[OK] Logged in as ${c.user.tag}`) - - const channel = await client.channels.fetch(channel_id).catch(() => null) - if (!channel) - { - console.error("Invalid channel_id:", channel_id) - return - } - - const - { - updatedNotCompatible, - newlyCompatible, - compatibleUpdated - } = await CheckMods() + console.log(`[OK] Logged in as ${c.user.tag}`) - await SendUpdate(channel, updatedNotCompatible, newlyCompatible, compatibleUpdated) + let channel = null + try + { + channel = await client.channels.fetch(channel_id) + console.log("Fetched channel:", channel.name, "type:", channel.type) + } + catch + { + console.error("❌ Failed to fetch channel:", channel_id) + return + } - setInterval(async () => - { const { - updatedNotCompatible, - newlyCompatible, - compatibleUpdated + noCompatible, + newlyCompatible, + stillCompatibleUpdate } = await CheckMods() - await SendUpdate(channel, updatedNotCompatible, newlyCompatible, compatibleUpdated) - }, 60 * 60 * 1000) + await SendUpdate(channel, noCompatible, newlyCompatible, stillCompatibleUpdate) + + setInterval(async () => + { + const + { + noCompatible, + newlyCompatible, + stillCompatibleUpdate + } = await CheckMods() + + await SendUpdate(channel, noCompatible, newlyCompatible, stillCompatibleUpdate) + }, check_interval_minutes * 60 * 1000) }) -client.login(token) +client.login(token)
\ No newline at end of file diff --git a/config/config.json b/config/config.json index 3cde6d7..6db2f86 100644 --- a/config/config.json +++ b/config/config.json @@ -1,5 +1,5 @@ { - "channel_id": "1426917156032876635", + "channel_id": "[channel]", "check_interval_minutes": 60, "minecraft_version": "1.21.10", "fabric_loader_version": "0.17.3", |
