有没有一种方法可以使Discord.js中的频道仅表情?

时间:2019-06-26 06:28:33

标签: javascript node.js discord.js

我正在寻找一种仅使用表情符号来限制一个文本通道的方法。因此,如果邮件中包含文本,则它会被机器人立即删除。

代码逻辑示例:

if (message.isEmoteOnly()) {
  console.log('Emote-only message detected');
} else {
  message.delete();
  message.channel.send('Your message has been deleted! This channel is in emote-only mode.');
}

2 个答案:

答案 0 :(得分:3)

使用Regular Expression来检查文本是否为表情符号格式,这是一种简单,更优雅,更不容易被滥用的方法。

/:[^:\s]+:|<:[^:\s]+:[0-9]+>|<a:[^:\s]+:[0-9]+>/g

要查看它的运行情况并了解每个令牌的作用,请查看here。在阅读下面的说明之前,我强烈建议您这样做。

乍一看似乎有点令人困惑,因此请就其工作原理进行细分...

  • :[^:\s]+:
    “正常”表情符号的格式为 :name: 。周围的:与冒号匹配,而[^:\s]+与中间的字符匹配。排除:(表示模板的末尾)和换行符(视为换行符,中间的字符不形成表情符号)。

  • <:[^:\s]+:[0-9]+>
    自定义表情符号的格式为 <:name:id> 。周围的<:>与模板的开头和结尾匹配。 [^:\s]+与名称匹配。名称和ID之间的冒号从字面上匹配。 [0-9]+与里面的数字匹配。 我没有将\d用于数字,因为可以将其他归类为Unicode的Unicode字符匹配。

  • <a:[^:\s]+:[0-9]+>
    动画表情符号的格式为 <a:name:id> <>与模板的开头和结尾匹配。 a:从字面上匹配。 [^:\s]+与名称匹配。 :实际上在名称和ID之间匹配。 [0-9]+与ID匹配。

现在,将其实现到您的代码中...

// Replace all emojis to leave just the text, if any.
const text = message.content.replace(/:[^:\s]+:|<:[^:\s]+:[0-9]+>|<a:[^:\s]+:[0-9]+>/g, '');

// Check if 'text' is not blank to see if there are characters which are not used in emojis.
if (text) {
  message.delete()
    .catch(console.error);
}

如果您只想在消息中允许一个表情符号,则可以定义字符串的开头和结尾,并删除全局修饰符。

/^(:[^:\s]+:|<:[^:\s]+:[0-9]+>|<a:[^:\s]+:[0-9]+>)$/

这将确保这是消息中唯一的内容。

编辑:

要在表情符号之间留出空格,只需在删除表情符号后在text中将其替换即可。在下面的示例中,\s还包括换行符(如果这不是期望的结果,请用空格替换)。

const text = message.content.replace(/:[^:\s]+:|<:[^:\s]+:[0-9]+>|<a:[^:\s]+:[0-9]+>/g, '').replace(/\s+/g, '');

在下面进行测试。

const str = ':smile: <a:parrot:1234> <:parrot:1234>';

const text = str.replace(/:[^:\s]+:|<:[^:\s]+:[0-9]+>|<a:[^:\s]+:[0-9]+>/g, '').replace(/\s+/g, '');

if (text) console.log('Not allowed.');
else console.log('Allowed.');

答案 1 :(得分:1)

尝试检查干净消息的内容是否以:开头并以:结束,或者是否为自定义表情的<:>结束。您可以使用

message.content.startsWith(':') && message.content.endsWith(':')

/* 'a' are animated emotes */

(message.content.startsWith('<a:') || message.content.startsWith('<:')) && message.content.endsWith('>')

用户可以通过执行:emote: loltext :emote:来利用它。如果您想避免这种情况,建议过滤掉表情,并检查字符串是否仍然存在。

// THIS IS A VERY SLOPPY WAY OF DOING THIS!!!!!!! DONT USE THIS FOR PRODUCTION
let split = message.content.split(' ');
for (let i = 0; i < split.length; i++) {
  if (!(split[i].startsWith(':') && split[i].endsWith(':')) && !((split[i].startsWith('<a:') || split[i].startsWith('<:')) && split[i].endsWith('>'))) {
    console.log(`has text: ${split[i]}`)
  }
}