Problem with either nested functions or quote marks?

Hi there, I’ve been lurking in the forums to find answers to my problems, but this one has me completely stumped.

I’m making an Undertale-inspired !mercy command, I’m trying to get Nightbot to respond to a command with three potential outcomes:

  1. if $(user)==$(touser), a brief message (you can’t spare yourself), else…
  2. generate a number between 1 and 10. if(x<10) then poll pastebin for a random “idle” response, else (if x=10 then),
  3. a rare “YOU WON! You got 0 XP and (random number) gold.” message (1/10 chance to appear)

So basically, if the user doesn’t add an argument after the command, they’ll get response 1. But if they do, then theoretically, 9/10 times they’ll get response 2, or 1/10 times response 3.

I am able to get responses 1 and 2 work if I omit the 3rd option, like this:
* $(eval if("$(user)"=="$(touser)"){"$(user) tried to spare themself. But nothing happened."}else{"$(touser)"+"$(eval a="$(urlfetch json".split("#");a[Math.floor(Math.random()*a.length)])"})

I’m also able to make it choose between responses 2 and 3 in isolation:
* $(eval var b=(Math.floor(Math.random()*11));if(b<10){"$(touser)"+"$(eval a="$(urlfetch json".split("#");a[Math.floor(Math.random()*a.length)])"}else{"YOU WON! $(user) earned 0 XP and "+(Math.ceil(Math.random()*100))+" gold."})

However, when I put it all together and try !mercy Nightbot, I get either Unexpected token ')' or missing ) after argument list, OR it just displays raw code like:
* Nightbot$(urlfetch json

I’ve tried using single vs. double quotes, and using if/else in different ways, but I just can’t get it to do what I want. Here’s what I’m currently working with:
* $(eval if('$(user)'=='$(touser)'){'$(user) tried to spare themself. But nothing happened.'}else{"$(eval var x=Math.ceil(Math.random()*10);if(x<10){$(touser)$(eval a='$(urlfetch json'.split('#');a[Math.floor(Math.random()*a.length)])}else{'YOU WON! $(user) earned 0 XP and '+(Math.ceil(Math.random()*100))+' gold.'})"})

Any help would be greatly appreciated! I feel like I’m very close to getting it, but not quite there. Thank you!

Hey @jpegnight!

You identified the issue properly: you reached the nesting limit! Basically, you use way too many $(eval), you only need one.

Here’s how I’d write your code:

const idleResponses = `$(urlfetch json`.split(`#`);
// $(urlfetch) isn't a native JS function, this is just for the example
const randomOutcome = Math.ceil(Math.random() * 10);
const goldAmount = Math.ceil(Math.random() * 100);
// the line above will generate a random number between 1 and 100 included
// if you'd rather generate a number between 0 and 100 included, use:
// Math.floor(Math.random() * 101)

if ('$(user)' === '$(touser)') {
  return '$(user) tried to spare themself. But nothing happened.';

if(randomOutcome === 10) {
  return `YOU WON! $(user) earned 0 XP and ${goldAmount} gold.`;

return '$(touser) ' + idleResponses[Math.floor(Math.random() * idleResponses.length)];

First I assign all the variables I’ll need, then I do the tests to get the right output.

So the Nightbot version is this:

$(eval i=`$(urlfetch json`.split(`#`);r=Math.ceil(Math.random()*10);g=Math.ceil(Math.random()*100);if(`$(user)`==`$(touser)`){`$(user) tried to spare themself. But nothing happened.`}else{if(r==10){`YOU WON! $(user) earned 0 XP and ${g} gold.`}else{`$(touser)${i[Math.floor(Math.random()*i.length)]}`}})

You may notice I also switched from single quotation marks to backticks, that’s because un-escaped single quotation marks in your Pastebin break the code, and backticks are a good way to go around that, they allow me to foolproof the code a bit, and I wanted to remain consitstent.

1 Like

Brilliant, it works! Thank you so, so much. I don’t know javascript, so I don’t know what’s native or not, and a lot of this has been a brute-force approach. I’m learning a lot though, and I’m sure what I’ve learned from your response will be very helpful for making future commands. Your code is more dynamic, cleaner, and shorter. Cheers!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.