Discord.js v14适配:旧Math.random()服务器图标定期更换代码升级
问题描述
我正在更新一段2017/18年编写的旧Discord.js练习代码,原本通过数组和Math.random()实现定期更换服务器图标。旧代码片段如下:
function changeGuildIcon(guild) { var icons = new Array(); icons[0] = "https://cdn.glitch.com/221cf221-9488-4246-bae1-269b2e87266f%2Fquack1.jpg?1546874576807"; icons[1] = "https://cdn.glitch.com/221cf221-9488-4246-bae1-269b2e87266f%2Fquack2.png?1546874572153"; icons[2] = "https://cdn.glitch.com/221cf221-9488-4246-bae1-269b2e87266f%2Fquack3.png?1546874572398"; icons[3] = "https://cdn.glitch.com/221cf221-9488-4246-bae1-269b2e87266f%2Fquack4.png?1546874572493"; icons[4] = "https://cdn.glitch.com/221cf221-9488-4246-bae1-269b2e87266f%2Fquack5.png?1546874573152"; function shuffle(a) { var j, x, i; //var is important for (i = a.length - 1; i > 0; i--) { j = Math.floor(Math.random() * (i + 1)); x = a[i]; a[i] = a[j]; a[j] = x; } return a; } var icons_shuffle = shuffle(icons); console.log(icons_shuffle); var iconsans = icons_shuffle[icons_shuffle.length - 1]; icons_shuffle.pop(); guild.setIcon(iconsans).then(console.log).catch(console.error); } client.on("ready", () => { let guild = client.guilds.get("242786073040781322"); setInterval( changeGuildIcon, 1000 /* < milliseconds */ * 60 /* < seconds */ * 60 /* < minutes */, guild ); });
记不清当时使用的Discord.js版本,代码原本写在单个main.js文件中,与其他命令通过else if拆分。现在需要让这段代码在bot在线时自动运行,同时补充必要的前置代码使其正常生效,求相关建议。
解决方案
一、前置基础代码(适配Discord.js v14,当前主流版本)
旧代码基于Discord.js v11或更早版本,v14有较多API变更,先补全初始化代码:
// 导入Discord.js核心模块 const { Client, GatewayIntentBits } = require('discord.js'); // 导入环境变量工具(建议用单独文件存敏感信息) require('dotenv').config(); // 创建客户端实例,必须声明所需权限意图 const client = new Client({ intents: [ GatewayIntentBits.Guilds, // 必须,用于获取服务器信息 // 若需要其他功能(如消息命令),可添加对应意图 ] }); // 登录机器人,令牌从.env文件读取 client.login(process.env.DISCORD_TOKEN);
注意事项:
- 先安装依赖:
npm install discord.js dotenv - 在项目根目录创建
.env文件,内容为:DISCORD_TOKEN=你的机器人令牌
二、适配v14的图标更换代码修改
旧代码中client.guilds.get()已在v14改为client.guilds.cache.get(),同时优化写法:
function changeGuildIcon(guild) { // 用数组字面量简化声明 const icons = [ "https://cdn.glitch.com/221cf221-9488-4246-bae1-269b2e87266f%2Fquack1.jpg?1546874576807", "https://cdn.glitch.com/221cf221-9488-4246-bae1-269b2e87266f%2Fquack2.png?1546874572153", "https://cdn.glitch.com/221cf221-9488-4246-bae1-269b2e87266f%2Fquack3.png?1546874572398", "https://cdn.glitch.com/221cf221-9488-4246-bae1-269b2e87266f%2Fquack4.png?1546874572493", "https://cdn.glitch.com/221cf221-9488-4246-bae1-269b2e87266f%2Fquack5.png?1546874573152" ]; // 保留Fisher-Yates洗牌逻辑,用解构赋值简化交换 function shuffle(a) { let j, x, i; for (i = a.length - 1; i > 0; i--) { j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; } const shuffledIcons = shuffle([...icons]); // 复制原数组避免修改源数据 const selectedIcon = shuffledIcons.pop(); // 优化日志输出,明确成功/失败信息 guild.setIcon(selectedIcon) .then(() => console.log(`成功更换服务器图标:${selectedIcon}`)) .catch(err => console.error(`更换图标失败:`, err)); } client.on("ready", async () => { console.log(`已登录为 ${client.user.tag}`); // v14需从缓存中获取服务器 const guild = client.guilds.cache.get("242786073040781322"); if (!guild) { return console.error("找不到目标服务器,请检查服务器ID是否正确"); } // 机器人上线后立即执行一次更换,再启动定时任务 changeGuildIcon(guild); // 每小时执行一次(3600000毫秒) setInterval(() => changeGuildIcon(guild), 3600000); });
三、关键注意事项
- 权限要求:机器人账号必须拥有
管理服务器权限才能修改服务器图标 - 版本兼容:若坚持使用旧版本(v11),可保留
client.guilds.get(),但不推荐——旧版本已停止维护,存在安全风险 - 错误处理:新增服务器不存在的判断,避免定时任务持续报错
- 数组保护:洗牌时复制原数组,防止原数组被修改导致后续重复选取同一图标
四、整合到原有命令结构
若要和其他命令放在同一个main.js里,直接合并逻辑即可,示例:
// 前置初始化代码... // 原有命令逻辑示例 client.on("messageCreate", (message) => { if (message.content === "!ping") { message.reply("Pong!"); } else if (message.content === "!help") { message.reply("帮助信息..."); } // 其他命令... }); // 图标更换代码...
内容的提问来源于stack exchange,提问作者Jonny
相关产品推荐
相关产品推荐

