You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复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方法,迭代器没有该方法,因此调用时会触发类型错误。

修复方案

将迭代器转换为数组即可,有两种简便实现方式:

  1. 使用Array.from()直接转换迭代器为数组
  2. 使用扩展运算符[...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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 00:00:10