我正在寻找一种仅使用表情符号来限制一个文本通道的方法。因此,如果邮件中包含文本,则它会被机器人立即删除。
代码逻辑示例:
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.');
}
答案 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]}`)
}
}