Discord.js 机器人广播命令无法生成embed 多种写法均无效
当前实现的核心逻辑错误
- 空内容校验完全失效:代码写的判断条件是
args.length < 0,数组长度的取值范围是0到正无穷,不可能小于0,这个分支永远不会被触发,哪怕用户输入为空,校验逻辑也直接跳过 - 内嵌消息的触发条件永远不成立:代码写的判断是当args数组第一个元素是"sayembed"时才发embed,但主流的Discord命令框架在解析消息时,会自动把匹配到的命令名(包括主命令、bc/broadcast这类别名)从参数列表中剥离,不会放进args数组。也就是说用户输入
!sayembed 测试内容时,args里的第一个元素是“测试内容”,根本不会出现“sayembed”这个字符串,这个if分支永远进不去,所有输入都会走else逻辑发普通文本,自然看不到embed效果 - 旧写法失效的原因:
richembed是discord.js v12之前的旧类名,v12版本之后官方就移除了RichEmbed,所有内嵌消息都统一通过MessageEmbed类实现discord.messageembed这类写法是导入逻辑错误,MessageEmbed是需要从discord.js模块解构出来的构造类,不是直接挂载在discord模块对象上的小写属性
- 兼容性问题:如果使用的是discord.js v14及以上版本,原有的
message.member.hasPermission()方法已经被官方移除,替换为message.member.permissions.has(),直接调用老方法会直接抛错;同时无异常捕获的message.delete(),在机器人没有管理消息权限时,会抛出未捕获的Promise异常打断整个命令流程
修正后的可运行代码
const { MessageEmbed, PermissionsBitField } = require("discord.js"); module.exports = { name: "sayembed", aliases: ["bc", "broadcast"], description: "通过机器人发送embed格式广播", usage: "<广播内容>", run: (client, message, args) => { // 删除用户发送的原命令,添加异常捕获避免权限不足报错 message.delete().catch(() => {}); // 适配新版discord.js的权限校验逻辑 if (!message.member.permissions.has(PermissionsBitField.Flags.ManageMessages)) return message.reply("你没有使用该命令的所需权限").then(m => m.delete(5000)); // 修正空内容判断:数组长度不可能小于0,判断条件应为长度等于0 if (args.length === 0) return message.reply("请输入需要广播的内容").then(m => m.delete(5000)); // 直接构建embed对象,无需额外判断参数前缀 const broadcastText = args.join(" "); const embed = new MessageEmbed() .setDescription(broadcastText) .setColor("Random") .setTimestamp(); // 适配新版discord.js的embed发送格式 message.channel.send({ embeds: [embed] }); } }
高频踩坑注意事项
- discord.js v13及以上版本,不能直接把MessageEmbed实例作为
channel.send()的参数传入,必须将实例放在embeds属性的数组里,否则会报参数格式错误 - 命令框架的参数解析规则:触发命令使用的主名、别名本身不会被计入args数组,因此不需要在代码内判断args首个元素是否为命令名
- 不要再使用已经废弃的旧API:
richembed、直接传embed到send方法、旧版权限判断方法,这些在当前主流版本的discord.js里都已经被移除
内容的提问来源于stack exchange,提问作者Szymek
相关产品推荐
相关产品推荐

