如何修复Discord抽奖机器人的'reactions.values(...).filter is not a function'错误?
Discord抽奖机器人随机选获奖者报错修复方案
报错信息
reactions = reactions.values().filter(user => user.id != "1268508879893958676") ^ TypeError: reactions.values(...).filter is not a function
问题原因
reactions.values()返回的是迭代器(Iterator)对象,而非数组。只有数组原生支持filter方法,迭代器没有该方法,因此调用时会触发类型错误。
修复方案
将迭代器转换为数组即可,有两种简便实现方式:
- 使用
Array.from()直接转换迭代器为数组 - 使用扩展运算符
[...iterable]展开迭代器为数组
替换报错行代码为以下任意一种:
// 方式1:Array.from reactions = Array.from(reactions.values()).filter(user => user.id !== "1268508879893958676") // 方式2:扩展运算符 reactions = [...reactions.values()].filter(user => user.id !== "1268508879893958676")
完整修正代码
额外补充了输入校验、异常处理等优化逻辑,避免后续潜在问题:
const ms = require("ms"); module.exports = { name: "giveaway", description: "Adds a giveaway.", async execute(message, args, Discord){ let channel = message.mentions.channels.first() || message.guild.channels.cache.get(args[0]) if (!channel) channel = message.channel; // 转换为数字并校验获奖者数量有效性 let winners = parseInt(args[1]) if (isNaN(winners) || winners < 1) { return message.reply("请输入有效的获奖者数量(至少1名)") } let time = args[2] let prize = args.slice(3).join(' ') // 校验时间格式有效性 time = ms(time) if (!time) { return message.reply("请输入有效的时间格式,比如 `1h`、`30m`") } const { EmbedBuilder } = require('discord.js') const embed = new EmbedBuilder() .setTitle('Giveaway!') .setDescription(`There is a new giveaway! React with "🎉" to enter.\n\`Ends in:\`${ms(time, { long: true })}\nHosted by: ${message.author}`) .setColor("#ff6600") .setTimestamp(Date.now() + time) const e = await message.channel.send({ embeds: [embed] }) e.react("🎉") setTimeout(async () => { try { let reactions = await e.reactions.cache.get("🎉").users.fetch() // 转换迭代器为数组并过滤机器人账号 reactions = [...reactions.values()].filter(user => user.id !== "1268508879893958676") // 处理无参与者情况 if (reactions.length === 0) { return message.channel.send("没有人参与这次抽奖,抽奖取消!") } // 处理获奖者数量超过参与人数的情况 if (winners > reactions.length) { winners = reactions.length } let w = [] const selectedIds = new Set() // 避免重复抽中同一用户 while (w.length < winners) { const randomIndex = Math.floor(Math.random() * reactions.length) const user = reactions[randomIndex] if (!selectedIds.has(user.id)) { selectedIds.add(user.id) w.push(user) } } message.channel.send(`${w.map(u => u.toString()).join(", ")} 赢得了 **${prize}**!`) } catch (err) { console.error(err) message.channel.send("抽奖过程中出现错误,请检查机器人权限!") } }, time) } }
优化说明
- 新增获奖者数量、时间格式的有效性校验,避免非法输入导致崩溃
- 处理无参与者、获奖者数量超过参与人数的边界情况
- 使用
Set确保同一用户不会被重复抽中 - 新增
try/catch捕获异常,便于排查权限或其他运行错误
内容的提问来源于stack exchange,提问作者Tuf Kourio
相关产品推荐
相关产品推荐

