mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-03-15 05:41:51 +00:00
Add censor plugin. Various other fixes/features. Update Knub to 9.4.13.
This commit is contained in:
parent
0c806f32fd
commit
e7734c558c
9 changed files with 283 additions and 43 deletions
11
package-lock.json
generated
11
package-lock.json
generated
|
@ -2176,9 +2176,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"knub": {
|
"knub": {
|
||||||
"version": "9.4.11",
|
"version": "9.4.13",
|
||||||
"resolved": "https://registry.npmjs.org/knub/-/knub-9.4.11.tgz",
|
"resolved": "https://registry.npmjs.org/knub/-/knub-9.4.13.tgz",
|
||||||
"integrity": "sha512-C/Ps3jegzgVfaKfcyumUhPdFd269t4yuAUWnXf71S3d/6MCLhVMfGehG0Ma2AMb5M85DqN8ge9n3OME3k1zwJw==",
|
"integrity": "sha512-4m5IMbctg1xAe6DoYSkk1jdQNWpUb6ZkjKxJPxHEmbXtIZm11qt/AmIcASgG5pvZOM7Q/PnsbLfRyzlUTbvOLA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"escape-string-regexp": "^1.0.5",
|
"escape-string-regexp": "^1.0.5",
|
||||||
"js-yaml": "^3.9.1",
|
"js-yaml": "^3.9.1",
|
||||||
|
@ -3670,6 +3670,11 @@
|
||||||
"integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
|
"integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"tlds": {
|
||||||
|
"version": "1.203.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tlds/-/tlds-1.203.1.tgz",
|
||||||
|
"integrity": "sha512-7MUlYyGJ6rSitEZ3r1Q1QNV8uSIzapS8SmmhSusBuIc7uIxPPwsKllEP0GRp1NS6Ik6F+fRZvnjDWm3ecv2hDw=="
|
||||||
|
},
|
||||||
"to-object-path": {
|
"to-object-path": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
|
||||||
|
|
|
@ -29,14 +29,16 @@
|
||||||
"@types/node": "^8.0.50",
|
"@types/node": "^8.0.50",
|
||||||
"dotenv": "^4.0.0",
|
"dotenv": "^4.0.0",
|
||||||
"eris": "^0.8.6",
|
"eris": "^0.8.6",
|
||||||
|
"escape-string-regexp": "^1.0.5",
|
||||||
"humanize-duration": "^3.15.0",
|
"humanize-duration": "^3.15.0",
|
||||||
"knex": "^0.14.6",
|
"knex": "^0.14.6",
|
||||||
"knub": "^9.4.11",
|
"knub": "^9.4.13",
|
||||||
"lodash.at": "^4.6.0",
|
"lodash.at": "^4.6.0",
|
||||||
"lodash.difference": "^4.5.0",
|
"lodash.difference": "^4.5.0",
|
||||||
"lodash.isequal": "^4.5.0",
|
"lodash.isequal": "^4.5.0",
|
||||||
"mariasql": "^0.2.6",
|
"mariasql": "^0.2.6",
|
||||||
"moment-timezone": "^0.5.21",
|
"moment-timezone": "^0.5.21",
|
||||||
|
"tlds": "^1.203.1",
|
||||||
"ts-node": "^3.3.0",
|
"ts-node": "^3.3.0",
|
||||||
"typescript": "^2.9.2"
|
"typescript": "^2.9.2"
|
||||||
},
|
},
|
||||||
|
|
|
@ -24,17 +24,18 @@
|
||||||
"ROLE_EDIT": "🖊 Role **{role.name}** was edited",
|
"ROLE_EDIT": "🖊 Role **{role.name}** was edited",
|
||||||
|
|
||||||
"MESSAGE_EDIT": "✏ **{member.user.username}#{member.user.discriminator}** (`{member.id}`) message edited in **{channel.name}**:\n`B:` {before}\n`A:` {after}",
|
"MESSAGE_EDIT": "✏ **{member.user.username}#{member.user.discriminator}** (`{member.id}`) message edited in **{channel.name}**:\n`B:` {before}\n`A:` {after}",
|
||||||
"MESSAGE_DELETE": "🗑 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) message deleted in **{channel.name}**:\n{messageText}{attachments}",
|
"MESSAGE_DELETE": "🗑 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) message deleted in **{channel.name}**:\n```{messageText}```",
|
||||||
"MESSAGE_DELETE_BULK": "🗑 **{count}** messages deleted in **{channel.name}**",
|
"MESSAGE_DELETE_BULK": "🗑 **{count}** messages deleted in **{channel.name}**",
|
||||||
|
"MESSAGE_DELETE_BARE": "🗑 message (id `{messageId}`) deleted in **{channel.name}** (no more info available due to restart)",
|
||||||
|
|
||||||
"VOICE_CHANNEL_JOIN": "🔸 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) joined **{channel.name}**",
|
"VOICE_CHANNEL_JOIN": "🔸 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) joined **{channel.name}**",
|
||||||
"VOICE_CHANNEL_MOVE": "🔹 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) moved **{oldChannel.name}** ➞ **{newChannel.name}**",
|
"VOICE_CHANNEL_MOVE": "🔹 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) moved **{oldChannel.name}** ➞ **{newChannel.name}**",
|
||||||
"VOICE_CHANNEL_LEAVE": "♦ **{member.user.username}#{member.user.discriminator}** (`{member.id}`) left **{channel.name}**",
|
"VOICE_CHANNEL_LEAVE": "♦ **{member.user.username}#{member.user.discriminator}** (`{member.id}`) left **{channel.name}**",
|
||||||
|
|
||||||
"COMMAND": "🤖 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) used command in **{channel.name}**:\n`{command}`",
|
"COMMAND": "🤖 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) used command in **#{channel.name}**:\n`{command}`",
|
||||||
|
|
||||||
"SPAM_DELETE": "🛑 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) triggered spam filter: **{filterName}**",
|
"SPAM_DELETE": "🛑 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) triggered spam filter: **{filterName}**",
|
||||||
"CENSOR": "🛑 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) censored message in **{channel.name}**:\n`{messageText}`",
|
"CENSOR": "🛑 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) censored message in **#{channel.name}** (`{channel.id}`) {reason}:\n```{messageText}```",
|
||||||
|
|
||||||
"CASE_CREATE": "✏ **{member.user.username}#{member.user.discriminator}** (`{member.id}`) manually created new **{caseType}** case (#{caseNum})"
|
"CASE_CREATE": "✏ **{member.user.username}#{member.user.discriminator}** (`{member.id}`) manually created new **{caseType}** case (#{caseNum})"
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ export class GuildLogs extends EventEmitter {
|
||||||
|
|
||||||
super();
|
super();
|
||||||
this.guildId = guildId;
|
this.guildId = guildId;
|
||||||
|
this.ignoredLogs = [];
|
||||||
|
|
||||||
// Store the instance for this guild so it can be returned later if a new instance for this guild is requested
|
// Store the instance for this guild so it can be returned later if a new instance for this guild is requested
|
||||||
guildInstances.set(guildId, this);
|
guildInstances.set(guildId, this);
|
||||||
|
|
|
@ -24,6 +24,7 @@ export enum LogType {
|
||||||
MESSAGE_EDIT,
|
MESSAGE_EDIT,
|
||||||
MESSAGE_DELETE,
|
MESSAGE_DELETE,
|
||||||
MESSAGE_DELETE_BULK,
|
MESSAGE_DELETE_BULK,
|
||||||
|
MESSAGE_DELETE_BARE,
|
||||||
|
|
||||||
VOICE_CHANNEL_JOIN,
|
VOICE_CHANNEL_JOIN,
|
||||||
VOICE_CHANNEL_LEAVE,
|
VOICE_CHANNEL_LEAVE,
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { UtilityPlugin } from "./plugins/Utility";
|
||||||
import { LogsPlugin } from "./plugins/Logs";
|
import { LogsPlugin } from "./plugins/Logs";
|
||||||
import { PostPlugin } from "./plugins/Post";
|
import { PostPlugin } from "./plugins/Post";
|
||||||
import { ReactionRolesPlugin } from "./plugins/ReactionRoles";
|
import { ReactionRolesPlugin } from "./plugins/ReactionRoles";
|
||||||
|
import { CensorPlugin } from "./plugins/Censor";
|
||||||
import knex from "./knex";
|
import knex from "./knex";
|
||||||
|
|
||||||
// Run latest database migrations
|
// Run latest database migrations
|
||||||
|
@ -32,7 +33,8 @@ knex.migrate.latest().then(() => {
|
||||||
mod_actions: ModActionsPlugin,
|
mod_actions: ModActionsPlugin,
|
||||||
logs: LogsPlugin,
|
logs: LogsPlugin,
|
||||||
post: PostPlugin,
|
post: PostPlugin,
|
||||||
reaction_roles: ReactionRolesPlugin
|
reaction_roles: ReactionRolesPlugin,
|
||||||
|
censor: CensorPlugin
|
||||||
},
|
},
|
||||||
globalPlugins: {
|
globalPlugins: {
|
||||||
bot_control: BotControlPlugin
|
bot_control: BotControlPlugin
|
||||||
|
|
212
src/plugins/Censor.ts
Normal file
212
src/plugins/Censor.ts
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
import { Plugin, decorators as d } from "knub";
|
||||||
|
import { Invite, Message } from "eris";
|
||||||
|
import url from "url";
|
||||||
|
import tlds from "tlds";
|
||||||
|
import escapeStringRegexp from "escape-string-regexp";
|
||||||
|
import { GuildLogs } from "../data/GuildLogs";
|
||||||
|
import { LogType } from "../data/LogType";
|
||||||
|
import { stripObjectToScalars } from "../utils";
|
||||||
|
|
||||||
|
const urlRegex = /(\S+\.\S+)/g;
|
||||||
|
const protocolRegex = /^[a-z]+:\/\//;
|
||||||
|
|
||||||
|
const getInviteCodesInString = (str: string): string[] => {
|
||||||
|
const inviteCodeRegex = /(?:discord.gg|discordapp.com\/invite)\/([a-z0-9]+)/gi;
|
||||||
|
const inviteCodes = [];
|
||||||
|
let match;
|
||||||
|
|
||||||
|
// tslint:disable-next-line
|
||||||
|
while ((match = inviteCodeRegex.exec(str)) !== null) {
|
||||||
|
inviteCodes.push(match[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return inviteCodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUrlsInString = (str: string): url.URL[] => {
|
||||||
|
const matches = str.match(urlRegex) || [];
|
||||||
|
return matches.reduce((urls, match) => {
|
||||||
|
if (!protocolRegex.test(match)) {
|
||||||
|
match = `https://${match}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let matchUrl: url.URL;
|
||||||
|
try {
|
||||||
|
matchUrl = new url.URL(match);
|
||||||
|
} catch (e) {
|
||||||
|
return urls;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hostnameParts = matchUrl.hostname.split(".");
|
||||||
|
const tld = hostnameParts[hostnameParts.length - 1];
|
||||||
|
if (tlds.includes(tld)) {
|
||||||
|
urls.push(matchUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return urls;
|
||||||
|
}, []);
|
||||||
|
};
|
||||||
|
|
||||||
|
export class CensorPlugin extends Plugin {
|
||||||
|
protected serverLogs: GuildLogs;
|
||||||
|
|
||||||
|
getDefaultOptions() {
|
||||||
|
return {
|
||||||
|
config: {
|
||||||
|
filter_invites: false,
|
||||||
|
invite_guild_whitelist: null,
|
||||||
|
invite_guild_blacklist: null,
|
||||||
|
invite_code_whitelist: null,
|
||||||
|
invite_code_blacklist: null,
|
||||||
|
|
||||||
|
filter_domains: false,
|
||||||
|
domain_whitelist: null,
|
||||||
|
domain_blacklist: null,
|
||||||
|
|
||||||
|
blocked_tokens: null,
|
||||||
|
blocked_words: null,
|
||||||
|
blocked_regex: null
|
||||||
|
},
|
||||||
|
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
level: ">=50",
|
||||||
|
config: {
|
||||||
|
filter_invites: false,
|
||||||
|
filter_domains: false,
|
||||||
|
blocked_tokens: null,
|
||||||
|
blocked_words: null,
|
||||||
|
blocked_regex: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
this.serverLogs = new GuildLogs(this.guildId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async censorMessage(msg: Message, reason: string) {
|
||||||
|
this.serverLogs.ignoreLog(LogType.MESSAGE_DELETE, msg.id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await msg.delete("Censored");
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.serverLogs.log(LogType.CENSOR, {
|
||||||
|
member: stripObjectToScalars(msg.member, ["user"]),
|
||||||
|
channel: stripObjectToScalars(msg.channel),
|
||||||
|
reason,
|
||||||
|
messageText: msg.cleanContent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async applyFiltersToMsg(msg: Message) {
|
||||||
|
if (msg.author.bot) return;
|
||||||
|
if (msg.type !== 0) return;
|
||||||
|
if (!msg.content) return;
|
||||||
|
|
||||||
|
// Filter invites
|
||||||
|
if (this.configValueForMsg(msg, "filter_invites")) {
|
||||||
|
const inviteGuildWhitelist: string[] = this.configValueForMsg(msg, "invite_guild_whitelist");
|
||||||
|
const inviteGuildBlacklist: string[] = this.configValueForMsg(msg, "invite_guild_blacklist");
|
||||||
|
const inviteCodeWhitelist: string[] = this.configValueForMsg(msg, "invite_code_whitelist");
|
||||||
|
const inviteCodeBlacklist: string[] = this.configValueForMsg(msg, "invite_code_blacklist");
|
||||||
|
|
||||||
|
const inviteCodes = getInviteCodesInString(msg.content);
|
||||||
|
|
||||||
|
const invites: Invite[] = await Promise.all(
|
||||||
|
inviteCodes.map(code => this.bot.getInvite(code))
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const invite of invites) {
|
||||||
|
if (inviteGuildWhitelist && !inviteGuildWhitelist.includes(invite.guild.id)) {
|
||||||
|
this.censorMessage(
|
||||||
|
msg,
|
||||||
|
`invite guild (**${invite.guild.name}** \`${invite.guild.id}\`) not found in whitelist`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inviteGuildBlacklist && inviteGuildBlacklist.includes(invite.guild.id)) {
|
||||||
|
this.censorMessage(
|
||||||
|
msg,
|
||||||
|
`invite guild (**${invite.guild.name}** \`${invite.guild.id}\`) found in blacklist`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inviteCodeWhitelist && !inviteCodeWhitelist.includes(invite.code)) {
|
||||||
|
this.censorMessage(msg, `invite code (\`${invite.code}\`) not found in whitelist`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inviteCodeBlacklist && inviteCodeBlacklist.includes(invite.code)) {
|
||||||
|
this.censorMessage(msg, `invite code (\`${invite.code}\`) found in blacklist`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter domains
|
||||||
|
if (this.configValueForMsg(msg, "filter_domains")) {
|
||||||
|
const domainWhitelist: string[] = this.configValueForMsg(msg, "domain_whitelist");
|
||||||
|
const domainBlacklist: string[] = this.configValueForMsg(msg, "domain_blacklist");
|
||||||
|
|
||||||
|
const urls = getUrlsInString(msg.content);
|
||||||
|
for (const thisUrl of urls) {
|
||||||
|
if (domainWhitelist && !domainWhitelist.includes(thisUrl.hostname)) {
|
||||||
|
this.censorMessage(msg, `domain (\`${thisUrl.hostname}\`) not found in whitelist`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domainBlacklist && domainBlacklist.includes(thisUrl.hostname)) {
|
||||||
|
this.censorMessage(msg, `domain (\`${thisUrl.hostname}\`) found in blacklist`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter tokens
|
||||||
|
const blockedTokens = this.configValueForMsg(msg, "blocked_tokens") || [];
|
||||||
|
for (const token of blockedTokens) {
|
||||||
|
if (msg.content.includes(token)) {
|
||||||
|
this.censorMessage(msg, `blocked token (\`${token}\`) found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter words
|
||||||
|
const blockedWords = this.configValueForMsg(msg, "blocked_words") || [];
|
||||||
|
for (const word of blockedWords) {
|
||||||
|
const regex = new RegExp(`\\b${escapeStringRegexp(word)}\\b`, "i");
|
||||||
|
if (regex.test(msg.content)) {
|
||||||
|
this.censorMessage(msg, `blocked word (\`${word}\`) found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter regex
|
||||||
|
const blockedRegex = this.configValueForMsg(msg, "blocked_regex") || [];
|
||||||
|
for (const regexStr of blockedRegex) {
|
||||||
|
const regex = new RegExp(regexStr);
|
||||||
|
if (regex.test(msg.content)) {
|
||||||
|
this.censorMessage(msg, `blocked regex (\`${regexStr}\`) found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@d.event("messageCreate")
|
||||||
|
async onMessageCreate(msg: Message) {
|
||||||
|
this.applyFiltersToMsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@d.event("messageUpdate")
|
||||||
|
async onMessageUpdate(msg: Message) {
|
||||||
|
this.applyFiltersToMsg(msg);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,7 @@
|
||||||
import { decorators as d, Plugin } from "knub";
|
import { decorators as d, Plugin } from "knub";
|
||||||
import { GuildLogs } from "../data/GuildLogs";
|
import { GuildLogs } from "../data/GuildLogs";
|
||||||
import { LogType } from "../data/LogType";
|
import { LogType } from "../data/LogType";
|
||||||
import {
|
import { Channel, Constants as ErisConstants, Member, Message, TextChannel, User } from "eris";
|
||||||
Channel,
|
|
||||||
Constants as ErisConstants,
|
|
||||||
Member,
|
|
||||||
Message,
|
|
||||||
PrivateChannel,
|
|
||||||
TextChannel,
|
|
||||||
User
|
|
||||||
} from "eris";
|
|
||||||
import { findRelevantAuditLogEntry, formatTemplateString, stripObjectToScalars } from "../utils";
|
import { findRelevantAuditLogEntry, formatTemplateString, stripObjectToScalars } from "../utils";
|
||||||
import DefaultLogMessages from "../data/DefaultLogMessages.json";
|
import DefaultLogMessages from "../data/DefaultLogMessages.json";
|
||||||
import moment from "moment-timezone";
|
import moment from "moment-timezone";
|
||||||
|
@ -98,7 +90,7 @@ export class LogsPlugin extends Plugin {
|
||||||
round: true
|
round: true
|
||||||
});
|
});
|
||||||
|
|
||||||
this.log(LogType.MEMBER_JOIN, {
|
this.serverLogs.log(LogType.MEMBER_JOIN, {
|
||||||
member: stripObjectToScalars(member, ["user"]),
|
member: stripObjectToScalars(member, ["user"]),
|
||||||
new: member.createdAt >= newThreshold ? " :new:" : "",
|
new: member.createdAt >= newThreshold ? " :new:" : "",
|
||||||
account_age: accountAge
|
account_age: accountAge
|
||||||
|
@ -107,7 +99,7 @@ export class LogsPlugin extends Plugin {
|
||||||
|
|
||||||
@d.event("guildMemberRemove")
|
@d.event("guildMemberRemove")
|
||||||
onMemberLeave(_, member) {
|
onMemberLeave(_, member) {
|
||||||
this.log(LogType.MEMBER_LEAVE, {
|
this.serverLogs.log(LogType.MEMBER_LEAVE, {
|
||||||
member: stripObjectToScalars(member, ["user"])
|
member: stripObjectToScalars(member, ["user"])
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -121,7 +113,7 @@ export class LogsPlugin extends Plugin {
|
||||||
);
|
);
|
||||||
const mod = relevantAuditLogEntry ? relevantAuditLogEntry.user : unknownUser;
|
const mod = relevantAuditLogEntry ? relevantAuditLogEntry.user : unknownUser;
|
||||||
|
|
||||||
this.log(LogType.MEMBER_BAN, {
|
this.serverLogs.log(LogType.MEMBER_BAN, {
|
||||||
user: stripObjectToScalars(user),
|
user: stripObjectToScalars(user),
|
||||||
mod: stripObjectToScalars(mod)
|
mod: stripObjectToScalars(mod)
|
||||||
});
|
});
|
||||||
|
@ -136,7 +128,7 @@ export class LogsPlugin extends Plugin {
|
||||||
);
|
);
|
||||||
const mod = relevantAuditLogEntry ? relevantAuditLogEntry.user : unknownUser;
|
const mod = relevantAuditLogEntry ? relevantAuditLogEntry.user : unknownUser;
|
||||||
|
|
||||||
this.log(LogType.MEMBER_UNBAN, {
|
this.serverLogs.log(LogType.MEMBER_UNBAN, {
|
||||||
user: stripObjectToScalars(user),
|
user: stripObjectToScalars(user),
|
||||||
mod: stripObjectToScalars(mod)
|
mod: stripObjectToScalars(mod)
|
||||||
});
|
});
|
||||||
|
@ -147,7 +139,7 @@ export class LogsPlugin extends Plugin {
|
||||||
if (!oldMember) return;
|
if (!oldMember) return;
|
||||||
|
|
||||||
if (member.nick !== oldMember.nick) {
|
if (member.nick !== oldMember.nick) {
|
||||||
this.log(LogType.MEMBER_NICK_CHANGE, {
|
this.serverLogs.log(LogType.MEMBER_NICK_CHANGE, {
|
||||||
member,
|
member,
|
||||||
oldNick: oldMember.nick,
|
oldNick: oldMember.nick,
|
||||||
newNick: member.nick
|
newNick: member.nick
|
||||||
|
@ -166,13 +158,13 @@ export class LogsPlugin extends Plugin {
|
||||||
const mod = relevantAuditLogEntry ? relevantAuditLogEntry.user : unknownUser;
|
const mod = relevantAuditLogEntry ? relevantAuditLogEntry.user : unknownUser;
|
||||||
|
|
||||||
if (addedRoles.length) {
|
if (addedRoles.length) {
|
||||||
this.log(LogType.MEMBER_ROLE_ADD, {
|
this.serverLogs.log(LogType.MEMBER_ROLE_ADD, {
|
||||||
member,
|
member,
|
||||||
role: this.guild.roles.get(addedRoles[0]),
|
role: this.guild.roles.get(addedRoles[0]),
|
||||||
mod: stripObjectToScalars(mod)
|
mod: stripObjectToScalars(mod)
|
||||||
});
|
});
|
||||||
} else if (removedRoles.length) {
|
} else if (removedRoles.length) {
|
||||||
this.log(LogType.MEMBER_ROLE_REMOVE, {
|
this.serverLogs.log(LogType.MEMBER_ROLE_REMOVE, {
|
||||||
member,
|
member,
|
||||||
role: this.guild.roles.get(removedRoles[0]),
|
role: this.guild.roles.get(removedRoles[0]),
|
||||||
mod: stripObjectToScalars(mod)
|
mod: stripObjectToScalars(mod)
|
||||||
|
@ -187,7 +179,7 @@ export class LogsPlugin extends Plugin {
|
||||||
|
|
||||||
if (user.username !== oldUser.username || user.discriminator !== oldUser.discriminator) {
|
if (user.username !== oldUser.username || user.discriminator !== oldUser.discriminator) {
|
||||||
const member = this.guild.members.get(user.id) || { id: user.id, user };
|
const member = this.guild.members.get(user.id) || { id: user.id, user };
|
||||||
this.log(LogType.MEMBER_USERNAME_CHANGE, {
|
this.serverLogs.log(LogType.MEMBER_USERNAME_CHANGE, {
|
||||||
member: stripObjectToScalars(member, ["user"]),
|
member: stripObjectToScalars(member, ["user"]),
|
||||||
oldName: `${oldUser.username}#${oldUser.discriminator}`,
|
oldName: `${oldUser.username}#${oldUser.discriminator}`,
|
||||||
newName: `${user.username}#${user.discriminator}`
|
newName: `${user.username}#${user.discriminator}`
|
||||||
|
@ -197,28 +189,28 @@ export class LogsPlugin extends Plugin {
|
||||||
|
|
||||||
@d.event("channelCreate")
|
@d.event("channelCreate")
|
||||||
onChannelCreate(channel) {
|
onChannelCreate(channel) {
|
||||||
this.log(LogType.CHANNEL_CREATE, {
|
this.serverLogs.log(LogType.CHANNEL_CREATE, {
|
||||||
channel: stripObjectToScalars(channel)
|
channel: stripObjectToScalars(channel)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@d.event("channelDelete")
|
@d.event("channelDelete")
|
||||||
onChannelDelete(channel) {
|
onChannelDelete(channel) {
|
||||||
this.log(LogType.CHANNEL_DELETE, {
|
this.serverLogs.log(LogType.CHANNEL_DELETE, {
|
||||||
channel: stripObjectToScalars(channel)
|
channel: stripObjectToScalars(channel)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@d.event("guildRoleCreate")
|
@d.event("guildRoleCreate")
|
||||||
onRoleCreate(_, role) {
|
onRoleCreate(_, role) {
|
||||||
this.log(LogType.ROLE_CREATE, {
|
this.serverLogs.log(LogType.ROLE_CREATE, {
|
||||||
role: stripObjectToScalars(role)
|
role: stripObjectToScalars(role)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@d.event("guildRoleDelete")
|
@d.event("guildRoleDelete")
|
||||||
onRoleDelete(_, role) {
|
onRoleDelete(_, role) {
|
||||||
this.log(LogType.ROLE_DELETE, {
|
this.serverLogs.log(LogType.ROLE_DELETE, {
|
||||||
role: stripObjectToScalars(role)
|
role: stripObjectToScalars(role)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -226,8 +218,9 @@ export class LogsPlugin extends Plugin {
|
||||||
@d.event("messageUpdate")
|
@d.event("messageUpdate")
|
||||||
onMessageUpdate(msg: Message, oldMsg: Message) {
|
onMessageUpdate(msg: Message, oldMsg: Message) {
|
||||||
if (oldMsg && msg.content === oldMsg.content) return;
|
if (oldMsg && msg.content === oldMsg.content) return;
|
||||||
|
if (msg.type !== 0) return;
|
||||||
|
|
||||||
this.log(LogType.MESSAGE_EDIT, {
|
this.serverLogs.log(LogType.MESSAGE_EDIT, {
|
||||||
member: stripObjectToScalars(msg.member, ["user"]),
|
member: stripObjectToScalars(msg.member, ["user"]),
|
||||||
channel: stripObjectToScalars(msg.channel),
|
channel: stripObjectToScalars(msg.channel),
|
||||||
before: oldMsg ? oldMsg.content || "" : "Unavailable due to restart",
|
before: oldMsg ? oldMsg.content || "" : "Unavailable due to restart",
|
||||||
|
@ -237,16 +230,33 @@ export class LogsPlugin extends Plugin {
|
||||||
|
|
||||||
@d.event("messageDelete")
|
@d.event("messageDelete")
|
||||||
onMessageDelete(msg: Message) {
|
onMessageDelete(msg: Message) {
|
||||||
this.log(LogType.MESSAGE_DELETE, {
|
if (msg.type !== 0) return;
|
||||||
member: stripObjectToScalars(msg.member, ["user"]),
|
|
||||||
channel: stripObjectToScalars(msg.channel),
|
if (msg.member) {
|
||||||
messageText: msg.cleanContent || ""
|
this.serverLogs.log(
|
||||||
});
|
LogType.MESSAGE_DELETE,
|
||||||
|
{
|
||||||
|
member: stripObjectToScalars(msg.member, ["user"]),
|
||||||
|
channel: stripObjectToScalars(msg.channel),
|
||||||
|
messageText: msg.cleanContent || ""
|
||||||
|
},
|
||||||
|
msg.id
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.serverLogs.log(
|
||||||
|
LogType.MESSAGE_DELETE_BARE,
|
||||||
|
{
|
||||||
|
messageId: msg.id,
|
||||||
|
channel: stripObjectToScalars(msg.channel)
|
||||||
|
},
|
||||||
|
msg.id
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@d.event("messageDeleteBulk")
|
@d.event("messageDeleteBulk")
|
||||||
onMessageDeleteBulk(messages: Message[]) {
|
onMessageDeleteBulk(messages: Message[]) {
|
||||||
this.log(LogType.MESSAGE_DELETE_BULK, {
|
this.serverLogs.log(LogType.MESSAGE_DELETE_BULK, {
|
||||||
count: messages.length,
|
count: messages.length,
|
||||||
channel: messages[0] ? messages[0].channel : null
|
channel: messages[0] ? messages[0].channel : null
|
||||||
});
|
});
|
||||||
|
@ -254,7 +264,7 @@ export class LogsPlugin extends Plugin {
|
||||||
|
|
||||||
@d.event("voiceChannelJoin")
|
@d.event("voiceChannelJoin")
|
||||||
onVoiceChannelJoin(member: Member, channel: Channel) {
|
onVoiceChannelJoin(member: Member, channel: Channel) {
|
||||||
this.log(LogType.VOICE_CHANNEL_JOIN, {
|
this.serverLogs.log(LogType.VOICE_CHANNEL_JOIN, {
|
||||||
member: stripObjectToScalars(member, ["user"]),
|
member: stripObjectToScalars(member, ["user"]),
|
||||||
channel: stripObjectToScalars(channel)
|
channel: stripObjectToScalars(channel)
|
||||||
});
|
});
|
||||||
|
@ -262,7 +272,7 @@ export class LogsPlugin extends Plugin {
|
||||||
|
|
||||||
@d.event("voiceChannelLeave")
|
@d.event("voiceChannelLeave")
|
||||||
onVoiceChannelLeave(member: Member, channel: Channel) {
|
onVoiceChannelLeave(member: Member, channel: Channel) {
|
||||||
this.log(LogType.VOICE_CHANNEL_LEAVE, {
|
this.serverLogs.log(LogType.VOICE_CHANNEL_LEAVE, {
|
||||||
member: stripObjectToScalars(member, ["user"]),
|
member: stripObjectToScalars(member, ["user"]),
|
||||||
channel: stripObjectToScalars(channel)
|
channel: stripObjectToScalars(channel)
|
||||||
});
|
});
|
||||||
|
@ -270,7 +280,7 @@ export class LogsPlugin extends Plugin {
|
||||||
|
|
||||||
@d.event("voiceChannelSwitch")
|
@d.event("voiceChannelSwitch")
|
||||||
onVoiceChannelSwitch(member: Member, newChannel: Channel, oldChannel: Channel) {
|
onVoiceChannelSwitch(member: Member, newChannel: Channel, oldChannel: Channel) {
|
||||||
this.log(LogType.VOICE_CHANNEL_MOVE, {
|
this.serverLogs.log(LogType.VOICE_CHANNEL_MOVE, {
|
||||||
member: stripObjectToScalars(member, ["user"]),
|
member: stripObjectToScalars(member, ["user"]),
|
||||||
oldChannel: stripObjectToScalars(oldChannel),
|
oldChannel: stripObjectToScalars(oldChannel),
|
||||||
newChannel: stripObjectToScalars(newChannel)
|
newChannel: stripObjectToScalars(newChannel)
|
||||||
|
|
|
@ -220,6 +220,12 @@ export class ModActionsPlugin extends Plugin {
|
||||||
@d.command("warn", "<member:Member> <reason:string$>")
|
@d.command("warn", "<member:Member> <reason:string$>")
|
||||||
@d.permission("warn")
|
@d.permission("warn")
|
||||||
async warnCmd(msg: Message, args: any) {
|
async warnCmd(msg: Message, args: any) {
|
||||||
|
// Make sure we're allowed to warn this member
|
||||||
|
if (!this.canActOn(msg.member, args.member)) {
|
||||||
|
msg.channel.createMessage(errorMessage("Cannot warn: insufficient permissions"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const warnMessage = this.configValue("warn_message")
|
const warnMessage = this.configValue("warn_message")
|
||||||
.replace("{guildName}", this.guild.name)
|
.replace("{guildName}", this.guild.name)
|
||||||
.replace("{reason}", args.reason);
|
.replace("{reason}", args.reason);
|
||||||
|
@ -235,7 +241,7 @@ export class ModActionsPlugin extends Plugin {
|
||||||
const failedMsg = await msg.channel.createMessage(
|
const failedMsg = await msg.channel.createMessage(
|
||||||
"Failed to message the user. Log the warning anyway?"
|
"Failed to message the user. Log the warning anyway?"
|
||||||
);
|
);
|
||||||
const reply = await waitForReaction(this.bot, failedMsg, ["✅", "❌"]);
|
const reply = await waitForReaction(this.bot, failedMsg, ["✅", "❌"], msg.author.id);
|
||||||
failedMsg.delete();
|
failedMsg.delete();
|
||||||
if (!reply || reply.name === "❌") {
|
if (!reply || reply.name === "❌") {
|
||||||
return;
|
return;
|
||||||
|
@ -508,11 +514,11 @@ export class ModActionsPlugin extends Plugin {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@d.command("addcase", "<type:string> <target:userId> [reason:string$]")
|
@d.command("addcase", "<type:string> <target:string> [reason:string$]")
|
||||||
@d.permission("addcase")
|
@d.permission("addcase")
|
||||||
async addcaseCmd(msg: Message, args: any) {
|
async addcaseCmd(msg: Message, args: any) {
|
||||||
// Verify the user id is a valid snowflake-ish
|
// Verify the user id is a valid snowflake-ish
|
||||||
if (!args.type.match(/^[0-9]{17,20}$/)) {
|
if (!args.target.match(/^[0-9]{17,20}$/)) {
|
||||||
msg.channel.createMessage(errorMessage("Cannot add case: invalid user id"));
|
msg.channel.createMessage(errorMessage("Cannot add case: invalid user id"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -535,7 +541,7 @@ export class ModActionsPlugin extends Plugin {
|
||||||
|
|
||||||
// Create the case
|
// Create the case
|
||||||
const caseId = await this.createCase(
|
const caseId = await this.createCase(
|
||||||
args.userId,
|
args.target,
|
||||||
msg.author.id,
|
msg.author.id,
|
||||||
CaseType[type],
|
CaseType[type],
|
||||||
null,
|
null,
|
||||||
|
|
Loading…
Add table
Reference in a new issue