### Discord Bot Setup Command (JavaScript) Source: https://context7.com/minh-ton/apple-updates/llms.txt This JavaScript code defines a Discord slash command '/setup' using discord.js. It allows administrators to configure notification roles and update channels for the server. The command checks for necessary user and bot permissions before proceeding with the setup process. ```javascript const { SlashCommandBuilder } = require('@discordjs/builders'); const { PermissionFlagsBits } = require('discord.js'); module.exports = { name: 'setup', command: 'setup', category: 'Utilities', cooldown: 5, ephemeral: false, description: 'Configures the bot to your liking!', usage: '`/setup`: Configures the bot.\n`/setup role add`: Adds a notification role.\n`/setup role remove`: Removes a notification role.', data: new SlashCommandBuilder() .setName("setup") .setDescription("Configures the bot to your liking!") .addStringOption(option => option .setName("option") .setDescription("Configures notification roles") .setRequired(false) .addChoices( { name: 'role add', value: 'role add' }, { name: 'role remove', value: 'role remove' }, { name: 'role list', value: 'role list' }, )), async execute(interaction) { // Check permissions if (!interaction.member.permissions.has(PermissionFlagsBits.ManageGuild)) { return interaction.editReply( error_alert("You do not have the `MANAGE SERVER` permission to use this command!") ); } if (!interaction.guild.members.me.permissions.has([ PermissionFlagsBits.ViewChannel, PermissionFlagsBits.AddReactions, PermissionFlagsBits.UseExternalEmojis, PermissionFlagsBits.ManageMessages ])) { return interaction.editReply( error_alert("I do not have the necessary permissions to work properly! \n\n ***Please make sure I have the following permissions:*** \n- View Channels\n- Add Reactions\n- Use External Emojis\n- Manage Messages") ); } try { if (interaction.options.getString('option') != undefined && interaction.options.getString('option').includes("role")) { await setup_roles(interaction); } else { await setup_updates(interaction); } } catch (e) { console.error(e); return interaction.editReply( error_alert("An unknown error occurred while running **setup** command.", e) ); } }, }; // Example usage by server admin: // /setup // - Bot presents channel selector // - Admin selects #apple-updates channel // - Bot reacts with emoji for each update type (šŸŽ iOS, šŸ’» macOS, etc.) // - Admin reacts to emoji for desired update types // - Bot saves configuration to database ``` -------------------------------- ### Format Data Utilities: Bytes, Colors, Update Names, Thumbnails, Time Source: https://context7.com/minh-ton/apple-updates/llms.txt A collection of utility functions for formatting data, including converting bytes to human-readable strings using 'pretty-bytes', generating random colors with 'randomcolor', and creating user-friendly update names from IDs. It also includes a function to retrieve OS-specific thumbnail URLs and a function to get the current time in a specified timezone. ```javascript const pretty_bytes = require('pretty-bytes'); const randomcolor = require('randomcolor'); function formatBytes(bytes) { return pretty_bytes(bytes); } function randomColor() { return randomcolor(); } function formatUpdatesName(updateid, version, cname) { // Convert SUDocumentationID to human-readable beta name // Example: "iOS18SeedBeta3" -> "Beta 3" if (!updateid || updateid === "N/A") return "Beta"; const id_lower = updateid.toLowerCase(); if (id_lower.includes('rc')) return "Release Candidate"; if (id_lower.includes('gm')) return "GM"; if (id_lower.includes('beta1')) return "Beta 1"; if (id_lower.includes('beta2')) return "Beta 2"; if (id_lower.includes('beta3')) return "Beta 3"; if (id_lower.includes('beta4')) return "Beta 4"; if (id_lower.includes('beta5')) return "Beta 5"; if (id_lower.includes('beta6')) return "Beta 6"; if (id_lower.includes('beta7')) return "Beta 7"; if (id_lower.includes('beta8')) return "Beta 8"; // Extract number from patterns like "iOS18Seed3" -> "Beta 3" const match = updateid.match(/seed(\d+)/i); if (match) return `Beta ${match[1]}`; return "Beta"; } function getThumbnail(os) { // Returns URL to OS-specific icon hosted on GitHub Pages const base_url = "https://minh-ton.github.io/apple-updates/assets/icons/"; const os_map = { 'ios15': 'ios15.png', 'ios16': 'ios16.png', 'ios17': 'ios17.png', 'ios18': 'ios18.png', 'ipados15': 'ipados15.png', 'ipados16': 'ipados16.png', 'ipados17': 'ipados17.png', 'macos13': 'macos13.png', 'macos14': 'macos14.png', 'macos15': 'macos15.png', 'watchos10': 'watchos10.png', 'watchos11': 'watchos11.png', 'tvos': 'tvos.png', 'audioos': 'homepod.png', 'pkg': 'package.png' }; return base_url + (os_map[os.toLowerCase()] || 'apple.png'); } function getCurrentTime(timezone) { return new Date().toLocaleString('en-US', { timeZone: timezone }); } // Example usage console.log(formatBytes(7516192768)); // Output: "7.52 GB" console.log(randomColor()); // Output: "#a3e048" (random) console.log(formatUpdatesName('iOS18SeedBeta3', '18.0', 'iOS')); // Output: "Beta 3" console.log(getThumbnail('iOS18')); // Output: "https://minh-ton.github.io/.../ios18.png" ``` -------------------------------- ### Schedule Periodic Update Checks Source: https://context7.com/minh-ton/apple-updates/llms.txt Implements automated polling of Apple's servers for macOS and iOS updates at regular intervals. The `fetch_gdmf` function orchestrates the fetching of beta and public releases for various Apple operating systems. Update checks are scheduled to run every 60 seconds, while fetching macOS installer packages from XML catalogs is done every 180 seconds. ```javascript // Main update fetching orchestration async function fetch_gdmf(macos, ios, ipados, watchos, audioos, tvos) { global.BOT_STATUS = "Working"; // Beta macOS checks if (macos) { await fetch_macos_updates(audiences.macos_13_beta, devices.macos.build, devices.macos.model, devices.macos.prodtype, devices.macos.version, 'beta', true); await fetch_macos_updates(audiences.macos_14_beta, devices.macos.build, devices.macos.model, devices.macos.prodtype, devices.macos.version, 'beta', true); await fetch_macos_updates(audiences.macos_15_beta, devices.macos.build, devices.macos.model, devices.macos.prodtype, devices.macos.version, 'beta', true); } // Public macOS checks if (macos) { await fetch_macos_updates(audiences.macos_release, devices.macos.build, devices.macos.model, devices.macos.prodtype, devices.macos.version, 'public', false); } // Beta iOS checks if (ios) { await fetch_other_updates(audiences.ios_18_beta, devices.ios.build, devices.ios.model, devices.ios.prodtype, devices.ios.version, "iOS", "beta", true); await fetch_other_updates(audiences.ios_26_beta, devices.ios.build, devices.ios.model, devices.ios.prodtype, devices.ios.version, "iOS", "beta", true); } // Public iOS checks if (ios) { await fetch_other_updates(audiences.ios_release, devices.ios.build, devices.ios.model, devices.ios.prodtype, devices.ios.version, "iOS", "public", false); } global.BOT_STATUS = "Idling"; } // Schedule update checks fetch_gdmf(true, true, true, true, true, true); // Initial check on startup setInterval(() => fetch_gdmf(true, true, true, true, true, true), 60000); // Every 60 seconds // Fetch macOS installer packages from XML catalogs async function fetch_xml() { global.BOT_STATUS = "Working"; await fetch_macos_pkg(catalogs.macos_beta, true, 'beta_pkg'); await fetch_macos_pkg(catalogs.macos_public, false, 'public_pkg'); global.BOT_STATUS = "Idling"; } setInterval(() => fetch_xml(), 180000); // Every 180 seconds (3 minutes) ``` -------------------------------- ### Discord Bot Initialization and Slash Command Registration (JavaScript) Source: https://context7.com/minh-ton/apple-updates/llms.txt Initializes the Discord bot client, loads commands dynamically from the 'cmds' directory, and registers slash commands with Discord's API. It supports environment-specific configurations for beta and production releases and integrates with Firebase for backend services. Dependencies include discord.js, firebase-admin, dotenv, and discord-api-types. ```javascript require('dotenv').config(); const { Client, Collection, GatewayIntentBits, Partials } = require('discord.js'); const firebase = require("firebase-admin"); const { REST } = require('@discordjs/rest'); const { Routes } = require('discord-api-types/v10'); const fs = require("fs"); global.BETA_RELEASE = process.env.NODE_ENV != "production"; global.UPDATE_MODE = false; global.SAVE_MODE = false; // Initialize Firebase var firebase_token = (BETA_RELEASE) ? process.env.firebase_beta : process.env.firebase; var bot_token = (BETA_RELEASE) ? process.env.bot_beta_token : process.env.bot_token; firebase.initializeApp({ credential: firebase.credential.cert(JSON.parse(firebase_token)) }); // Create Discord client global.bot = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.DirectMessages, GatewayIntentBits.GuildMessageReactions ], partials: [Partials.Channel] }); global.bot.commands = new Collection(); global.bot.cooldowns = new Collection(); // Load commands dynamically const commands = fs.readdirSync('./cmds'); const command_collection = []; for (const category of commands) { const cmd_files = fs.readdirSync(`./cmds/${category}`).filter(file => file.endsWith('.js')); for (const file of cmd_files) { const command = require(`./cmds/${category}/${file}`); global.bot.commands.set(command.name, command); if (category == "owner") continue; // Skip owner commands from public registration command_collection.push(command.data.toJSON()); } } // Register slash commands const rest = new REST({ version: '10' }).setToken(bot_token); (async () => { try { if (global.BETA_RELEASE) { // Beta: Register commands to specific test server await rest.put(Routes.applicationGuildCommands(process.env.beta_id, process.env.server_id), { body: command_collection }); } else { // Production: Register commands globally await rest.put(Routes.applicationCommands(process.env.client_id), { body: command_collection }); } console.log('Successfully registered application commands.'); } catch (error) { console.error(error); } })(); global.bot.login(bot_token); global.bot.on("ready", async () => { console.log(`Logged in as ${global.bot.user.tag}!`); console.log(`Currently in ${global.bot.guilds.cache.size} servers!`); }); ``` -------------------------------- ### Fetch Non-Mac Apple OS Updates using GDMF API (JavaScript) Source: https://context7.com/minh-ton/apple-updates/llms.txt Retrieves software updates for iOS, iPadOS, watchOS, tvOS, and audioOS by making a POST request to the GDMF API. It parses the base64 encoded response to extract update details such as OS version, build, download size, and update ID. Requires the 'axios' library for HTTP requests and local JSON files for audience and device data. ```javascript async function gdmf_other(assetaud, build, hwm, prodtype, prodversion, cname, dname, beta) { const res = await axios.post('https://gdmf.apple.com/v2/assets', { AssetAudience: assetaud, CertIssuanceDay: "2020-09-29", ClientVersion: 2, AssetType: "com.apple.MobileAsset.SoftwareUpdate", BuildVersion: build, HWModelStr: hwm, ProductType: prodtype, ProductVersion: prodversion, }).catch(function (error) { return send_error(error, "gdmf.js", `fetch_other_updates - ${cname} ${dname}`, `politely asking gdmf.apple.com for updates`); }); if (!res) return send_error("No data available.", "gdmf.js", `fetch_other_updates - ${cname} ${dname}`, `politely asking gdmf.apple.com for updates`); var arr = res.data.split("."); let buff = new Buffer.from(arr[1], 'base64'); let text = JSON.parse(buff.toString('utf8')); if (!text.Assets[0]) { return send_error(`Missing text.Asset[0]`, "gdmf.js", `gdmf_other`, `update not available for ${assetaud}.`); } let os_update = { os_version: text.Assets[0].OSVersion.replace('9.9.', ''), os_build: text.Assets[0].Build, os_size: text.Assets[0]._DownloadSize, os_updateid: text.Assets[0].SUDocumentationID, os_postdate: text.PostingDate, os_raw_response: JSON.stringify(text.Assets[0]) }; return os_update; } // Example: Fetch iOS 18 Beta updates const audiences = require('./assets/audiences.json'); const devices = require('./assets/devices.json'); gdmf_other( audiences.ios_18_beta, devices.ios.build, // "22A5297f" devices.ios.model, // "D74AP" devices.ios.prodtype, // "iPhone15,3" devices.ios.version, // "17.4" "iOS", "beta", true ).then(update => { console.log(`iOS ${update.os_version} (Build ${update.os_build})`); console.log(`Download size: ${update.os_size} bytes`); }); ``` -------------------------------- ### Create Discord Update Embeds Source: https://context7.com/minh-ton/apple-updates/llms.txt Generates rich Discord embeds for macOS public releases and other beta updates. It utilizes `discord.js` for embed creation and `randomcolor` for dynamic embed colors. The functions take version, build, size, and changelog information as input and format them into visually appealing Discord messages. It also handles platform-specific thumbnails and notification logic. ```javascript const { EmbedBuilder } = require('discord.js'); const brightColor = require('randomcolor'); function send_macos_public(version, build, size, changelog) { const embed = new EmbedBuilder() .setTitle(`New macOS Public Release!`) .addFields( { name: `Version`, value: `${version}`, inline: true }, { name: `Build`, value: build, inline: true }, { name: `Size`, value: formatBytes(size), inline: true } ) .setThumbnail(getThumbnail("macOS" + version.split('.')[0])) .setDescription(changelog) .setColor(brightColor()) .setTimestamp(); send_to_servers('macos', embed, `${version} (${build})`); } function send_other_beta_updates(os, version, build, size, updateid) { const thumb = (multi_icons.includes(os.toLowerCase())) ? getThumbnail(os + version.split('.')[0]) : getThumbnail(os); const embed = new EmbedBuilder() .setTitle(`New ${os} Beta Release!`) .addFields( { name: `Version`, value: `${version} (${updateid})`, inline: true }, { name: `Build`, value: build, inline: true }, { name: `Size`, value: formatBytes(size), inline: true } ) .setThumbnail(thumb) .setColor(brightColor()) .setTimestamp(); send_to_servers(os, embed, `${version} (${updateid} - Build ${build})`); } // Example: Create and send macOS beta update notification send_macos_beta('15.2', '24C5073e', 8589934592, 'Beta 3'); // Example: Create and send iOS public release send_other_updates('iOS', '18.2', '22C65', 7516192768, '• Fix for issue causing apps to crash\n• Security updates'); ``` -------------------------------- ### Fetch macOS Updates from GDMF API (JavaScript) Source: https://context7.com/minh-ton/apple-updates/llms.txt This JavaScript function queries Apple's Global Device Management Framework (GDMF) API to retrieve information about macOS software updates. It parses a JWT-like response to extract details such as download URL, version, build number, size, and update ID. Dependencies include 'axios' for HTTP requests and local JSON files for audience and device data. ```javascript const axios = require('axios'); async function gdmf_macos(assetaud, build, hwm, prodtype, prodversion, beta) { const res = await axios.post('https://gdmf.apple.com/v2/assets', { AssetAudience: assetaud, CertIssuanceDay: "2020-09-29", ClientVersion: 2, AssetType: "com.apple.MobileAsset.MacSoftwareUpdate", BuildVersion: build, HWModelStr: hwm, ProductType: prodtype, ProductVersion: prodversion, }).catch(function (error) { return send_error(error, "gdmf.js", `gdmf_macos`, `politely asking gdmf.apple.com for updates`); }); if (!res) return send_error("No data available.", "gdmf.js", `gdmf_macos`, `politely asking gdmf.apple.com for updates`); // Parse JWT-like response (three parts separated by dots) var arr = res.data.split("."); let buff = new Buffer.from(arr[1], 'base64'); let text = JSON.parse(buff.toString('utf8')); let data = []; for (let asset in text.Assets) { let mac_update = { mac_pkg: `${text.Assets[asset].__BaseURL}${text.Assets[asset].__RelativePath}`, mac_version: text.Assets[asset].OSVersion, mac_build: text.Assets[asset].Build, mac_size: text.Assets[asset]._DownloadSize, mac_updateid: text.Assets[asset].SUDocumentationID, mac_postdate: text.PostingDate }; data.push(mac_update); } return data; } // Example usage: Fetch macOS 15 Beta updates const audiences = require('./assets/audiences.json'); const devices = require('./assets/devices.json'); gdmf_macos( audiences.macos_15_beta, devices.macos.build, // "23A339" devices.macos.model, // "Mac14,2" devices.macos.prodtype, // "Mac" devices.macos.version, // "14.0" true ).then(updates => { console.log(`Found ${updates.length} macOS updates`); updates.forEach(update => { console.log(`Version: ${update.mac_version}, Build: ${update.mac_build}`); }); }); ``` -------------------------------- ### Handle Discord Slash Command Interactions with Cooldowns (JavaScript) Source: https://context7.com/minh-ton/apple-updates/llms.txt Processes incoming slash commands from Discord users, enforcing per-user cooldowns before executing the command. It handles command not found errors, defers replies, and includes error handling for command execution. This function relies on the global 'bot' instance and the 'error_alert' helper function. ```javascript global.bot.on('interactionCreate', async interaction => { if (!interaction.isCommand()) return; if (!interaction.guildId) { return interaction.reply(error_alert(`I am unable to run this command in a DM.`)); } // Get command const cmd = global.bot.commands.get(interaction.commandName); if (!cmd) return; // Defer reply (ephemeral or public based on command settings) await interaction.deferReply({ ephemeral: (cmd.ephemeral != undefined) ? cmd.ephemeral : true }); // Command cooldowns if (interaction.member.id != process.env.owner_id) { const { cooldowns } = global.bot; if (!cooldowns.has(cmd.name)) cooldowns.set(cmd.name, new Collection()); const now = Date.now(); const timestamps = cooldowns.get(cmd.name); const amount = (cmd.cooldown || 4) * 1000; if (timestamps.has(interaction.member.id)) { const exp_time = timestamps.get(interaction.member.id) + amount; if (now < exp_time) { const remaining = (exp_time - now) / 1000; return interaction.editReply( error_alert(`I need to rest a little bit! Please wait **${remaining.toFixed(0)} more seconds** to use `${cmd.name}`!`) ); } } timestamps.set(interaction.member.id, now); setTimeout(() => timestamps.delete(interaction.member.id), amount); } // Execute command try { await cmd.execute(interaction); } catch (e) { console.error(e); await interaction.editReply(error_alert(`An unknown error occured while running `${cmd.name}`.`, e)); } }); ``` -------------------------------- ### Save Apple Package Information to Firebase Source: https://context7.com/minh-ton/apple-updates/llms.txt Saves package-specific metadata (version, build, size, package URL) to Firestore. This function is crucial for tracking individual package details for different update types (public/beta). ```javascript const firebase = require("firebase-admin"); let db = firebase.firestore(); async function save_package(cname, build, version, size, package, postdate, beta) { if (global.SAVE_MODE == false) return; const database = db.collection('other').doc('information'); const package_type = (beta) ? `${cname.toLowerCase()}_beta` : `${cname.toLowerCase()}_public`; try { await database.collection(package_type).doc(build).set({ version: version, build: build, size: size, package: package, packagesize: size, postdate: postdate, beta: beta }); console.log(`[${cname}] Saved package ${version} (${build}) to database.`); } catch (error) { send_error(error, "info.js", `save_package`, `saving ${cname} package to database`); } } ``` -------------------------------- ### Query Apple Update Information with Discord.js Source: https://context7.com/minh-ton/apple-updates/llms.txt This JavaScript code snippet defines a Discord slash command to retrieve Apple update information from a Firebase Firestore database. It handles user input for OS and version, queries both public and beta datasets, and presents results with interactive navigation buttons. Dependencies include '@discordjs/builders', 'discord.js', 'firebase-admin', and 'uniqid'. ```javascript const { SlashCommandBuilder } = require('@discordjs/builders'); const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js"); const firebase = require("firebase-admin"); const uniqid = require('uniqid'); let db = firebase.firestore(); const database = db.collection('other').doc('information'); module.exports = { name: 'update_information', command: 'update_information', category: 'Apple', description: 'Gets information about an update.', ephemeral: false, usage: '`/update_information `', data: new SlashCommandBuilder() .setName("update_information") .setDescription("Gets information about an update.") .addStringOption(option => option .setName('os') .setDescription('Specify the operating system') .setRequired(true) .addChoices( { name: 'iOS', value: 'ios' }, { name: 'iPadOS', value: 'ipados' }, { name: 'watchOS', value: 'watchos' }, { name: 'tvOS', value: 'tvos' }, { name: 'macOS', value: 'macos' }, { name: 'audioOS', value: 'audioos' } )) .addStringOption(option => option .setName('version') .setDescription("Specify the version, e.g. 14.8.1") .setRequired(true)), async execute(interaction) { const os_name = interaction.options.getString('os'); const search_query = interaction.options.getString('version'); try { // Query both public and beta databases let version_query_public = await database .collection(os_name.toLowerCase() + "_public") .where('version', '==', search_query) .get(); let version_query_beta = await database .collection(os_name.toLowerCase() + "_beta") .where('version', '==', search_query) .get(); if (version_query_public.empty && version_query_beta.empty) { return interaction.editReply(error_alert('No results found.')); } const query_data = []; if (!version_query_public.empty) { version_query_public.forEach(doc => { query_data.push(doc.data()) }); } if (!version_query_beta.empty) { version_query_beta.forEach(doc => { query_data.push(doc.data()) }); } // Create navigation buttons const next_id = uniqid('next-'); const prev_id = uniqid('prev-'); const cancel_id = uniqid('cancel-'); var index = 0; const embed = new EmbedBuilder() .setTitle(`${os_name} ${query_data[index].version}`) .addFields( { name: "Version", value: query_data[index].version, inline: true }, { name: "Build", value: query_data[index].build, inline: true }, { name: "Size", value: formatBytes(query_data[index].size), inline: true } ) .setDescription(query_data[index].changelog || "Release notes not available") .setColor(randomColor()); const row = new ActionRowBuilder().addComponents( new ButtonBuilder() .setCustomId(cancel_id) .setLabel('Done') .setStyle(ButtonStyle.Success), new ButtonBuilder() .setCustomId(next_id) .setLabel('Next') .setStyle(ButtonStyle.Primary) .setDisabled(query_data.length === 1) ); await interaction.editReply({ embeds: [embed], components: [row] }); // Set up button collector const filter = ch => { ch.deferUpdate(); return ch.member.id == interaction.member.id; }; const collector = interaction.channel.createMessageComponentCollector({ filter, time: 180000 }); collector.on('collect', async action => { if (action.customId == next_id) index++; if (action.customId == prev_id) index--; if (action.customId == cancel_id) return collector.stop(); // Update embed with new index const updated_embed = new EmbedBuilder() .setTitle(`${os_name} ${query_data[index].version}`) .addFields( { name: "Version", value: query_data[index].version, inline: true }, { name: "Build", value: query_data[index].build, inline: true }, ``` -------------------------------- ### Check macOS Updates and Prevent Duplicates in Firestore Source: https://context7.com/minh-ton/apple-updates/llms.txt Queries Firestore to check if a macOS update build already exists, preventing duplicate notifications and processing. It saves new builds to the 'macos' collection, distinguishing between 'beta' and 'public' release tracks. Dependencies include the 'firebase-admin' SDK and external functions like 'gdmf_macos', 'send_macos_beta', 'send_macos_public', and 'save_update'. ```javascript const firebase = require("firebase-admin"); let db = firebase.firestore(); async function fetch_macos_updates(assetaud, build, hwm, prodtype, prodversion, dname, beta) { // Fetch updates from Apple const updates = await gdmf_macos(assetaud, build, hwm, prodtype, prodversion, beta); if (!updates || updates.length === 0) return; const database_name = (beta) ? 'beta' : 'public'; const build_database = db.collection('macos').doc(database_name); for (let update of updates) { // Check if build already exists in database const build_doc = await build_database.collection('builds').doc(update.mac_build).get(); if (build_doc.exists) { console.log(`[macOS] Build ${update.mac_build} already exists. Skipping.`); continue; } // New build detected - save to database await build_database.collection('builds').doc(update.mac_build).set({ build: update.mac_build }); // Send notification to servers if (beta) { send_macos_beta( update.mac_version, update.mac_build, update.mac_size, update.mac_updateid ); } else { send_macos_public( update.mac_version, update.mac_build, update.mac_size, update.mac_changelog ); } // Save full update details save_update( 'macOS', update.mac_version, update.mac_size, update.mac_build, update.mac_updateid, update.mac_changelog, update.mac_postdate, update.mac_raw_response, beta ); } } // Example: Orchestrate update fetching with duplicate prevention fetch_macos_updates( audiences.macos_15_beta, devices.macos.build, devices.macos.model, devices.macos.prodtype, devices.macos.version, 'beta', true ); ``` -------------------------------- ### Broadcast OS Updates to Discord Servers (JavaScript) Source: https://context7.com/minh-ton/apple-updates/llms.txt Sends update notifications to Discord servers that have subscribed to specific update types. It utilizes Firebase Firestore to store server subscriptions and role configurations. The function constructs an embed message with server branding and optionally includes role mentions for specific OS updates. Requires 'firebase-admin' for database operations and 'discord.js' for bot interactions. ```javascript const firebase = require("firebase-admin"); let db = firebase.firestore(); const ios_database = db.collection('discord').doc('ios'); const role_database = db.collection('discord').doc('roles').collection('servers'); async function send_to_servers(os, embed, version) { if (global.UPDATE_MODE) return; switch (os.toLowerCase()) { case "ios": const ios = await ios_database.get(); const ios_guilds = ios.data(); for (let channel in ios.data()) { let chn = global.bot.channels.cache.get(ios_guilds[channel]); if (chn != undefined) { let role = await role_database.doc(channel).get(); let role_data = role.data(); let server = global.bot.guilds.cache.get(channel); // Send embed with server branding chn.send({ embeds: [embed.setAuthor({ name: server.name, iconURL: server.iconURL() })] }).catch(function (error) { send_error(error, "send.js", `send_ios`, `send ios update to channels`); }); // Send role mention if configured if (role_data != undefined && server != undefined && role_data['ios'] != undefined) { if (server.roles.cache.get(role_data['ios']) != undefined) { chn.send(`<@&${role_data['ios']}> **iOS ${version}** has been released!`) .catch(function (error) { send_error(error, "send.js", `send_ios`, `send ios roles to channels`); }); } } } } break; // Similar cases for macos, ipados, watchos, tvos, audioos, pkg, bot } } // Example: Broadcast iOS update to all subscribed servers const { EmbedBuilder } = require('discord.js'); const embed = new EmbedBuilder() .setTitle(`New iOS Public Release!`) .addFields( { name: `Version`, value: `18.2`, inline: true }, { name: `Build`, value: '22C65', inline: true }, { name: `Size`, value: '7.2 GB', inline: true } ) .setDescription('Bug fixes and security improvements') .setColor('#007AFF') .setTimestamp(); send_to_servers('ios', embed, '18.2'); ``` -------------------------------- ### Save Apple Update Metadata to Firebase Source: https://context7.com/minh-ton/apple-updates/llms.txt Persists update metadata (version, size, build, changelog, etc.) to Firestore. It prevents duplicate notifications and allows for historical tracking. The function differentiates between public and beta releases. ```javascript const firebase = require("firebase-admin"); let db = firebase.firestore(); async function save_update(cname, version, size, build, updateid, changelog, postdate, raw_response, beta) { if (global.SAVE_MODE == false) return; const database = db.collection('other').doc('information'); const update_type = (beta) ? `${cname.toLowerCase()}_beta` : `${cname.toLowerCase()}_public`; try { await database.collection(update_type).doc(build).set({ version: version, size: size, build: build, updateid: updateid, changelog: changelog, postdate: postdate, raw_response: raw_response, beta: beta }); console.log(`[${cname}] Saved ${version} (${build}) to database.`); } catch (error) { send_error(error, "info.js", `save_update`, `saving ${cname} ${version} to database`); } } // Example: Enable database saving mode and save an update global.SAVE_MODE = true; save_update( 'iOS', '18.2', 7516192768, '22C65', 'SUDocumentationID123', '• Bug fixes\n• Security improvements', new Date('2024-12-11'), '{"OSVersion":"18.2","Build":"22C65"}', false ); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.