Node.js环境下Discord垃圾消息机器人无法按用户指定次数重复发送消息的问题求助
Hey there! Let's break down what's going wrong with your spam bot code and get it working properly. I see a few key issues that are making your loop fail entirely, plus some small improvements we can make to make the bot more reliable.
What's Breaking the Code?
1. You're not capturing the user's number input correctly
Using setTimeout and grabbing message.channel.lastMessage after 10 seconds is a flawed approach:
lastMessagecould be any message sent in the channel (not just the user's response) in that window.spamNumis a full DiscordMessageobject, not a string or number. RunningparseInt(spamNum)on an object will returnNaN—so your loop has zero iterations to run.
2. Your for loop syntax is wrong
for (i in parseInt(spamNum)) doesn't work for looping a specific number of times. The in operator iterates over object properties, not numeric counts. Even if you had a valid number here, this loop wouldn't do what you want.
3. Unsafe variable scoping
You're using undeclared variables (like spamWord) and var (which has function-level scope instead of block-level), which can lead to unexpected behavior down the line.
Fixed Code
Here's a revised version of your code that addresses all these issues:
const express = require("express"); const app = express(); app.listen(3000, () => { console.log("Project is Running!"); }) app.get("/", (req, res) => { res.send("Hello World!"); }) const Discord = require("discord.js"); const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES"] }); client.on("messageCreate", async (message) => { // Ignore bots to prevent infinite loops if (message.author.bot) return; // Spam Command if (message.content === "Spam") { await message.channel.send("I will spam the contents of the last message in this channel after 10 seconds. Then send a number to choose how many times to spam it."); const delayInMilliseconds = 10000; setTimeout(async () => { // Get the actual text content of the last message (not the full object) const spamWord = message.channel.lastMessage.content; await message.channel.send(`OK, now how many times will I spam "${spamWord}"? You have 10 seconds to send your number.`); // Use a MessageCollector to safely capture the user's response const collector = message.channel.createMessageCollector({ filter: response => !response.author.bot && !isNaN(parseInt(response.content)), time: delayInMilliseconds, max: 1 }); collector.on("collect", async (response) => { const spamNum = parseInt(response.content); // Loop the correct number of times with standard syntax for (let i = 0; i < spamNum; i++) { await message.channel.send(spamWord); // Add a small delay between messages to avoid Discord rate limits await new Promise(resolve => setTimeout(resolve, 500)); } }); collector.on("end", (collected) => { if (collected.size === 0) { message.channel.send("You didn't send a valid number in time!"); } }); }, delayInMilliseconds); } }); client.login(process.env.token);
Key Improvements Explained
- MessageCollector instead of setTimeout: This safely waits for the user's response, filters only valid numbers, and ignores bot messages to avoid chaos.
- Correct loop syntax:
for (let i = 0; i < spamNum; i++)is the standard way to loop a specific number of times. - Proper variable handling: Using
const/letfor all variables, and accessing thecontentproperty of messages (not the full object) to get actual text. - Rate limit protection: Added a small delay between spam messages to avoid hitting Discord's API rate limits (which could get your bot temporarily blocked).
- Bot ignore filter: Prevents the bot from responding to its own messages, which would cause infinite loops.
内容的提问来源于stack exchange,提问作者FrancoFan

