'Discord.js | Detect if message contains an Emoji

I'm programming a poll feature for my bot where I can create a poll by chatting with the bot. The "poll" the bot creates is just a basic message where other users can react to vote. I'm struggling with finding a way to tell the bot which emoji I want for each possible answer. My idea right now is to write the bot a single message for each possible answer which contains an emoji and the answer (":white_check_mark: Yes"). In hours of trying and searching I have not found any way to check whether the first part of the message is an emoji. I found many posts about searching for the pattern of ":", "<:" or "<a:", which every emoji is supposed to start with, but I've tried everything I could come up with and it's not working cause for some reason the emojis are not written in that way. I would appreciate it if anyone could help me with the problem because as of now I have no clue how to continue with my original idea.

Edit: What I basically just need is a way to check whether a message contains an emoji. However, I was asked to attach my code which would be pretty much to give you an idea of how I'm working. I need to check if a message starts with an emoji because it has to so that the bot knows which emoji he needs to react to the message with and he obviously can't react with something that isn't an emoji.

Thanks Noah



Solution 1:[1]

There is actually a much simpler way of checking if a message contains emoji(s), and separating them from message content. (This is posted more for future viewers of this question, as opposed to the OP who has already solved their problem).

Though the accepted answer works for detecting unicode emotes, it uses an external package, is based on an outdated way of doing this from pre-ES6, and overcomplicates things in some ways. You can check if a string contains an emoji, whether unicode or custom discord format (including animated emotes), with a very simple regex. All on a single, succinct line of code.

const emotes = (str) => str.match(/<a?:.+?:\d{18}>|\p{Extended_Pictographic}/gu);

// TESTS:

console.log(emotes("No emotes here")) 
// -> null

console.log(emotes("None here 1234 either"))
// -> null

console.log(emotes("One over here ?"))
// -> ["?"]

console.log(emotes("One over here also <:yea:123456789012345678>"))
// -> ["<:yea:123456789012345678>"]

console.log(emotes("Two over <a:yea:123456789012345678> here ?"))
// -> ["<a:yea:123456789012345678>", "?"]

console.log(emotes("Three ? emotes ? here ?"))
// -> ["?", "?", "?"]

This is how this emotes() method could be used in generic djs code:

if (emotes(message.content)) {
  // Do what you want with the emotes
  message.reply(`The emotes found were: ${emotes(message.content).join(", ")}`);
}

I will also explain what the regex is doing here so it is understandable. The regex looks for two different scenarios: discord's custom emote format and unicode emotes.

Custom emotes look something like this: <:emotename:123456789012345678>. They have the emoji's name between two colons, and the ID of the emoji after the last colon. Animated emotes follow the same format, except for an 'a' added before the first colon: <a:emotename:123456789012345678>. The first part of the regex (<a?:.+?:\d{18}>) checks for these two discord custom emote cases. a? matches 0 or 1 of 'a', meaning it will find both animated and unanimated emotes. .+? matches any combination of characters, in between the two specified colons (representing the emote's name). \d{18} matches exactly 18 numerical digits (representing the emote's ID).

Unicode emotes represent text emojis and discord's built-in emojis, and they look something like this: ?. This was what the OP found challenging to detect in message content. But thanks to ES6, it is possible to match specific categories of unicode characters using regex (assuming you have the u unicode flag added to your regex, in our case we have that and the g global flag added). The second part of the regex (\p{Extended_Pictographic}) matches this case. This matches any unicode character belonging to the category Extended_Pictographic, or in other words all of the emote characters.

(Note: there actually is a Emote category that can be used with \p{Emote}, but this unfortunately matches plaintext numbers and some punctuation on top of all emotes. Extended_Pictographic matches just the emotes.)

These two parts of the regex are combined with a |, meaning anything that matches the first OR second regex will be returned in the results. So emotes() will return an array of any unicode or custom discord emotes found in the provided string, or null if none are found.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Cannicide