1

I've been searching throughout Stack Overflow for answers, but I can't find a way to get a message by its id in multiple channels.

Basically, I'm trying to make a reaction role command using Discord.JS v14, but I can't be guaranteed that everyone who uses the bot is going to use it in the same channel the message is in. I've tried using .forEach() but it doesn't work.

Here's my code:

const {
  SlashCommandBuilder,
  PermissionFlagsBits,
  EmbedBuilder,
} = require("discord.js");
const { enabled, disabled } = require("../../../config.json");
const Settings = require("../../schemas/settings");
const mongoose = require("mongoose");
const Reaction = require("../../schemas/reactionRole");

module.exports = {
  name: "reaction",
  description: ``,
  category: "Utility",
  data: new SlashCommandBuilder()
    .setName(`reaction`)
    .setDescription(`Modify or setup reaction roles in your server!`)
    .setDefaultMemberPermissions(PermissionFlagsBits.ManageRoles)
    .addSubcommand((subcommand) =>
      subcommand
        .setName(`setup`)
        .setDescription(`Setup reaction roles in your server`)
        .addRoleOption((option) =>
          option
            .setName("role")
            .setDescription(`Specify a role you want to use`)
            .setRequired(true)
        )
        .addStringOption((option) =>
          option
            .setName("message-id")
            .setDescription(`Enter the message's id`)
            .setRequired(true)
        )
        .addStringOption((option) =>
          option
            .setName(`emoji`)
            .setDescription(`Specify the emoji's id`)
            .setRequired(true)
        )
    ),
  async execute(interaction, client) {
    switch (interaction.options.getSubcommand()) {
      case `setup`:
        const role = interaction.options.getRole(`role`);
        const msg = interaction.options.getString(`message`);
        const emoj = interaction.options.getString(`emoji`);
        const emoji = client.emojis.cache.get(emoj);
        const message = interaction.channel.messages.fetch(msg) //How can I replace this?

        const notEmoji = new EmbedBuilder()
          .setTitle(`Invalid Emoji Specified`)
          .setColor(`Red`)
          .setDescription(`The emoji id you specified is not valid`)
          .addFields({
            name: `How to get emoji id:`,
            value: `To get an emoji's id, you first type it as usual:\n:smile:\nTo get it's id, you add a backslash (\\) to it, as such: \:smile:\nThe number is what you use as the id.`,
          });

          const notMessage = new EmbedBuilder()
          .setTitle(`Invalid Message Specified`)
          .setColor(`Red`)
          .setDescription(`The message id you specified is not valid`)
          .addFields({
            name: `How to get message id:`,
            value: `To get a message's id, you hover over it whilst clicking shift, then a number of icons will appear, click on the ID icon to copy the id of the message`,
          });

        if (!message) return interaction.reply({ embeds: [notMessage] });

      
        
        const m = await interaction.channel.messages.fetch(message); //How can I replace this?
        m.react(emoji);

        await new Reaction({
          _id: mongoose.Types.ObjectId(),
          guildId: interaction.guild.id,
          messageId: message.id,
          emojiId: emoji.id,
          roleId: role.id,
        });

        break;

      default:
        break;
    }
  },
};
Refluent
  • 93
  • 8
  • Does this answer your question? [Get Message By ID: Discord.js](https://stackoverflow.com/questions/49442638/get-message-by-id-discord-js) – Michael M. Oct 26 '22 at 03:47
  • @MichaelM. This is for a single channel. OP wants to find it in multiple channels. – kelsny Oct 26 '22 at 04:20
  • 2
    I don't think this is feasible since messages can have *the same* ID across channels + how would you even start? Which channels would you search first? Do we know all the channels the message could be in? – kelsny Oct 26 '22 at 04:21
  • Oh, I didn't know that they could have the same ID across multiple channels. Thanks @caTS – Refluent Oct 26 '22 at 04:47
  • 1
    @caTS Why do you think that IDs are not unique? Why would messages have the same ID if they use [snowflakes](https://discord.com/developers/docs/reference#snowflakes)? However, I don't think there is a way to get a message by its ID if you don't know the channel. – Zsolt Meszaros Oct 26 '22 at 06:42
  • 1
    @ZsoltMeszaros Discord is already almost running out of user ids. They are planning to add another digit to ids (if they have not done so already). Also, there are literally billions of new messages daily... And back in the old days, message ids were actually channel ids with the message id with a hypen in between. I think it is safe to say that IDs are not unique across channels. – kelsny Oct 26 '22 at 12:44
  • 2
    @caTS Where is this info coming from? The snowflake IDs that Zsolt mentioned have 42 bits reserved for a millisecond timestamp. Which holds up to ~140 years of milliseconds (starting from 2015-01-01). This timestamp is combined with a worker, PID, and an increment. If there was only one worker with a single PID this gives snowflakes room to generate a max of 4095 ids each millisecond. By adding additional processes and workers they can further scale this number, to a max of 4194303 IDs each millisecond. – 3limin4t0r Oct 27 '22 at 16:59

1 Answers1

1

People in the comments have mentioned that this is not possible, however, I have been experimenting with Discord IDs lately and found that it is possible. A user can copy a message's ID by pressing the Shift key on their keyboard, hovering over a message, and clicking on the ID icon. This way, the copied ID contains two parts, something similar to this: 123456789123456789-123456789123456789.

The first part of the ID is actually the channel's ID, in which the message has been sent, whereas the second part is the message's ID. The only downside to this is that this is only the case for users copying a message's ID, but not a bot. The bot will simply just receive the second part.

However, since my case only needs the user to copy the message ID, I think I could do something like this:

const args = msg.split(`-`); // Splitting the string into an array

const channelId = args[0]; // The first element of the array
const messageId = args[1]; // The second element of the array

const m = await client.channels.cache
.get(channelId)
.messages.fetch(messageId); // Searching the client for the channel, and the message in that channel
// Code below

Please note, when you right-click on a message and copy the ID, the copied string is the message ID only. It doesn't include the channel ID. Pressing Shift, hovering over the message, and clicking the ID icon doesn't require the Developer mode to be turned on either.

Zsolt Meszaros
  • 21,961
  • 19
  • 54
  • 57
Refluent
  • 93
  • 8
  • I've just checked it in the latest discord on my Mac and it only copies the message ID, no dashes, not the channel ID. What did you use to copy both in a single click? – Zsolt Meszaros Oct 27 '22 at 20:59
  • Right clicking the message and copying it's ID only gives you the message ID, but if you click shift and hover over the message, you can click an ID button which gives you both. The aforementioned way is also better as most user's won't have Developer mode turned on. – Refluent Oct 28 '22 at 11:06