mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-05-10 12:25:02 +00:00
Automod work
This commit is contained in:
parent
140ba84544
commit
f657b169df
32 changed files with 1099 additions and 5 deletions
4
backend/src/plugins/Automod/triggers/attachmentSpam.ts
Normal file
4
backend/src/plugins/Automod/triggers/attachmentSpam.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { RecentActionType } from "../constants";
|
||||
import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger";
|
||||
|
||||
export const AttachmentSpamTrigger = createMessageSpamTrigger(RecentActionType.Attachment, "attachment");
|
37
backend/src/plugins/Automod/triggers/availableTriggers.ts
Normal file
37
backend/src/plugins/Automod/triggers/availableTriggers.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import * as t from "io-ts";
|
||||
import { MatchWordsTrigger } from "./matchWords";
|
||||
import { AutomodTriggerBlueprint } from "../helpers";
|
||||
import { MessageSpamTrigger } from "./messageSpam";
|
||||
import { MentionSpamTrigger } from "./mentionSpam";
|
||||
import { LinkSpamTrigger } from "./linkSpam";
|
||||
import { AttachmentSpamTrigger } from "./attachmentSpam";
|
||||
import { EmojiSpamTrigger } from "./emojiSpam";
|
||||
import { LineSpamTrigger } from "./lineSpam";
|
||||
import { CharacterSpamTrigger } from "./characterSpam";
|
||||
import { MatchRegexTrigger } from "./matchRegex";
|
||||
|
||||
export const availableTriggers: Record<string, AutomodTriggerBlueprint<any, any>> = {
|
||||
match_words: MatchWordsTrigger,
|
||||
match_regex: MatchRegexTrigger,
|
||||
|
||||
message_spam: MessageSpamTrigger,
|
||||
mention_spam: MentionSpamTrigger,
|
||||
link_spam: LinkSpamTrigger,
|
||||
attachment_spam: AttachmentSpamTrigger,
|
||||
emoji_spam: EmojiSpamTrigger,
|
||||
line_spam: LineSpamTrigger,
|
||||
character_spam: CharacterSpamTrigger,
|
||||
};
|
||||
|
||||
export const AvailableTriggers = t.type({
|
||||
match_words: MatchWordsTrigger.configType,
|
||||
match_regex: MatchRegexTrigger.configType,
|
||||
|
||||
message_spam: MessageSpamTrigger.configType,
|
||||
mention_spam: MentionSpamTrigger.configType,
|
||||
link_spam: LinkSpamTrigger.configType,
|
||||
attachment_spam: AttachmentSpamTrigger.configType,
|
||||
emoji_spam: EmojiSpamTrigger.configType,
|
||||
line_spam: LineSpamTrigger.configType,
|
||||
character_spam: CharacterSpamTrigger.configType,
|
||||
});
|
4
backend/src/plugins/Automod/triggers/characterSpam.ts
Normal file
4
backend/src/plugins/Automod/triggers/characterSpam.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { RecentActionType } from "../constants";
|
||||
import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger";
|
||||
|
||||
export const CharacterSpamTrigger = createMessageSpamTrigger(RecentActionType.Character, "character");
|
4
backend/src/plugins/Automod/triggers/emojiSpam.ts
Normal file
4
backend/src/plugins/Automod/triggers/emojiSpam.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { RecentActionType } from "../constants";
|
||||
import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger";
|
||||
|
||||
export const EmojiSpamTrigger = createMessageSpamTrigger(RecentActionType.Emoji, "emoji");
|
27
backend/src/plugins/Automod/triggers/exampleTrigger.ts
Normal file
27
backend/src/plugins/Automod/triggers/exampleTrigger.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import * as t from "io-ts";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
export const ExampleTrigger = automodTrigger({
|
||||
configType: t.type({
|
||||
some: t.number,
|
||||
value: t.string,
|
||||
}),
|
||||
|
||||
defaultConfig: {},
|
||||
|
||||
matchResultType: t.type({
|
||||
thing: t.string,
|
||||
}),
|
||||
|
||||
async match() {
|
||||
return {
|
||||
extra: {
|
||||
thing: "hi",
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
renderMatchInformation() {
|
||||
return "";
|
||||
},
|
||||
});
|
4
backend/src/plugins/Automod/triggers/lineSpam.ts
Normal file
4
backend/src/plugins/Automod/triggers/lineSpam.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { RecentActionType } from "../constants";
|
||||
import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger";
|
||||
|
||||
export const LineSpamTrigger = createMessageSpamTrigger(RecentActionType.Line, "line");
|
4
backend/src/plugins/Automod/triggers/linkSpam.ts
Normal file
4
backend/src/plugins/Automod/triggers/linkSpam.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { RecentActionType } from "../constants";
|
||||
import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger";
|
||||
|
||||
export const LinkSpamTrigger = createMessageSpamTrigger(RecentActionType.Link, "link");
|
72
backend/src/plugins/Automod/triggers/matchRegex.ts
Normal file
72
backend/src/plugins/Automod/triggers/matchRegex.ts
Normal file
|
@ -0,0 +1,72 @@
|
|||
import * as t from "io-ts";
|
||||
import { transliterate } from "transliteration";
|
||||
import escapeStringRegexp from "escape-string-regexp";
|
||||
import { automodTrigger } from "../helpers";
|
||||
import { disableInlineCode, verboseChannelMention } from "../../../utils";
|
||||
import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage";
|
||||
|
||||
export const MatchRegexTrigger = automodTrigger({
|
||||
configType: t.type({
|
||||
patterns: t.array(t.string),
|
||||
case_sensitive: t.boolean,
|
||||
normalize: t.boolean,
|
||||
match_messages: t.boolean,
|
||||
match_embeds: t.boolean,
|
||||
match_visible_names: t.boolean,
|
||||
match_usernames: t.boolean,
|
||||
match_nicknames: t.boolean,
|
||||
match_custom_status: t.boolean,
|
||||
}),
|
||||
|
||||
defaultConfig: {
|
||||
case_sensitive: false,
|
||||
normalize: false,
|
||||
match_messages: true,
|
||||
match_embeds: true,
|
||||
match_visible_names: false,
|
||||
match_usernames: false,
|
||||
match_nicknames: false,
|
||||
match_custom_status: false,
|
||||
},
|
||||
|
||||
matchResultType: t.type({
|
||||
pattern: t.string,
|
||||
type: MatchableTextType,
|
||||
}),
|
||||
|
||||
async match({ pluginData, context, triggerConfig: trigger }) {
|
||||
if (!context.message) {
|
||||
return;
|
||||
}
|
||||
|
||||
for await (let [type, str] of matchMultipleTextTypesOnMessage(pluginData, trigger, context.message)) {
|
||||
if (trigger.normalize) {
|
||||
str = transliterate(str);
|
||||
}
|
||||
|
||||
for (const pattern of trigger.patterns) {
|
||||
const regex = new RegExp(pattern, trigger.case_sensitive ? "" : "i");
|
||||
const test = regex.test(str);
|
||||
if (test) {
|
||||
return {
|
||||
extra: {
|
||||
pattern,
|
||||
type,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
renderMatchInformation({ pluginData, contexts, matchResult }) {
|
||||
const channel = pluginData.guild.channels.get(contexts[0].message.channel_id);
|
||||
const prettyChannel = verboseChannelMention(channel);
|
||||
|
||||
return `Matched regex \`${disableInlineCode(matchResult.extra.pattern)}\` in message (\`${
|
||||
contexts[0].message.id
|
||||
}\`) in ${prettyChannel}:`;
|
||||
},
|
||||
});
|
90
backend/src/plugins/Automod/triggers/matchWords.ts
Normal file
90
backend/src/plugins/Automod/triggers/matchWords.ts
Normal file
|
@ -0,0 +1,90 @@
|
|||
import * as t from "io-ts";
|
||||
import { transliterate } from "transliteration";
|
||||
import escapeStringRegexp from "escape-string-regexp";
|
||||
import { automodTrigger } from "../helpers";
|
||||
import { disableInlineCode, verboseChannelMention } from "../../../utils";
|
||||
import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage";
|
||||
|
||||
export const MatchWordsTrigger = automodTrigger({
|
||||
configType: t.type({
|
||||
words: t.array(t.string),
|
||||
case_sensitive: t.boolean,
|
||||
only_full_words: t.boolean,
|
||||
normalize: t.boolean,
|
||||
loose_matching: t.boolean,
|
||||
loose_matching_threshold: t.number,
|
||||
match_messages: t.boolean,
|
||||
match_embeds: t.boolean,
|
||||
match_visible_names: t.boolean,
|
||||
match_usernames: t.boolean,
|
||||
match_nicknames: t.boolean,
|
||||
match_custom_status: t.boolean,
|
||||
}),
|
||||
|
||||
defaultConfig: {
|
||||
case_sensitive: false,
|
||||
only_full_words: true,
|
||||
normalize: false,
|
||||
loose_matching: false,
|
||||
loose_matching_threshold: 4,
|
||||
match_messages: true,
|
||||
match_embeds: true,
|
||||
match_visible_names: false,
|
||||
match_usernames: false,
|
||||
match_nicknames: false,
|
||||
match_custom_status: false,
|
||||
},
|
||||
|
||||
matchResultType: t.type({
|
||||
word: t.string,
|
||||
type: MatchableTextType,
|
||||
}),
|
||||
|
||||
async match({ pluginData, context, triggerConfig: trigger }) {
|
||||
if (!context.message) {
|
||||
return;
|
||||
}
|
||||
|
||||
for await (let [type, str] of matchMultipleTextTypesOnMessage(pluginData, trigger, context.message)) {
|
||||
if (trigger.normalize) {
|
||||
str = transliterate(str);
|
||||
}
|
||||
|
||||
const looseMatchingThreshold = Math.min(Math.max(trigger.loose_matching_threshold, 1), 64);
|
||||
|
||||
for (const word of trigger.words) {
|
||||
// When performing loose matching, allow any amount of whitespace or up to looseMatchingThreshold number of other
|
||||
// characters between the matched characters. E.g. if we're matching banana, a loose match could also match b a n a n a
|
||||
let pattern = trigger.loose_matching
|
||||
? [...word].map(c => escapeStringRegexp(c)).join(`(?:\\s*|.{0,${looseMatchingThreshold})`)
|
||||
: escapeStringRegexp(word);
|
||||
|
||||
if (trigger.only_full_words) {
|
||||
pattern = `\\b${pattern}\\b`;
|
||||
}
|
||||
|
||||
const regex = new RegExp(pattern, trigger.case_sensitive ? "" : "i");
|
||||
const test = regex.test(str);
|
||||
if (test) {
|
||||
return {
|
||||
extra: {
|
||||
word,
|
||||
type,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
renderMatchInformation({ pluginData, contexts, matchResult }) {
|
||||
const channel = pluginData.guild.channels.get(contexts[0].message.channel_id);
|
||||
const prettyChannel = verboseChannelMention(channel);
|
||||
|
||||
return `Matched word \`${disableInlineCode(matchResult.extra.word)}\` in message (\`${
|
||||
contexts[0].message.id
|
||||
}\`) in ${prettyChannel}:`;
|
||||
},
|
||||
});
|
4
backend/src/plugins/Automod/triggers/mentionSpam.ts
Normal file
4
backend/src/plugins/Automod/triggers/mentionSpam.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { RecentActionType } from "../constants";
|
||||
import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger";
|
||||
|
||||
export const MentionSpamTrigger = createMessageSpamTrigger(RecentActionType.Mention, "mention");
|
4
backend/src/plugins/Automod/triggers/messageSpam.ts
Normal file
4
backend/src/plugins/Automod/triggers/messageSpam.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { RecentActionType } from "../constants";
|
||||
import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger";
|
||||
|
||||
export const MessageSpamTrigger = createMessageSpamTrigger(RecentActionType.Message, "message");
|
Loading…
Add table
Add a link
Reference in a new issue