Discord Bot 8ball command shows undefined variable when trying to get random responses without message spam

I’m working on an 8ball feature for my Discord bot and running into a scope issue. I want the bot to pick different responses from an array each time someone uses the command, but I’m having trouble accessing the selected answer outside of my randomization function.

When I try to reference the chosen response in my message, it shows as undefined. I know this is because the variable is declared inside the function scope, but when I move the message sending into the randomization function, it creates a loop that spams the channel every few seconds.

Here’s what I have so far:

const Discord = require("discord.js");

module.exports = {
    name: "fortune",
    description: "Get a prediction from the mystical fortune teller.",
    execute(message, arguments){
        let userQuery = arguments.slice(1).join(" ");
        
        if (!userQuery){
          message.channel.send("Please ask the fortune teller a question first.");
          return;
        }       

      function getRandomResponse(){
        const responses = require("../data/fortune.json").responses;
        const selectedResponse = responses[Math.floor(Math.random() * responses.length)];
        return true;
      }
      setInterval(getRandomResponse, 3000);
      
      message.channel.send("**The crystal ball swirls with mysterious energy...**");
      message.channel.send(`:crystal_ball: The fortune teller reveals: "${selectedResponse}".`);
       
    }
}

How can I properly return the random selection from my function so I can use it in the message without creating an infinite loop?

Had the same issue with my first bot! Your problem is setInterval - it’s meant for repeated stuff, but you just want one random pick. Right now you’re creating a timer that fires every 3 seconds, hence the spam. Just ditch setInterval and call your function directly. Also make sure you’re returning the actual response, not just true. Quick tip: move that require statement outside the function. You’re reloading the JSON file every single time, which is pretty wasteful. Better approach: declare your responses array at the top of your module, then getRandomResponse can just return the random pick without all that file loading. Call it once, store what you get, then use that stored value in your message.

Your function’s returning true instead of the actual response, and setInterval creates a recurring timer that’s causing the spam. You need to return the selectedResponse from getRandomResponse and call it once - ditch the setInterval. Here’s the fix:

function getRandomResponse(){
  const responses = require("../data/fortune.json").responses;
  const selectedResponse = responses[Math.floor(Math.random() * responses.length)];
  return selectedResponse; // return the actual response
}

const selectedResponse = getRandomResponse(); // call it once and store result

message.channel.send("**The crystal ball swirls with mysterious energy...**");
message.channel.send(`:crystal_ball: The fortune teller reveals: "${selectedResponse}".`);

Drop the setInterval completely - you only want one response per command.

ur missing the return of selectedResponse in getRandomResponse. instead of setInterval, call that func directly to get the response. then save it to a var and send the msg, otherwise itll spam like u saw.