Discord.js embed width is unreliable

Viewed 8186

I am using Discord.js library to create a discord bot. Whenever I am sending an embedded message to a text channel, its width keeps changing with different data.

const celestialObject = new MessageEmbed()
            .setColor("#F0386B")
            .setTitle(
              res.data.name == res.data.englishName
                ? res.data.englishName
                : `${res.data.englishName} (${res.data.name})`
            )
            .attachFiles(attachment)
            .setThumbnail("attachment://logo.png")

            .addFields(
              {
                name: "```Density```",
                value: res.data.density.toFixed(2) + " g/cm^3",
                inline: true,
              },
              {
                name: "```Gravity```",
                value: res.data.gravity + " m/s^2",
                inline: true,
              },
              {
                name: "```Moons```",
                value: res.data.moons ? Object.keys(res.data.moons).length : 0,
                inline: true,
              },
              {
                name: "```Mass```",
                value: `
                    ${res.data.mass.massValue.toFixed(2)}^
                    ${res.data.mass.massExponent} kgs
`,
                inline: true,
              },
              {
                name: "```Escape Velocity```",
                value: (res.data.escape / 1000).toFixed(1) + " km/s",
                inline: true,
              },
              {
                name: "```Orbital revolution```",
                value: res.data.sideralOrbit.toFixed(2) + " days",
                inline: true,
              },
              {
                name: "```Rotation speed```",
                value: (res.data.sideralRotation / 24).toFixed(2) + " days",
                inline: true,
              },
              {
                name: "```Radius```",
                value: res.data.meanRadius.toFixed(2) + " kms",
                inline: true,
              }
            )
            .setTimestamp()
            .setFooter(
              "Generated by astronomia with Solar System OpenData API",
              "https://api.le-systeme-solaire.net/assets/images/logo.png"
            );
          if (images[args[0]].description) {
            celestialObject
              .setDescription(`\`\`\` ${images[args[0]].description}\`\`\``)
              .setImage(images[args[0]].link);
          }
          if (res.data.discoveredBy) {
            celestialObject.addFields({
              name: "```Discovered By```",
              value: res.data.discoveredBy,
              inline: true,
            });
          }
          if (res.data.discoveryDate) {
            celestialObject.addFields({
              name: "```Discovered On```",
              value: res.data.discoveryDate,
              inline: true,
            });
          }
          message.channel.send(celestialObject);

With this code I'm getting following results.

Here width of embed is more. enter image description here

Here width of embed is less. enter image description here

How can I get maximum width every time? I looked into discord.js documentation and couldn't find anything.

3 Answers

Its happening because of the code blocks you have used its weird because I've noticed that as well, not sure why it happening though.

If you want to stop your lines from breaking -

   {
     name: "```Orbital \n revolution```",
     value: res.data.sideralOrbit.toFixed(2) + " days",
     inline: true,
   }

\n breaks the line I've used spaces around it so that its more clear in you code you can use Orbital \nrevolution

One tricks that I use to force the width:

embed.setFooter("\u3000".repeat(10/*any big number works too*/)+"|")

This code basically sets a lot of spaces as the footer, forcing discord to make width for it. \u3000 is the unicode for the "IDEOGRAPHIC SPACE", which is a space character. (You can't use normal spaces as discord only reads the first one.)

Another possible way can be to insert a 1px x some large value transparent image (you can generate one from here) in the message. I haven't used DiscordJS, but in simple webhook format it will be something like:

const embed = { // ...
  image: {
    url: 'https://i.stack.imgur.com/Fzh0w.png'
  }
}

While developing the bot, you can use some free service like Discohook to visually test what your message will look like.

Benefits of using this workaround over the one suggested by chan kelvin are:

  1. You need not to worry about other text on footer like timestamp.
  2. If you don't add the spaces to the footer, instead to the description itself, then it will also do the above, but will look somewhat odd because of the more height (16px vs 1px + some padding).
    • Note that if you try creating fixed-width title/author name, then the space will also be hyperlinked (+ underlined).

Drawback: On mobile client, even the transparent image is slightly visible! :/

PS:

  1. You need to modify the method given by chan to use \u2800 (Braille Pattern Blank) instead of ideographic space, as the latter one is now discarded by Discord.
  2. You can use my method even if you have added other image in the embed. Discord permits adding up to 4 images per embed if its URL is set.
Related