3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-05-10 12:25:02 +00:00

Typed log functions + more

This commit is contained in:
Dragory 2021-08-18 01:51:42 +03:00
parent d2ac700143
commit bed6589d48
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
166 changed files with 4021 additions and 869 deletions

View file

@ -30,13 +30,85 @@ import {
import { LogsThreadCreateEvt, LogsThreadDeleteEvt, LogsThreadUpdateEvt } from "./events/LogsThreadModifyEvts";
import { LogsGuildMemberUpdateEvt } from "./events/LogsUserUpdateEvts";
import { LogsVoiceStateUpdateEvt } from "./events/LogsVoiceChannelEvts";
import { ConfigSchema, FORMAT_NO_TIMESTAMP, LogsPluginType } from "./types";
import { ConfigSchema, FORMAT_NO_TIMESTAMP, ILogTypeData, LogsPluginType, TLogChannel } from "./types";
import { getLogMessage } from "./util/getLogMessage";
import { log } from "./util/log";
import { onMessageDelete } from "./util/onMessageDelete";
import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk";
import { onMessageUpdate } from "./util/onMessageUpdate";
import { Util } from "discord.js";
import { TemplateSafeValueContainer, TypedTemplateSafeValueContainer } from "../../templateFormatter";
import { mapToPublicFn } from "../../pluginUtils";
import { logAutomodAction } from "./logFunctions/logAutomodAction";
import { logBotAlert } from "./logFunctions/logBotAlert";
import { logCaseCreate } from "./logFunctions/logCaseCreate";
import { logCaseDelete } from "./logFunctions/logCaseDelete";
import { logCaseUpdate } from "./logFunctions/logCaseUpdate";
import { logCensor } from "./logFunctions/logCensor";
import { logChannelCreate } from "./logFunctions/logChannelCreate";
import { logChannelDelete } from "./logFunctions/logChannelDelete";
import { logChannelUpdate } from "./logFunctions/logChannelUpdate";
import { logClean } from "./logFunctions/logClean";
import { logEmojiCreate } from "./logFunctions/logEmojiCreate";
import { logEmojiDelete } from "./logFunctions/logEmojiDelete";
import { logEmojiUpdate } from "./logFunctions/logEmojiUpdate";
import { logMassBan } from "./logFunctions/logMassBan";
import { logMassMute } from "./logFunctions/logMassMute";
import { logMassUnban } from "./logFunctions/logMassUnban";
import { logMemberBan } from "./logFunctions/logMemberBan";
import { logMemberForceban } from "./logFunctions/logMemberForceban";
import { logMemberJoin } from "./logFunctions/logMemberJoin";
import { logMemberJoinWithPriorRecords } from "./logFunctions/logMemberJoinWithPriorRecords";
import { logMemberKick } from "./logFunctions/logMemberKick";
import { logMemberLeave } from "./logFunctions/logMemberLeave";
import { logMemberMute } from "./logFunctions/logMemberMute";
import { logMemberMuteExpired } from "./logFunctions/logMemberMuteExpired";
import { logMemberMuteRejoin } from "./logFunctions/logMemberMuteRejoin";
import { logMemberNickChange } from "./logFunctions/logMemberNickChange";
import { logMemberNote } from "./logFunctions/logMemberNote";
import { logMemberRestore } from "./logFunctions/logMemberRestore";
import { logMemberRoleAdd } from "./logFunctions/logMemberRoleAdd";
import { logMemberRoleChanges } from "./logFunctions/logMemberRoleChanges";
import { logMemberRoleRemove } from "./logFunctions/logMemberRoleRemove";
import { logMemberTimedBan } from "./logFunctions/logMemberTimedBan";
import { logMemberTimedMute } from "./logFunctions/logMemberTimedMute";
import { logMemberTimedUnmute } from "./logFunctions/logMemberTimedUnmute";
import { logMemberUnban } from "./logFunctions/logMemberUnban";
import { logMemberUnmute } from "./logFunctions/logMemberUnmute";
import { logMemberWarn } from "./logFunctions/logMemberWarn";
import { logMessageDelete } from "./logFunctions/logMessageDelete";
import { logMessageDeleteAuto } from "./logFunctions/logMessageDeleteAuto";
import { logMessageDeleteBare } from "./logFunctions/logMessageDeleteBare";
import { logMessageDeleteBulk } from "./logFunctions/logMessageDeleteBulk";
import { logMessageEdit } from "./logFunctions/logMessageEdit";
import { logMessageSpamDetected } from "./logFunctions/logMessageSpamDetected";
import { logOtherSpamDetected } from "./logFunctions/logOtherSpamDetected";
import { logPostedScheduledMessage } from "./logFunctions/logPostedScheduledMessage";
import { logRepeatedMessage } from "./logFunctions/logRepeatedMessage";
import { logRoleCreate } from "./logFunctions/logRoleCreate";
import { logRoleDelete } from "./logFunctions/logRoleDelete";
import { logRoleUpdate } from "./logFunctions/logRoleUpdate";
import { logScheduledMessage } from "./logFunctions/logScheduledMessage";
import { logScheduledRepeatedMessage } from "./logFunctions/logScheduledRepeatedMessage";
import { logSetAntiraidAuto } from "./logFunctions/logSetAntiraidAuto";
import { logSetAntiraidUser } from "./logFunctions/logSetAntiraidUser";
import { logStageInstanceCreate } from "./logFunctions/logStageInstanceCreate";
import { logStageInstanceDelete } from "./logFunctions/logStageInstanceDelete";
import { logStageInstanceUpdate } from "./logFunctions/logStageInstanceUpdate";
import { logStickerCreate } from "./logFunctions/logStickerCreate";
import { logStickerDelete } from "./logFunctions/logStickerDelete";
import { logStickerUpdate } from "./logFunctions/logStickerUpdate";
import { logThreadCreate } from "./logFunctions/logThreadCreate";
import { logThreadDelete } from "./logFunctions/logThreadDelete";
import { logThreadUpdate } from "./logFunctions/logThreadUpdate";
import { logVoiceChannelForceDisconnect } from "./logFunctions/logVoiceChannelForceDisconnect";
import { logVoiceChannelForceMove } from "./logFunctions/logVoiceChannelForceMove";
import { logVoiceChannelJoin } from "./logFunctions/logVoiceChannelJoin";
import { logVoiceChannelLeave } from "./logFunctions/logVoiceChannelLeave";
import { logVoiceChannelMove } from "./logFunctions/logVoiceChannelMove";
import { logMemberTimedUnban } from "./logFunctions/logMemberTimedUnban";
import { logDmFailed } from "./logFunctions/logDmFailed";
const defaultOptions: PluginOptions<LogsPluginType> = {
config: {
@ -98,17 +170,85 @@ export const LogsPlugin = zeppelinGuildPlugin<LogsPluginType>()({
],
public: {
log(pluginData) {
return (type: LogType, data: any) => {
return log(pluginData, type, data);
getLogMessage: pluginData => {
return <TLogType extends keyof ILogTypeData>(
type: TLogType,
data: TypedTemplateSafeValueContainer<ILogTypeData[TLogType]>,
opts?: Pick<TLogChannel, "format" | "timestamp_format" | "include_embed_timestamp">,
) => {
return getLogMessage(pluginData, type, data, opts);
};
},
getLogMessage(pluginData) {
return (type: LogType, data: any) => {
return getLogMessage(pluginData, type, data);
};
},
logAutomodAction: mapToPublicFn(logAutomodAction),
logBotAlert: mapToPublicFn(logBotAlert),
logCaseCreate: mapToPublicFn(logCaseCreate),
logCaseDelete: mapToPublicFn(logCaseDelete),
logCaseUpdate: mapToPublicFn(logCaseUpdate),
logCensor: mapToPublicFn(logCensor),
logChannelCreate: mapToPublicFn(logChannelCreate),
logChannelDelete: mapToPublicFn(logChannelDelete),
logChannelUpdate: mapToPublicFn(logChannelUpdate),
logClean: mapToPublicFn(logClean),
logEmojiCreate: mapToPublicFn(logEmojiCreate),
logEmojiDelete: mapToPublicFn(logEmojiDelete),
logEmojiUpdate: mapToPublicFn(logEmojiUpdate),
logMassBan: mapToPublicFn(logMassBan),
logMassMute: mapToPublicFn(logMassMute),
logMassUnban: mapToPublicFn(logMassUnban),
logMemberBan: mapToPublicFn(logMemberBan),
logMemberForceban: mapToPublicFn(logMemberForceban),
logMemberJoin: mapToPublicFn(logMemberJoin),
logMemberJoinWithPriorRecords: mapToPublicFn(logMemberJoinWithPriorRecords),
logMemberKick: mapToPublicFn(logMemberKick),
logMemberLeave: mapToPublicFn(logMemberLeave),
logMemberMute: mapToPublicFn(logMemberMute),
logMemberMuteExpired: mapToPublicFn(logMemberMuteExpired),
logMemberMuteRejoin: mapToPublicFn(logMemberMuteRejoin),
logMemberNickChange: mapToPublicFn(logMemberNickChange),
logMemberNote: mapToPublicFn(logMemberNote),
logMemberRestore: mapToPublicFn(logMemberRestore),
logMemberRoleAdd: mapToPublicFn(logMemberRoleAdd),
logMemberRoleChanges: mapToPublicFn(logMemberRoleChanges),
logMemberRoleRemove: mapToPublicFn(logMemberRoleRemove),
logMemberTimedBan: mapToPublicFn(logMemberTimedBan),
logMemberTimedMute: mapToPublicFn(logMemberTimedMute),
logMemberTimedUnban: mapToPublicFn(logMemberTimedUnban),
logMemberTimedUnmute: mapToPublicFn(logMemberTimedUnmute),
logMemberUnban: mapToPublicFn(logMemberUnban),
logMemberUnmute: mapToPublicFn(logMemberUnmute),
logMemberWarn: mapToPublicFn(logMemberWarn),
logMessageDelete: mapToPublicFn(logMessageDelete),
logMessageDeleteAuto: mapToPublicFn(logMessageDeleteAuto),
logMessageDeleteBare: mapToPublicFn(logMessageDeleteBare),
logMessageDeleteBulk: mapToPublicFn(logMessageDeleteBulk),
logMessageEdit: mapToPublicFn(logMessageEdit),
logMessageSpamDetected: mapToPublicFn(logMessageSpamDetected),
logOtherSpamDetected: mapToPublicFn(logOtherSpamDetected),
logPostedScheduledMessage: mapToPublicFn(logPostedScheduledMessage),
logRepeatedMessage: mapToPublicFn(logRepeatedMessage),
logRoleCreate: mapToPublicFn(logRoleCreate),
logRoleDelete: mapToPublicFn(logRoleDelete),
logRoleUpdate: mapToPublicFn(logRoleUpdate),
logScheduledMessage: mapToPublicFn(logScheduledMessage),
logScheduledRepeatedMessage: mapToPublicFn(logScheduledRepeatedMessage),
logSetAntiraidAuto: mapToPublicFn(logSetAntiraidAuto),
logSetAntiraidUser: mapToPublicFn(logSetAntiraidUser),
logStageInstanceCreate: mapToPublicFn(logStageInstanceCreate),
logStageInstanceDelete: mapToPublicFn(logStageInstanceDelete),
logStageInstanceUpdate: mapToPublicFn(logStageInstanceUpdate),
logStickerCreate: mapToPublicFn(logStickerCreate),
logStickerDelete: mapToPublicFn(logStickerDelete),
logStickerUpdate: mapToPublicFn(logStickerUpdate),
logThreadCreate: mapToPublicFn(logThreadCreate),
logThreadDelete: mapToPublicFn(logThreadDelete),
logThreadUpdate: mapToPublicFn(logThreadUpdate),
logVoiceChannelForceDisconnect: mapToPublicFn(logVoiceChannelForceDisconnect),
logVoiceChannelForceMove: mapToPublicFn(logVoiceChannelForceMove),
logVoiceChannelJoin: mapToPublicFn(logVoiceChannelJoin),
logVoiceChannelLeave: mapToPublicFn(logVoiceChannelLeave),
logVoiceChannelMove: mapToPublicFn(logVoiceChannelMove),
logDmFailed: mapToPublicFn(logDmFailed),
},
beforeLoad(pluginData) {

View file

@ -1,14 +1,17 @@
import { LogType } from "../../../data/LogType";
import { differenceToString, getScalarDifference } from "../../../utils";
import { channelToConfigAccessibleChannel } from "../../../utils/configAccessibleObjects";
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
import { logsEvt } from "../types";
import { logChannelCreate } from "../logFunctions/logChannelCreate";
import { logChannelDelete } from "../logFunctions/logChannelDelete";
import { logChannelUpdate } from "../logFunctions/logChannelUpdate";
export const LogsChannelCreateEvt = logsEvt({
event: "channelCreate",
async listener(meta) {
meta.pluginData.state.guildLogs.log(LogType.CHANNEL_CREATE, {
channel: channelToConfigAccessibleChannel(meta.args.channel),
logChannelCreate(meta.pluginData, {
channel: meta.args.channel,
});
},
});
@ -17,8 +20,8 @@ export const LogsChannelDeleteEvt = logsEvt({
event: "channelDelete",
async listener(meta) {
meta.pluginData.state.guildLogs.log(LogType.CHANNEL_DELETE, {
channel: channelToConfigAccessibleChannel(meta.args.channel),
logChannelDelete(meta.pluginData, {
channel: meta.args.channel,
});
},
});
@ -30,14 +33,10 @@ export const LogsChannelUpdateEvt = logsEvt({
const diff = getScalarDifference(meta.args.oldChannel, meta.args.newChannel);
const differenceString = differenceToString(diff);
meta.pluginData.state.guildLogs.log(
LogType.CHANNEL_UPDATE,
{
oldChannel: channelToConfigAccessibleChannel(meta.args.oldChannel),
newChannel: channelToConfigAccessibleChannel(meta.args.newChannel),
differenceString,
},
meta.args.newChannel.id,
);
logChannelUpdate(meta.pluginData, {
oldChannel: meta.args.oldChannel,
newChannel: meta.args.newChannel,
differenceString,
});
},
});

View file

@ -1,18 +1,18 @@
import { LogType } from "../../../data/LogType";
import { differenceToString, getScalarDifference } from "../../../utils";
import {
channelToConfigAccessibleChannel,
emojiToConfigAccessibleEmoji,
stickerToConfigAccessibleSticker,
} from "../../../utils/configAccessibleObjects";
import { logsEvt } from "../types";
import { logEmojiCreate } from "../logFunctions/logEmojiCreate";
import { logEmojiDelete } from "../logFunctions/logEmojiDelete";
import { logEmojiUpdate } from "../logFunctions/logEmojiUpdate";
import { logStickerCreate } from "../logFunctions/logStickerCreate";
import { logStickerDelete } from "../logFunctions/logStickerDelete";
import { logStickerUpdate } from "../logFunctions/logStickerUpdate";
export const LogsEmojiCreateEvt = logsEvt({
event: "emojiCreate",
async listener(meta) {
meta.pluginData.state.guildLogs.log(LogType.EMOJI_CREATE, {
emoji: emojiToConfigAccessibleEmoji(meta.args.emoji),
logEmojiCreate(meta.pluginData, {
emoji: meta.args.emoji,
});
},
});
@ -21,8 +21,8 @@ export const LogsEmojiDeleteEvt = logsEvt({
event: "emojiDelete",
async listener(meta) {
meta.pluginData.state.guildLogs.log(LogType.EMOJI_DELETE, {
emoji: emojiToConfigAccessibleEmoji(meta.args.emoji),
logEmojiDelete(meta.pluginData, {
emoji: meta.args.emoji,
});
},
});
@ -34,9 +34,9 @@ export const LogsEmojiUpdateEvt = logsEvt({
const diff = getScalarDifference(meta.args.oldEmoji, meta.args.newEmoji);
const differenceString = differenceToString(diff);
meta.pluginData.state.guildLogs.log(LogType.EMOJI_UPDATE, {
oldEmoji: emojiToConfigAccessibleEmoji(meta.args.oldEmoji),
newEmoji: emojiToConfigAccessibleEmoji(meta.args.newEmoji),
logEmojiUpdate(meta.pluginData, {
oldEmoji: meta.args.oldEmoji,
newEmoji: meta.args.newEmoji,
differenceString,
});
},
@ -46,8 +46,8 @@ export const LogsStickerCreateEvt = logsEvt({
event: "stickerCreate",
async listener(meta) {
meta.pluginData.state.guildLogs.log(LogType.STICKER_CREATE, {
sticker: stickerToConfigAccessibleSticker(meta.args.sticker),
logStickerCreate(meta.pluginData, {
sticker: meta.args.sticker,
});
},
});
@ -56,8 +56,8 @@ export const LogsStickerDeleteEvt = logsEvt({
event: "stickerDelete",
async listener(meta) {
meta.pluginData.state.guildLogs.log(LogType.STICKER_DELETE, {
sticker: stickerToConfigAccessibleSticker(meta.args.sticker),
logStickerDelete(meta.pluginData, {
sticker: meta.args.sticker,
});
},
});
@ -69,14 +69,10 @@ export const LogsStickerUpdateEvt = logsEvt({
const diff = getScalarDifference(meta.args.oldSticker, meta.args.newSticker);
const differenceString = differenceToString(diff);
meta.pluginData.state.guildLogs.log(
LogType.STICKER_UPDATE,
{
oldSticker: stickerToConfigAccessibleSticker(meta.args.oldSticker),
newSticker: stickerToConfigAccessibleSticker(meta.args.newSticker),
differenceString,
},
meta.args.newSticker.id,
);
logStickerUpdate(meta.pluginData, {
oldSticker: meta.args.oldSticker,
newSticker: meta.args.newSticker,
differenceString,
});
},
});

View file

@ -1,8 +1,11 @@
import { GuildAuditLogs } from "discord.js";
import { LogType } from "../../../data/LogType";
import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry";
import { logsEvt } from "../types";
import { logMemberBan } from "../logFunctions/logMemberBan";
import { isLogIgnored } from "../util/isLogIgnored";
import { logMemberUnban } from "../logFunctions/logMemberUnban";
export const LogsGuildBanAddEvt = logsEvt({
event: "guildBanAdd",
@ -11,21 +14,22 @@ export const LogsGuildBanAddEvt = logsEvt({
const pluginData = meta.pluginData;
const user = meta.args.ban.user;
if (isLogIgnored(pluginData, LogType.MEMBER_BAN, user.id)) {
return;
}
const relevantAuditLogEntry = await safeFindRelevantAuditLogEntry(
pluginData,
GuildAuditLogs.Actions.MEMBER_BAN_ADD as number,
user.id,
);
const mod = relevantAuditLogEntry?.executor ?? null;
pluginData.state.guildLogs.log(
LogType.MEMBER_BAN,
{
mod: mod ? userToConfigAccessibleUser(mod) : {},
user: userToConfigAccessibleUser(user),
},
user.id,
);
logMemberBan(meta.pluginData, {
mod,
user,
caseNumber: 0,
reason: "",
});
},
});
@ -36,6 +40,10 @@ export const LogsGuildBanRemoveEvt = logsEvt({
const pluginData = meta.pluginData;
const user = meta.args.ban.user;
if (isLogIgnored(pluginData, LogType.MEMBER_UNBAN, user.id)) {
return;
}
const relevantAuditLogEntry = await safeFindRelevantAuditLogEntry(
pluginData,
GuildAuditLogs.Actions.MEMBER_BAN_REMOVE as number,
@ -43,13 +51,11 @@ export const LogsGuildBanRemoveEvt = logsEvt({
);
const mod = relevantAuditLogEntry?.executor ?? null;
pluginData.state.guildLogs.log(
LogType.MEMBER_UNBAN,
{
mod: mod ? userToConfigAccessibleUser(mod) : {},
userId: user.id,
},
user.id,
);
logMemberUnban(pluginData, {
mod,
userId: user.id,
caseNumber: 0,
reason: "",
});
},
});

View file

@ -1,9 +1,11 @@
import humanizeDuration from "humanize-duration";
import moment from "moment-timezone";
import { LogType } from "../../../data/LogType";
import { memberToConfigAccessibleMember } from "../../../utils/configAccessibleObjects";
import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
import { CasesPlugin } from "../../Cases/CasesPlugin";
import { logsEvt } from "../types";
import { logMemberJoin } from "../logFunctions/logMemberJoin";
import { logMemberJoinWithPriorRecords } from "../logFunctions/logMemberJoinWithPriorRecords";
export const LogsGuildMemberAddEvt = logsEvt({
event: "guildMemberAdd",
@ -12,16 +14,8 @@ export const LogsGuildMemberAddEvt = logsEvt({
const pluginData = meta.pluginData;
const member = meta.args.member;
const newThreshold = moment.utc().valueOf() - 1000 * 60 * 60;
const accountAge = humanizeDuration(moment.utc().valueOf() - member.user.createdTimestamp, {
largest: 2,
round: true,
});
pluginData.state.guildLogs.log(LogType.MEMBER_JOIN, {
member: memberToConfigAccessibleMember(member),
new: member.user.createdTimestamp >= newThreshold ? " :new:" : "",
account_age: accountAge,
logMemberJoin(pluginData, {
member,
});
const cases = (await pluginData.state.cases.with("notes").getByUserId(member.id)).filter(c => !c.is_hidden);
@ -45,8 +39,8 @@ export const LogsGuildMemberAddEvt = logsEvt({
}
}
pluginData.state.guildLogs.log(LogType.MEMBER_JOIN_WITH_PRIOR_RECORDS, {
member: memberToConfigAccessibleMember(member),
logMemberJoinWithPriorRecords(pluginData, {
member,
recentCaseSummary,
});
}

View file

@ -1,13 +1,14 @@
import { LogType } from "../../../data/LogType";
import { memberToConfigAccessibleMember } from "../../../utils/configAccessibleObjects";
import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
import { logsEvt } from "../types";
import { logMemberLeave } from "../logFunctions/logMemberLeave";
export const LogsGuildMemberRemoveEvt = logsEvt({
event: "guildMemberRemove",
async listener(meta) {
meta.pluginData.state.guildLogs.log(LogType.MEMBER_LEAVE, {
member: memberToConfigAccessibleMember(meta.args.member),
logMemberLeave(meta.pluginData, {
member: meta.args.member,
});
},
});

View file

@ -1,14 +1,17 @@
import { LogType } from "../../../data/LogType";
import { differenceToString, getScalarDifference } from "../../../utils";
import { roleToConfigAccessibleRole } from "../../../utils/configAccessibleObjects";
import { roleToTemplateSafeRole } from "../../../utils/templateSafeObjects";
import { logsEvt } from "../types";
import { logRoleCreate } from "../logFunctions/logRoleCreate";
import { logRoleDelete } from "../logFunctions/logRoleDelete";
import { logRoleUpdate } from "../logFunctions/logRoleUpdate";
export const LogsRoleCreateEvt = logsEvt({
event: "roleCreate",
async listener(meta) {
meta.pluginData.state.guildLogs.log(LogType.ROLE_CREATE, {
role: roleToConfigAccessibleRole(meta.args.role),
logRoleCreate(meta.pluginData, {
role: meta.args.role,
});
},
});
@ -17,8 +20,8 @@ export const LogsRoleDeleteEvt = logsEvt({
event: "roleDelete",
async listener(meta) {
meta.pluginData.state.guildLogs.log(LogType.ROLE_DELETE, {
role: roleToConfigAccessibleRole(meta.args.role),
logRoleDelete(meta.pluginData, {
role: meta.args.role,
});
},
});
@ -30,9 +33,9 @@ export const LogsRoleUpdateEvt = logsEvt({
const diff = getScalarDifference(meta.args.oldRole, meta.args.newRole);
const differenceString = differenceToString(diff);
meta.pluginData.state.guildLogs.log(LogType.ROLE_UPDATE, {
newRole: roleToConfigAccessibleRole(meta.args.newRole),
oldRole: roleToConfigAccessibleRole(meta.args.oldRole),
logRoleUpdate(meta.pluginData, {
newRole: meta.args.newRole,
oldRole: meta.args.oldRole,
differenceString,
});
},

View file

@ -1,7 +1,11 @@
import { LogType } from "../../../data/LogType";
import { differenceToString, getScalarDifference } from "../../../utils";
import { channelToConfigAccessibleChannel, stageToConfigAccessibleStage } from "../../../utils/configAccessibleObjects";
import { channelToTemplateSafeChannel, stageToTemplateSafeStage } from "../../../utils/templateSafeObjects";
import { logsEvt } from "../types";
import { logStageInstanceCreate } from "../logFunctions/logStageInstanceCreate";
import { StageChannel } from "discord.js";
import { logStageInstanceDelete } from "../logFunctions/logStageInstanceDelete";
import { logStageInstanceUpdate } from "../logFunctions/logStageInstanceUpdate";
export const LogsStageInstanceCreateEvt = logsEvt({
event: "stageInstanceCreate",
@ -9,11 +13,11 @@ export const LogsStageInstanceCreateEvt = logsEvt({
async listener(meta) {
const stageChannel =
meta.args.stageInstance.channel ??
(await meta.pluginData.guild.channels.fetch(meta.args.stageInstance.channelId))!;
((await meta.pluginData.guild.channels.fetch(meta.args.stageInstance.channelId)) as StageChannel);
meta.pluginData.state.guildLogs.log(LogType.STAGE_INSTANCE_CREATE, {
stageInstance: stageToConfigAccessibleStage(meta.args.stageInstance),
stageChannel: channelToConfigAccessibleChannel(stageChannel),
logStageInstanceCreate(meta.pluginData, {
stageInstance: meta.args.stageInstance,
stageChannel,
});
},
});
@ -24,11 +28,11 @@ export const LogsStageInstanceDeleteEvt = logsEvt({
async listener(meta) {
const stageChannel =
meta.args.stageInstance.channel ??
(await meta.pluginData.guild.channels.fetch(meta.args.stageInstance.channelId))!;
((await meta.pluginData.guild.channels.fetch(meta.args.stageInstance.channelId)) as StageChannel);
meta.pluginData.state.guildLogs.log(LogType.STAGE_INSTANCE_DELETE, {
stageInstance: stageToConfigAccessibleStage(meta.args.stageInstance),
stageChannel: channelToConfigAccessibleChannel(stageChannel),
logStageInstanceDelete(meta.pluginData, {
stageInstance: meta.args.stageInstance,
stageChannel,
});
},
});
@ -39,15 +43,15 @@ export const LogsStageInstanceUpdateEvt = logsEvt({
async listener(meta) {
const stageChannel =
meta.args.newStageInstance.channel ??
(await meta.pluginData.guild.channels.fetch(meta.args.newStageInstance.channelId))!;
((await meta.pluginData.guild.channels.fetch(meta.args.newStageInstance.channelId)) as StageChannel);
const diff = getScalarDifference(meta.args.oldStageInstance, meta.args.newStageInstance);
const differenceString = differenceToString(diff);
meta.pluginData.state.guildLogs.log(LogType.STAGE_INSTANCE_UPDATE, {
oldStageInstance: stageToConfigAccessibleStage(meta.args.oldStageInstance),
newStageInstance: stageToConfigAccessibleStage(meta.args.newStageInstance),
stageChannel: channelToConfigAccessibleChannel(stageChannel),
logStageInstanceUpdate(meta.pluginData, {
oldStageInstance: meta.args.oldStageInstance,
newStageInstance: meta.args.newStageInstance,
stageChannel,
differenceString,
});
},

View file

@ -1,14 +1,17 @@
import { LogType } from "../../../data/LogType";
import { differenceToString, getScalarDifference } from "../../../utils";
import { channelToConfigAccessibleChannel } from "../../../utils/configAccessibleObjects";
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
import { logsEvt } from "../types";
import { logThreadCreate } from "../logFunctions/logThreadCreate";
import { logThreadDelete } from "../logFunctions/logThreadDelete";
import { logThreadUpdate } from "../logFunctions/logThreadUpdate";
export const LogsThreadCreateEvt = logsEvt({
event: "threadCreate",
async listener(meta) {
meta.pluginData.state.guildLogs.log(LogType.THREAD_CREATE, {
thread: channelToConfigAccessibleChannel(meta.args.thread),
logThreadCreate(meta.pluginData, {
thread: meta.args.thread,
});
},
});
@ -17,8 +20,8 @@ export const LogsThreadDeleteEvt = logsEvt({
event: "threadDelete",
async listener(meta) {
meta.pluginData.state.guildLogs.log(LogType.THREAD_DELETE, {
thread: channelToConfigAccessibleChannel(meta.args.thread),
logThreadDelete(meta.pluginData, {
thread: meta.args.thread,
});
},
});
@ -30,14 +33,10 @@ export const LogsThreadUpdateEvt = logsEvt({
const diff = getScalarDifference(meta.args.oldThread, meta.args.newThread, ["messageCount", "archiveTimestamp"]);
const differenceString = differenceToString(diff);
meta.pluginData.state.guildLogs.log(
LogType.THREAD_UPDATE,
{
oldThread: channelToConfigAccessibleChannel(meta.args.oldThread),
newThread: channelToConfigAccessibleChannel(meta.args.newThread),
differenceString,
},
meta.args.newThread.id,
);
logThreadUpdate(meta.pluginData, {
oldThread: meta.args.oldThread,
newThread: meta.args.newThread,
differenceString,
});
},
});

View file

@ -1,10 +1,14 @@
import { GuildAuditLogs } from "discord.js";
import diff from "lodash.difference";
import isEqual from "lodash.isequal";
import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects";
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { LogType } from "../../../data/LogType";
import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry";
import { logsEvt } from "../types";
import { logMemberNickChange } from "../logFunctions/logMemberNickChange";
import { logMemberRoleChanges } from "../logFunctions/logMemberRoleChanges";
import { logMemberRoleAdd } from "../logFunctions/logMemberRoleAdd";
import { logMemberRoleRemove } from "../logFunctions/logMemberRoleRemove";
export const LogsGuildMemberUpdateEvt = logsEvt({
event: "guildMemberUpdate",
@ -16,11 +20,9 @@ export const LogsGuildMemberUpdateEvt = logsEvt({
if (!oldMember) return;
const logMember = memberToConfigAccessibleMember(member);
if (member.nickname !== oldMember.nickname) {
pluginData.state.guildLogs.log(LogType.MEMBER_NICK_CHANGE, {
member: logMember,
logMemberNickChange(pluginData, {
member,
oldNick: oldMember.nickname != null ? oldMember.nickname : "<none>",
newNick: member.nickname != null ? member.nickname : "<none>",
});
@ -56,50 +58,38 @@ export const LogsGuildMemberUpdateEvt = logsEvt({
if (addedRoles.length && removedRoles.length) {
// Roles added *and* removed
pluginData.state.guildLogs.log(
LogType.MEMBER_ROLE_CHANGES,
{
member: logMember,
addedRoles: addedRoles
.map(roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` })
.map(r => r.name)
.join(", "),
removedRoles: removedRoles
.map(roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` })
.map(r => r.name)
.join(", "),
mod: mod ? userToConfigAccessibleUser(mod) : {},
},
member.id,
);
logMemberRoleChanges(pluginData, {
member,
addedRoles: addedRoles
.map(roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` })
.map(r => r.name)
.join(", "),
removedRoles: removedRoles
.map(roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` })
.map(r => r.name)
.join(", "),
mod,
});
} else if (addedRoles.length) {
// Roles added
pluginData.state.guildLogs.log(
LogType.MEMBER_ROLE_ADD,
{
member: logMember,
roles: addedRoles
.map(roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` })
.map(r => r.name)
.join(", "),
mod: mod ? userToConfigAccessibleUser(mod) : {},
},
member.id,
);
logMemberRoleAdd(pluginData, {
member,
roles: addedRoles
.map(roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` })
.map(r => r.name)
.join(", "),
mod,
});
} else if (removedRoles.length && !addedRoles.length) {
// Roles removed
pluginData.state.guildLogs.log(
LogType.MEMBER_ROLE_REMOVE,
{
member: logMember,
roles: removedRoles
.map(roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` })
.map(r => r.name)
.join(", "),
mod: mod ? userToConfigAccessibleUser(mod) : {},
},
member.id,
);
logMemberRoleRemove(pluginData, {
member,
roles: removedRoles
.map(roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` })
.map(r => r.name)
.join(", "),
mod,
});
}
}
}

View file

@ -1,9 +1,9 @@
import {
channelToConfigAccessibleChannel,
memberToConfigAccessibleMember,
} from "../../../utils/configAccessibleObjects";
import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
import { LogType } from "../../../data/LogType";
import { logsEvt } from "../types";
import { logVoiceChannelLeave } from "../logFunctions/logVoiceChannelLeave";
import { logVoiceChannelJoin } from "../logFunctions/logVoiceChannelJoin";
import { logVoiceChannelMove } from "../logFunctions/logVoiceChannelMove";
export const LogsVoiceStateUpdateEvt = logsEvt({
event: "voiceStateUpdate",
@ -15,21 +15,21 @@ export const LogsVoiceStateUpdateEvt = logsEvt({
if (!newChannel && oldChannel) {
// Leave evt
meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_LEAVE, {
member: memberToConfigAccessibleMember(member),
channel: channelToConfigAccessibleChannel(oldChannel!),
logVoiceChannelLeave(meta.pluginData, {
member,
channel: oldChannel,
});
} else if (!oldChannel && newChannel) {
// Join Evt
meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_JOIN, {
member: memberToConfigAccessibleMember(member),
channel: channelToConfigAccessibleChannel(newChannel),
logVoiceChannelJoin(meta.pluginData, {
member,
channel: newChannel,
});
} else {
meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_MOVE, {
member: memberToConfigAccessibleMember(member),
oldChannel: channelToConfigAccessibleChannel(oldChannel!),
newChannel: channelToConfigAccessibleChannel(newChannel!),
} else if (oldChannel && newChannel) {
logVoiceChannelMove(meta.pluginData, {
member,
oldChannel,
newChannel,
});
}
},

View file

@ -0,0 +1,33 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogAutomodActionData {
rule: string;
user: User;
users: User[];
actionsTaken: string;
matchSummary: string;
}
export function logAutomodAction(pluginData: GuildPluginData<LogsPluginType>, data: LogAutomodActionData) {
return log(
pluginData,
LogType.AUTOMOD_ACTION,
createTypedTemplateSafeValueContainer({
rule: data.rule,
user: userToTemplateSafeUser(data.user),
users: data.users.map(user => userToTemplateSafeUser(user)),
actionsTaken: data.actionsTaken,
matchSummary: data.matchSummary,
}),
{
userId: data.user.id,
bot: data.user.bot,
},
);
}

View file

@ -0,0 +1,20 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
interface LogBotAlertData {
body: string;
}
export function logBotAlert(pluginData: GuildPluginData<LogsPluginType>, data: LogBotAlertData) {
return log(
pluginData,
LogType.BOT_ALERT,
createTypedTemplateSafeValueContainer({
body: data.body,
}),
{},
);
}

View file

@ -0,0 +1,32 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogCaseCreateData {
mod: User;
userId: string;
caseNum: number;
caseType: string;
reason: string;
}
export function logCaseCreate(pluginData: GuildPluginData<LogsPluginType>, data: LogCaseCreateData) {
return log(
pluginData,
LogType.CASE_CREATE,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
userId: data.userId,
caseNum: data.caseNum,
caseType: data.caseType,
reason: data.reason,
}),
{
userId: data.userId,
},
);
}

View file

@ -0,0 +1,25 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember } from "discord.js";
import { caseToTemplateSafeCase, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
import { Case } from "../../../data/entities/Case";
interface LogCaseDeleteData {
mod: GuildMember;
case: Case;
}
export function logCaseDelete(pluginData: GuildPluginData<LogsPluginType>, data: LogCaseDeleteData) {
return log(
pluginData,
LogType.CASE_DELETE,
createTypedTemplateSafeValueContainer({
mod: memberToTemplateSafeMember(data.mod),
case: caseToTemplateSafeCase(data.case),
}),
{},
);
}

View file

@ -0,0 +1,28 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogCaseUpdateData {
mod: User;
caseNumber: number;
caseType: string;
note: string;
}
export function logCaseUpdate(pluginData: GuildPluginData<LogsPluginType>, data: LogCaseUpdateData) {
return log(
pluginData,
LogType.CASE_UPDATE,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
caseNumber: data.caseNumber,
caseType: data.caseType,
note: data.note,
}),
{},
);
}

View file

@ -0,0 +1,41 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js";
import {
channelToTemplateSafeChannel,
savedMessageToTemplateSafeSavedMessage,
userToTemplateSafeUser,
} from "../../../utils/templateSafeObjects";
import { SavedMessage } from "../../../data/entities/SavedMessage";
import { UnknownUser } from "../../../utils";
import { deactivateMentions, disableCodeBlocks } from "knub/dist/helpers";
interface LogCensorData {
user: User | UnknownUser;
channel: BaseGuildTextChannel | ThreadChannel;
reason: string;
message: SavedMessage;
}
export function logCensor(pluginData: GuildPluginData<LogsPluginType>, data: LogCensorData) {
return log(
pluginData,
LogType.CENSOR,
createTypedTemplateSafeValueContainer({
user: userToTemplateSafeUser(data.user),
channel: channelToTemplateSafeChannel(data.channel),
reason: data.reason,
message: savedMessageToTemplateSafeSavedMessage(data.message),
messageText: disableCodeBlocks(deactivateMentions(data.message.data.content)),
}),
{
userId: data.user.id,
channel: data.channel.id,
category: data.channel.parentId,
bot: data.user instanceof User ? data.user.bot : false,
},
);
}

View file

@ -0,0 +1,25 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildChannel, NewsChannel } from "discord.js";
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
interface LogChannelCreateData {
channel: GuildChannel | NewsChannel;
}
export function logChannelCreate(pluginData: GuildPluginData<LogsPluginType>, data: LogChannelCreateData) {
return log(
pluginData,
LogType.CHANNEL_CREATE,
createTypedTemplateSafeValueContainer({
channel: channelToTemplateSafeChannel(data.channel),
}),
{
channel: data.channel.id,
category: data.channel.parentId,
},
);
}

View file

@ -0,0 +1,25 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildChannel, NewsChannel } from "discord.js";
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
interface LogChannelDeleteData {
channel: GuildChannel | NewsChannel;
}
export function logChannelDelete(pluginData: GuildPluginData<LogsPluginType>, data: LogChannelDeleteData) {
return log(
pluginData,
LogType.CHANNEL_DELETE,
createTypedTemplateSafeValueContainer({
channel: channelToTemplateSafeChannel(data.channel),
}),
{
channel: data.channel.id,
category: data.channel.parentId,
},
);
}

View file

@ -0,0 +1,29 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildChannel, NewsChannel } from "discord.js";
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
interface LogChannelUpdateData {
oldChannel: GuildChannel | NewsChannel;
newChannel: GuildChannel | NewsChannel;
differenceString: string;
}
export function logChannelUpdate(pluginData: GuildPluginData<LogsPluginType>, data: LogChannelUpdateData) {
return log(
pluginData,
LogType.CHANNEL_UPDATE,
createTypedTemplateSafeValueContainer({
oldChannel: channelToTemplateSafeChannel(data.oldChannel),
newChannel: channelToTemplateSafeChannel(data.newChannel),
differenceString: data.differenceString,
}),
{
channel: data.newChannel.id,
category: data.newChannel.parentId,
},
);
}

View file

@ -0,0 +1,31 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildTextChannel, User } from "discord.js";
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogCleanData {
mod: User;
channel: BaseGuildTextChannel;
count: number;
archiveUrl: string;
}
export function logClean(pluginData: GuildPluginData<LogsPluginType>, data: LogCleanData) {
return log(
pluginData,
LogType.CLEAN,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
channel: channelToTemplateSafeChannel(data.channel),
count: data.count,
archiveUrl: data.archiveUrl,
}),
{
channel: data.channel.id,
category: data.channel.parentId,
},
);
}

View file

@ -0,0 +1,28 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { UnknownUser } from "../../../utils";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogDmFailedData {
source: string;
user: User | UnknownUser;
}
export function logDmFailed(pluginData: GuildPluginData<LogsPluginType>, data: LogDmFailedData) {
return log(
pluginData,
LogType.DM_FAILED,
createTypedTemplateSafeValueContainer({
source: data.source,
user: userToTemplateSafeUser(data.user),
}),
{
userId: data.user.id,
bot: data.user instanceof User ? data.user.bot : false,
},
);
}

View file

@ -0,0 +1,22 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { Emoji } from "discord.js";
import { emojiToTemplateSafeEmoji } from "../../../utils/templateSafeObjects";
interface LogEmojiCreateData {
emoji: Emoji;
}
export function logEmojiCreate(pluginData: GuildPluginData<LogsPluginType>, data: LogEmojiCreateData) {
return log(
pluginData,
LogType.EMOJI_CREATE,
createTypedTemplateSafeValueContainer({
emoji: emojiToTemplateSafeEmoji(data.emoji),
}),
{},
);
}

View file

@ -0,0 +1,22 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { Emoji } from "discord.js";
import { emojiToTemplateSafeEmoji } from "../../../utils/templateSafeObjects";
interface LogEmojiDeleteData {
emoji: Emoji;
}
export function logEmojiDelete(pluginData: GuildPluginData<LogsPluginType>, data: LogEmojiDeleteData) {
return log(
pluginData,
LogType.EMOJI_DELETE,
createTypedTemplateSafeValueContainer({
emoji: emojiToTemplateSafeEmoji(data.emoji),
}),
{},
);
}

View file

@ -0,0 +1,26 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { Emoji } from "discord.js";
import { emojiToTemplateSafeEmoji } from "../../../utils/templateSafeObjects";
interface LogEmojiUpdateData {
oldEmoji: Emoji;
newEmoji: Emoji;
differenceString: string;
}
export function logEmojiUpdate(pluginData: GuildPluginData<LogsPluginType>, data: LogEmojiUpdateData) {
return log(
pluginData,
LogType.EMOJI_UPDATE,
createTypedTemplateSafeValueContainer({
oldEmoji: emojiToTemplateSafeEmoji(data.oldEmoji),
newEmoji: emojiToTemplateSafeEmoji(data.newEmoji),
differenceString: data.differenceString,
}),
{},
);
}

View file

@ -0,0 +1,26 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogMassBanData {
mod: User;
count: number;
reason: string;
}
export function logMassBan(pluginData: GuildPluginData<LogsPluginType>, data: LogMassBanData) {
return log(
pluginData,
LogType.MASSBAN,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
count: data.count,
reason: data.reason,
}),
{},
);
}

View file

@ -0,0 +1,24 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogMassMuteData {
mod: User;
count: number;
}
export function logMassMute(pluginData: GuildPluginData<LogsPluginType>, data: LogMassMuteData) {
return log(
pluginData,
LogType.MASSMUTE,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
count: data.count,
}),
{},
);
}

View file

@ -0,0 +1,26 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogMassUnbanData {
mod: User;
count: number;
reason: string;
}
export function logMassUnban(pluginData: GuildPluginData<LogsPluginType>, data: LogMassUnbanData) {
return log(
pluginData,
LogType.MASSUNBAN,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
count: data.count,
reason: data.reason,
}),
{},
);
}

View file

@ -0,0 +1,32 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { UnknownUser } from "../../../utils";
interface LogMemberBanData {
mod: User | UnknownUser | null;
user: User | UnknownUser;
caseNumber: number;
reason: string;
}
export function logMemberBan(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberBanData) {
return log(
pluginData,
LogType.MEMBER_BAN,
createTypedTemplateSafeValueContainer({
mod: data.mod ? userToTemplateSafeUser(data.mod) : null,
user: userToTemplateSafeUser(data.user),
caseNumber: data.caseNumber,
reason: data.reason,
}),
{
userId: data.user.id,
bot: data.user instanceof User ? data.user.bot : false,
},
);
}

View file

@ -0,0 +1,30 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember, Snowflake } from "discord.js";
import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
interface LogMemberForcebanData {
mod: GuildMember;
userId: Snowflake;
caseNumber: number;
reason: string;
}
export function logMemberForceban(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberForcebanData) {
return log(
pluginData,
LogType.MEMBER_FORCEBAN,
createTypedTemplateSafeValueContainer({
mod: memberToTemplateSafeMember(data.mod),
userId: data.userId,
caseNumber: data.caseNumber,
reason: data.reason,
}),
{
userId: data.userId,
},
);
}

View file

@ -0,0 +1,35 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember } from "discord.js";
import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
import moment from "moment-timezone";
import humanizeDuration from "humanize-duration";
interface LogMemberJoinData {
member: GuildMember;
}
export function logMemberJoin(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberJoinData) {
const newThreshold = moment.utc().valueOf() - 1000 * 60 * 60;
const accountAge = humanizeDuration(moment.utc().valueOf() - data.member.user.createdTimestamp, {
largest: 2,
round: true,
});
return log(
pluginData,
LogType.MEMBER_JOIN,
createTypedTemplateSafeValueContainer({
member: memberToTemplateSafeMember(data.member),
new: data.member.user.createdTimestamp >= newThreshold ? " :new:" : "",
account_age: accountAge,
}),
{
userId: data.member.id,
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,30 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember } from "discord.js";
import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
interface LogMemberJoinWithPriorRecordsData {
member: GuildMember;
recentCaseSummary: string;
}
export function logMemberJoinWithPriorRecords(
pluginData: GuildPluginData<LogsPluginType>,
data: LogMemberJoinWithPriorRecordsData,
) {
return log(
pluginData,
LogType.MEMBER_JOIN_WITH_PRIOR_RECORDS,
createTypedTemplateSafeValueContainer({
member: memberToTemplateSafeMember(data.member),
recentCaseSummary: data.recentCaseSummary,
}),
{
userId: data.member.id,
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,32 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember, User } from "discord.js";
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { UnknownUser } from "../../../utils";
interface LogMemberKickData {
mod: User | UnknownUser | null;
user: User;
caseNumber: number;
reason: string;
}
export function logMemberKick(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberKickData) {
return log(
pluginData,
LogType.MEMBER_KICK,
createTypedTemplateSafeValueContainer({
mod: data.mod ? userToTemplateSafeUser(data.mod) : null,
user: userToTemplateSafeUser(data.user),
caseNumber: data.caseNumber,
reason: data.reason,
}),
{
userId: data.user.id,
bot: data.user.bot,
},
);
}

View file

@ -0,0 +1,25 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember, PartialGuildMember } from "discord.js";
import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
interface LogMemberLeaveData {
member: GuildMember | PartialGuildMember;
}
export function logMemberLeave(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberLeaveData) {
return log(
pluginData,
LogType.MEMBER_LEAVE,
createTypedTemplateSafeValueContainer({
member: memberToTemplateSafeMember(data.member),
}),
{
userId: data.member.id,
bot: data.member.user?.bot ?? false,
},
);
}

View file

@ -0,0 +1,32 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember, User } from "discord.js";
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { UnknownUser } from "../../../utils";
interface LogMemberMuteData {
mod: User | UnknownUser;
user: User | UnknownUser;
caseNumber: number;
reason: string;
}
export function logMemberMute(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberMuteData) {
return log(
pluginData,
LogType.MEMBER_MUTE,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
user: userToTemplateSafeUser(data.user),
caseNumber: data.caseNumber,
reason: data.reason,
}),
{
userId: data.user.id,
bot: data.user instanceof User ? data.user.bot : false,
},
);
}

View file

@ -0,0 +1,40 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember } from "discord.js";
import {
memberToTemplateSafeMember,
TemplateSafeUnknownMember,
TemplateSafeUnknownUser,
} from "../../../utils/templateSafeObjects";
import { UnknownUser } from "../../../utils";
interface LogMemberMuteExpiredData {
member: GuildMember | UnknownUser;
}
export function logMemberMuteExpired(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberMuteExpiredData) {
const member =
data.member instanceof GuildMember
? memberToTemplateSafeMember(data.member)
: new TemplateSafeUnknownMember({ ...data.member, user: new TemplateSafeUnknownUser({ ...data.member }) });
const roles = data.member instanceof GuildMember ? Array.from(data.member.roles.cache.keys()) : [];
const bot = data.member instanceof GuildMember ? data.member.user.bot : false;
return log(
pluginData,
LogType.MEMBER_MUTE_EXPIRED,
createTypedTemplateSafeValueContainer({
member,
}),
{
userId: data.member.id,
roles,
bot,
},
);
}

View file

@ -0,0 +1,25 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember } from "discord.js";
import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
interface LogMemberMuteRejoinData {
member: GuildMember;
}
export function logMemberMuteRejoin(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberMuteRejoinData) {
return log(
pluginData,
LogType.MEMBER_MUTE_REJOIN,
createTypedTemplateSafeValueContainer({
member: memberToTemplateSafeMember(data.member),
}),
{
userId: data.member.id,
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,30 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember } from "discord.js";
import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
interface LogMemberNickChangeData {
member: GuildMember;
oldNick: string;
newNick: string;
}
export function logMemberNickChange(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberNickChangeData) {
return log(
pluginData,
LogType.MEMBER_NICK_CHANGE,
createTypedTemplateSafeValueContainer({
member: memberToTemplateSafeMember(data.member),
oldNick: data.oldNick,
newNick: data.newNick,
}),
{
userId: data.member.id,
roles: Array.from(data.member.roles.cache.keys()),
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,32 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { UnknownUser } from "../../../utils";
interface LogMemberNoteData {
mod: User;
user: User | UnknownUser;
caseNumber: number;
reason: string;
}
export function logMemberNote(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberNoteData) {
return log(
pluginData,
LogType.MEMBER_NOTE,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
user: userToTemplateSafeUser(data.user),
caseNumber: data.caseNumber,
reason: data.reason,
}),
{
userId: data.user.id,
bot: data.user instanceof User ? data.user.bot : false,
},
);
}

View file

@ -0,0 +1,28 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember } from "discord.js";
import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
interface LogMemberRestoreData {
member: GuildMember;
restoredData: string;
}
export function logMemberRestore(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberRestoreData) {
return log(
pluginData,
LogType.MEMBER_RESTORE,
createTypedTemplateSafeValueContainer({
member: memberToTemplateSafeMember(data.member),
restoredData: data.restoredData,
}),
{
userId: data.member.id,
roles: Array.from(data.member.roles.cache.keys()),
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,30 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember, Role, User } from "discord.js";
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogMemberRoleAddData {
mod: User | null;
member: GuildMember;
roles: Role[];
}
export function logMemberRoleAdd(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberRoleAddData) {
return log(
pluginData,
LogType.MEMBER_ROLE_ADD,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
member: memberToTemplateSafeMember(data.member),
roles: data.roles.map(r => r.name).join(", "),
}),
{
userId: data.member.id,
roles: Array.from(data.member.roles.cache.keys()),
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,32 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember, User } from "discord.js";
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { UnknownUser } from "../../../utils";
interface LogMemberRoleChangesData {
mod: User | UnknownUser | null;
member: GuildMember;
addedRoles: string;
removedRoles: string;
}
export function logMemberRoleChanges(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberRoleChangesData) {
return log(
pluginData,
LogType.MEMBER_ROLE_CHANGES,
createTypedTemplateSafeValueContainer({
mod: data.mod ? userToTemplateSafeUser(data.mod) : null,
member: memberToTemplateSafeMember(data.member),
addedRoles: data.addedRoles,
removedRoles: data.removedRoles,
}),
{
userId: data.member.id,
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,30 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember, Role, User } from "discord.js";
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogMemberRoleRemoveData {
mod: User | null;
member: GuildMember;
roles: Role[];
}
export function logMemberRoleRemove(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberRoleRemoveData) {
return log(
pluginData,
LogType.MEMBER_ROLE_REMOVE,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
member: memberToTemplateSafeMember(data.member),
roles: data.roles.map(r => r.name).join(", "),
}),
{
userId: data.member.id,
roles: Array.from(data.member.roles.cache.keys()),
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,34 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { UnknownUser } from "../../../utils";
interface LogMemberTimedBanData {
mod: User | UnknownUser;
user: User | UnknownUser;
banTime: string;
caseNumber: number;
reason: string;
}
export function logMemberTimedBan(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberTimedBanData) {
return log(
pluginData,
LogType.MEMBER_TIMED_BAN,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
user: userToTemplateSafeUser(data.user),
banTime: data.banTime,
caseNumber: data.caseNumber,
reason: data.reason,
}),
{
userId: data.user.id,
bot: data.user instanceof User ? data.user.bot : false,
},
);
}

View file

@ -0,0 +1,31 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { UnknownUser } from "../../../utils";
interface LogMemberTimedMuteData {
mod: User | UnknownUser;
user: User | UnknownUser;
time: string;
caseNumber: number;
reason: string;
}
export function logMemberTimedMute(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberTimedMuteData) {
return log(
pluginData,
LogType.MEMBER_TIMED_MUTE,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
user: userToTemplateSafeUser(data.user),
time: data.time,
caseNumber: data.caseNumber,
reason: data.reason,
}),
{},
);
}

View file

@ -0,0 +1,33 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { UnknownUser } from "../../../utils";
interface LogMemberTimedUnbanData {
mod: User | UnknownUser;
userId: string;
banTime: string;
caseNumber: number;
reason: string;
}
export function logMemberTimedUnban(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberTimedUnbanData) {
return log(
pluginData,
LogType.MEMBER_TIMED_UNBAN,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
userId: data.userId,
banTime: data.banTime,
caseNumber: data.caseNumber,
reason: data.reason,
}),
{
userId: data.userId,
},
);
}

View file

@ -0,0 +1,30 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogMemberTimedUnmuteData {
mod: User;
user: User;
time: string;
caseNumber: number;
reason: string;
}
export function logMemberTimedUnmute(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberTimedUnmuteData) {
return log(
pluginData,
LogType.MEMBER_TIMED_UNMUTE,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
user: userToTemplateSafeUser(data.user),
time: data.time,
caseNumber: data.caseNumber,
reason: data.reason,
}),
{},
);
}

View file

@ -0,0 +1,31 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember, Snowflake, User } from "discord.js";
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { UnknownUser } from "../../../utils";
interface LogMemberUnbanData {
mod: User | UnknownUser | null;
userId: Snowflake;
caseNumber: number;
reason: string;
}
export function logMemberUnban(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberUnbanData) {
return log(
pluginData,
LogType.MEMBER_UNBAN,
createTypedTemplateSafeValueContainer({
mod: data.mod ? userToTemplateSafeUser(data.mod) : null,
userId: data.userId,
caseNumber: data.caseNumber,
reason: data.reason,
}),
{
userId: data.userId,
},
);
}

View file

@ -0,0 +1,31 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember, User } from "discord.js";
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogMemberUnmuteData {
mod: GuildMember;
user: User;
caseNumber: number;
reason: string;
}
export function logMemberUnmute(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberUnmuteData) {
return log(
pluginData,
LogType.MEMBER_UNMUTE,
createTypedTemplateSafeValueContainer({
mod: memberToTemplateSafeMember(data.mod),
user: userToTemplateSafeUser(data.user),
caseNumber: data.caseNumber,
reason: data.reason,
}),
{
userId: data.user.id,
bot: data.user.bot,
},
);
}

View file

@ -0,0 +1,32 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember } from "discord.js";
import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
interface LogMemberWarnData {
mod: GuildMember;
member: GuildMember;
caseNumber: number;
reason: string;
}
export function logMemberWarn(pluginData: GuildPluginData<LogsPluginType>, data: LogMemberWarnData) {
return log(
pluginData,
LogType.MEMBER_WARN,
createTypedTemplateSafeValueContainer({
mod: memberToTemplateSafeMember(data.mod),
member: memberToTemplateSafeMember(data.member),
caseNumber: data.caseNumber,
reason: data.reason,
}),
{
userId: data.member.id,
roles: Array.from(data.member.roles.cache.keys()),
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,56 @@
import { GuildPluginData } from "knub";
import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js";
import {
channelToTemplateSafeChannel,
savedMessageToTemplateSafeSavedMessage,
userToTemplateSafeUser,
} from "../../../utils/templateSafeObjects";
import moment from "moment-timezone";
import { ISavedMessageAttachmentData, SavedMessage } from "../../../data/entities/SavedMessage";
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
import { UnknownUser, useMediaUrls } from "../../../utils";
interface LogMessageDeleteData {
user: User | UnknownUser;
channel: BaseGuildTextChannel | ThreadChannel;
message: SavedMessage;
}
export function logMessageDelete(pluginData: GuildPluginData<LogsPluginType>, data: LogMessageDeleteData) {
// Replace attachment URLs with media URLs
if (data.message.data.attachments) {
for (const attachment of data.message.data.attachments as ISavedMessageAttachmentData[]) {
attachment.url = useMediaUrls(attachment.url);
}
}
// See comment on FORMAT_NO_TIMESTAMP in types.ts
const config = pluginData.config.get();
const timestampFormat =
(config.format.timestamp !== FORMAT_NO_TIMESTAMP ? config.format.timestamp : null) ?? config.timestamp_format;
return log(
pluginData,
LogType.MESSAGE_DELETE,
createTypedTemplateSafeValueContainer({
user: userToTemplateSafeUser(data.user),
channel: channelToTemplateSafeChannel(data.channel),
message: savedMessageToTemplateSafeSavedMessage(data.message),
messageDate: pluginData
.getPlugin(TimeAndDatePlugin)
.inGuildTz(moment.utc(data.message.data.timestamp, "x"))
.format(timestampFormat),
}),
{
userId: data.user.id,
channel: data.channel.id,
category: data.channel.parentId,
messageTextContent: data.message.data.content,
bot: data.user instanceof User ? data.user.bot : false,
},
);
}

View file

@ -0,0 +1,39 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildTextChannel, User } from "discord.js";
import {
channelToTemplateSafeChannel,
savedMessageToTemplateSafeSavedMessage,
userToTemplateSafeUser,
} from "../../../utils/templateSafeObjects";
import { SavedMessage } from "../../../data/entities/SavedMessage";
import { UnknownUser } from "../../../utils";
interface LogMessageDeleteAutoData {
message: SavedMessage;
user: User | UnknownUser;
channel: BaseGuildTextChannel;
messageDate: string;
}
export function logMessageDeleteAuto(pluginData: GuildPluginData<LogsPluginType>, data: LogMessageDeleteAutoData) {
return log(
pluginData,
LogType.MESSAGE_DELETE_AUTO,
createTypedTemplateSafeValueContainer({
message: savedMessageToTemplateSafeSavedMessage(data.message),
user: userToTemplateSafeUser(data.user),
channel: channelToTemplateSafeChannel(data.channel),
messageDate: data.messageDate,
}),
{
userId: data.user.id,
bot: data.user.bot,
channel: data.channel.id,
category: data.channel.parentId,
},
);
}

View file

@ -0,0 +1,27 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildTextChannel, ThreadChannel } from "discord.js";
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
interface LogMessageDeleteBareData {
messageId: string;
channel: BaseGuildTextChannel | ThreadChannel;
}
export function logMessageDeleteBare(pluginData: GuildPluginData<LogsPluginType>, data: LogMessageDeleteBareData) {
return log(
pluginData,
LogType.MESSAGE_DELETE_BARE,
createTypedTemplateSafeValueContainer({
messageId: data.messageId,
channel: channelToTemplateSafeChannel(data.channel),
}),
{
channel: data.channel.id,
category: data.channel.parentId,
},
);
}

View file

@ -0,0 +1,31 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildTextChannel, ThreadChannel } from "discord.js";
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
interface LogMessageDeleteBulkData {
count: number;
authorIds: string[];
channel: BaseGuildTextChannel | ThreadChannel;
archiveUrl: string;
}
export function logMessageDeleteBulk(pluginData: GuildPluginData<LogsPluginType>, data: LogMessageDeleteBulkData) {
return log(
pluginData,
LogType.MESSAGE_DELETE_BULK,
createTypedTemplateSafeValueContainer({
count: data.count,
authorIds: data.authorIds,
channel: channelToTemplateSafeChannel(data.channel),
archiveUrl: data.archiveUrl,
}),
{
channel: data.channel.id,
category: data.channel.parentId,
},
);
}

View file

@ -0,0 +1,39 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildTextChannel, ThreadChannel, User } from "discord.js";
import {
channelToTemplateSafeChannel,
savedMessageToTemplateSafeSavedMessage,
userToTemplateSafeUser,
} from "../../../utils/templateSafeObjects";
import { SavedMessage } from "../../../data/entities/SavedMessage";
import { UnknownUser } from "../../../utils";
interface LogMessageEditData {
user: User | UnknownUser;
channel: BaseGuildTextChannel | ThreadChannel;
before: SavedMessage;
after: SavedMessage;
}
export function logMessageEdit(pluginData: GuildPluginData<LogsPluginType>, data: LogMessageEditData) {
return log(
pluginData,
LogType.MESSAGE_EDIT,
createTypedTemplateSafeValueContainer({
user: userToTemplateSafeUser(data.user),
channel: channelToTemplateSafeChannel(data.channel),
before: savedMessageToTemplateSafeSavedMessage(data.before),
after: savedMessageToTemplateSafeSavedMessage(data.after),
}),
{
userId: data.user.id,
channel: data.channel.id,
messageTextContent: data.after.data.content,
bot: data.user instanceof User ? data.user.bot : false,
},
);
}

View file

@ -0,0 +1,38 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildTextChannel, GuildChannel, GuildMember, ThreadChannel } from "discord.js";
import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
interface LogMessageSpamDetectedData {
member: GuildMember;
channel: GuildChannel | ThreadChannel;
description: string;
limit: number;
interval: number;
archiveUrl: string;
}
export function logMessageSpamDetected(pluginData: GuildPluginData<LogsPluginType>, data: LogMessageSpamDetectedData) {
return log(
pluginData,
LogType.MESSAGE_SPAM_DETECTED,
createTypedTemplateSafeValueContainer({
member: memberToTemplateSafeMember(data.member),
channel: channelToTemplateSafeChannel(data.channel),
description: data.description,
limit: data.limit,
interval: data.interval,
archiveUrl: data.archiveUrl,
}),
{
userId: data.member.id,
roles: Array.from(data.member.roles.cache.keys()),
channel: data.channel.id,
category: data.channel.parentId,
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,31 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { GuildMember } from "discord.js";
import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
interface LogOtherSpamDetectedData {
member: GuildMember;
description: string;
limit: number;
interval: number;
}
export function logOtherSpamDetected(pluginData: GuildPluginData<LogsPluginType>, data: LogOtherSpamDetectedData) {
return log(
pluginData,
LogType.OTHER_SPAM_DETECTED,
createTypedTemplateSafeValueContainer({
member: memberToTemplateSafeMember(data.member),
description: data.description,
limit: data.limit,
interval: data.interval,
}),
{
userId: data.member.id,
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,34 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildTextChannel, User } from "discord.js";
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogPostedScheduledMessageData {
author: User;
channel: BaseGuildTextChannel;
messageId: string;
}
export function logPostedScheduledMessage(
pluginData: GuildPluginData<LogsPluginType>,
data: LogPostedScheduledMessageData,
) {
return log(
pluginData,
LogType.POSTED_SCHEDULED_MESSAGE,
createTypedTemplateSafeValueContainer({
author: userToTemplateSafeUser(data.author),
channel: channelToTemplateSafeChannel(data.channel),
messageId: data.messageId,
}),
{
userId: data.author.id,
bot: data.author.bot,
channel: data.channel.id,
category: data.channel.parentId,
},
);
}

View file

@ -0,0 +1,39 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildTextChannel, User } from "discord.js";
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogRepeatedMessageData {
author: User;
channel: BaseGuildTextChannel;
datetime: string;
date: string;
time: string;
repeatInterval: string;
repeatDetails: string;
}
export function logRepeatedMessage(pluginData: GuildPluginData<LogsPluginType>, data: LogRepeatedMessageData) {
return log(
pluginData,
LogType.REPEATED_MESSAGE,
createTypedTemplateSafeValueContainer({
author: userToTemplateSafeUser(data.author),
channel: channelToTemplateSafeChannel(data.channel),
datetime: data.datetime,
date: data.date,
time: data.time,
repeatInterval: data.repeatInterval,
repeatDetails: data.repeatDetails,
}),
{
userId: data.author.id,
bot: data.author.bot,
channel: data.channel.id,
category: data.channel.parentId,
},
);
}

View file

@ -0,0 +1,22 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { Role } from "discord.js";
import { roleToTemplateSafeRole } from "../../../utils/templateSafeObjects";
interface LogRoleCreateData {
role: Role;
}
export function logRoleCreate(pluginData: GuildPluginData<LogsPluginType>, data: LogRoleCreateData) {
return log(
pluginData,
LogType.ROLE_CREATE,
createTypedTemplateSafeValueContainer({
role: roleToTemplateSafeRole(data.role),
}),
{},
);
}

View file

@ -0,0 +1,22 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { Role } from "discord.js";
import { roleToTemplateSafeRole } from "../../../utils/templateSafeObjects";
interface LogRoleDeleteData {
role: Role;
}
export function logRoleDelete(pluginData: GuildPluginData<LogsPluginType>, data: LogRoleDeleteData) {
return log(
pluginData,
LogType.ROLE_DELETE,
createTypedTemplateSafeValueContainer({
role: roleToTemplateSafeRole(data.role),
}),
{},
);
}

View file

@ -0,0 +1,26 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { Role } from "discord.js";
import { roleToTemplateSafeRole } from "../../../utils/templateSafeObjects";
interface LogRoleUpdateData {
oldRole: Role;
newRole: Role;
differenceString: string;
}
export function logRoleUpdate(pluginData: GuildPluginData<LogsPluginType>, data: LogRoleUpdateData) {
return log(
pluginData,
LogType.ROLE_UPDATE,
createTypedTemplateSafeValueContainer({
oldRole: roleToTemplateSafeRole(data.oldRole),
newRole: roleToTemplateSafeRole(data.newRole),
differenceString: data.differenceString,
}),
{},
);
}

View file

@ -0,0 +1,35 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildTextChannel, User } from "discord.js";
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogScheduledMessageData {
author: User;
channel: BaseGuildTextChannel;
datetime: string;
date: string;
time: string;
}
export function logScheduledMessage(pluginData: GuildPluginData<LogsPluginType>, data: LogScheduledMessageData) {
return log(
pluginData,
LogType.SCHEDULED_MESSAGE,
createTypedTemplateSafeValueContainer({
author: userToTemplateSafeUser(data.author),
channel: channelToTemplateSafeChannel(data.channel),
datetime: data.datetime,
date: data.date,
time: data.time,
}),
{
userId: data.author.id,
bot: data.author.bot,
channel: data.channel.id,
category: data.channel.parentId,
},
);
}

View file

@ -0,0 +1,42 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildTextChannel, User } from "discord.js";
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogScheduledRepeatedMessageData {
author: User;
channel: BaseGuildTextChannel;
datetime: string;
date: string;
time: string;
repeatInterval: string;
repeatDetails: string;
}
export function logScheduledRepeatedMessage(
pluginData: GuildPluginData<LogsPluginType>,
data: LogScheduledRepeatedMessageData,
) {
return log(
pluginData,
LogType.SCHEDULED_REPEATED_MESSAGE,
createTypedTemplateSafeValueContainer({
author: userToTemplateSafeUser(data.author),
channel: channelToTemplateSafeChannel(data.channel),
datetime: data.datetime,
date: data.date,
time: data.time,
repeatInterval: data.repeatInterval,
repeatDetails: data.repeatDetails,
}),
{
userId: data.author.id,
bot: data.author.bot,
channel: data.channel.id,
category: data.channel.parentId,
},
);
}

View file

@ -0,0 +1,20 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
interface LogSetAntiraidAutoData {
level: string;
}
export function logSetAntiraidAuto(pluginData: GuildPluginData<LogsPluginType>, data: LogSetAntiraidAutoData) {
return log(
pluginData,
LogType.SET_ANTIRAID_AUTO,
createTypedTemplateSafeValueContainer({
level: data.level,
}),
{},
);
}

View file

@ -0,0 +1,27 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { User } from "discord.js";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
interface LogSetAntiraidUserData {
level: string;
user: User;
}
export function logSetAntiraidUser(pluginData: GuildPluginData<LogsPluginType>, data: LogSetAntiraidUserData) {
return log(
pluginData,
LogType.SET_ANTIRAID_USER,
createTypedTemplateSafeValueContainer({
level: data.level,
user: userToTemplateSafeUser(data.user),
}),
{
userId: data.user.id,
bot: data.user.bot,
},
);
}

View file

@ -0,0 +1,27 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { StageChannel, StageInstance } from "discord.js";
import { channelToTemplateSafeChannel, stageToTemplateSafeStage } from "../../../utils/templateSafeObjects";
interface LogStageInstanceCreateData {
stageInstance: StageInstance;
stageChannel: StageChannel;
}
export function logStageInstanceCreate(pluginData: GuildPluginData<LogsPluginType>, data: LogStageInstanceCreateData) {
return log(
pluginData,
LogType.STAGE_INSTANCE_CREATE,
createTypedTemplateSafeValueContainer({
stageInstance: stageToTemplateSafeStage(data.stageInstance),
stageChannel: channelToTemplateSafeChannel(data.stageChannel),
}),
{
channel: data.stageInstance.channel!.id,
category: data.stageInstance.channel!.parentId,
},
);
}

View file

@ -0,0 +1,27 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { StageChannel, StageInstance } from "discord.js";
import { channelToTemplateSafeChannel, stageToTemplateSafeStage } from "../../../utils/templateSafeObjects";
interface LogStageInstanceDeleteData {
stageInstance: StageInstance;
stageChannel: StageChannel;
}
export function logStageInstanceDelete(pluginData: GuildPluginData<LogsPluginType>, data: LogStageInstanceDeleteData) {
return log(
pluginData,
LogType.STAGE_INSTANCE_DELETE,
createTypedTemplateSafeValueContainer({
stageInstance: stageToTemplateSafeStage(data.stageInstance),
stageChannel: channelToTemplateSafeChannel(data.stageChannel),
}),
{
channel: data.stageInstance.channel!.id,
category: data.stageInstance.channel!.parentId,
},
);
}

View file

@ -0,0 +1,31 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { StageChannel, StageInstance } from "discord.js";
import { channelToTemplateSafeChannel, stageToTemplateSafeStage } from "../../../utils/templateSafeObjects";
interface LogStageInstanceUpdateData {
oldStageInstance: StageInstance;
newStageInstance: StageInstance;
stageChannel: StageChannel;
differenceString: string;
}
export function logStageInstanceUpdate(pluginData: GuildPluginData<LogsPluginType>, data: LogStageInstanceUpdateData) {
return log(
pluginData,
LogType.STAGE_INSTANCE_UPDATE,
createTypedTemplateSafeValueContainer({
oldStageInstance: stageToTemplateSafeStage(data.oldStageInstance),
newStageInstance: stageToTemplateSafeStage(data.newStageInstance),
stageChannel: channelToTemplateSafeChannel(data.stageChannel),
differenceString: data.differenceString,
}),
{
channel: data.newStageInstance.channel!.id,
category: data.newStageInstance.channel!.parentId,
},
);
}

View file

@ -0,0 +1,22 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { Sticker } from "discord.js";
import { stickerToTemplateSafeSticker } from "../../../utils/templateSafeObjects";
interface LogStickerCreateData {
sticker: Sticker;
}
export function logStickerCreate(pluginData: GuildPluginData<LogsPluginType>, data: LogStickerCreateData) {
return log(
pluginData,
LogType.STICKER_CREATE,
createTypedTemplateSafeValueContainer({
sticker: stickerToTemplateSafeSticker(data.sticker),
}),
{},
);
}

View file

@ -0,0 +1,22 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { Sticker } from "discord.js";
import { stickerToTemplateSafeSticker } from "../../../utils/templateSafeObjects";
interface LogStickerDeleteData {
sticker: Sticker;
}
export function logStickerDelete(pluginData: GuildPluginData<LogsPluginType>, data: LogStickerDeleteData) {
return log(
pluginData,
LogType.STICKER_DELETE,
createTypedTemplateSafeValueContainer({
sticker: stickerToTemplateSafeSticker(data.sticker),
}),
{},
);
}

View file

@ -0,0 +1,26 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { Sticker } from "discord.js";
import { stickerToTemplateSafeSticker } from "../../../utils/templateSafeObjects";
interface LogStickerUpdateData {
oldSticker: Sticker;
newSticker: Sticker;
differenceString: string;
}
export function logStickerUpdate(pluginData: GuildPluginData<LogsPluginType>, data: LogStickerUpdateData) {
return log(
pluginData,
LogType.STICKER_UPDATE,
createTypedTemplateSafeValueContainer({
oldSticker: stickerToTemplateSafeSticker(data.oldSticker),
newSticker: stickerToTemplateSafeSticker(data.newSticker),
differenceString: data.differenceString,
}),
{},
);
}

View file

@ -0,0 +1,25 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { ThreadChannel } from "discord.js";
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
interface LogThreadCreateData {
thread: ThreadChannel;
}
export function logThreadCreate(pluginData: GuildPluginData<LogsPluginType>, data: LogThreadCreateData) {
return log(
pluginData,
LogType.THREAD_CREATE,
createTypedTemplateSafeValueContainer({
thread: channelToTemplateSafeChannel(data.thread),
}),
{
channel: data.thread.parentId,
category: data.thread.parent?.parentId,
},
);
}

View file

@ -0,0 +1,25 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { ThreadChannel } from "discord.js";
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
interface LogThreadDeleteData {
thread: ThreadChannel;
}
export function logThreadDelete(pluginData: GuildPluginData<LogsPluginType>, data: LogThreadDeleteData) {
return log(
pluginData,
LogType.THREAD_DELETE,
createTypedTemplateSafeValueContainer({
thread: channelToTemplateSafeChannel(data.thread),
}),
{
channel: data.thread.parentId,
category: data.thread.parent?.parentId,
},
);
}

View file

@ -0,0 +1,29 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { ThreadChannel } from "discord.js";
import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects";
interface LogThreadUpdateData {
oldThread: ThreadChannel;
newThread: ThreadChannel;
differenceString: string;
}
export function logThreadUpdate(pluginData: GuildPluginData<LogsPluginType>, data: LogThreadUpdateData) {
return log(
pluginData,
LogType.THREAD_UPDATE,
createTypedTemplateSafeValueContainer({
oldThread: channelToTemplateSafeChannel(data.oldThread),
newThread: channelToTemplateSafeChannel(data.newThread),
differenceString: data.differenceString,
}),
{
channel: data.newThread.parentId,
category: data.newThread.parent?.parentId,
},
);
}

View file

@ -0,0 +1,39 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildVoiceChannel, GuildMember, User } from "discord.js";
import {
channelToTemplateSafeChannel,
memberToTemplateSafeMember,
userToTemplateSafeUser,
} from "../../../utils/templateSafeObjects";
interface LogVoiceChannelForceDisconnectData {
mod: User;
member: GuildMember;
oldChannel: BaseGuildVoiceChannel;
}
export function logVoiceChannelForceDisconnect(
pluginData: GuildPluginData<LogsPluginType>,
data: LogVoiceChannelForceDisconnectData,
) {
return log(
pluginData,
LogType.VOICE_CHANNEL_FORCE_DISCONNECT,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
member: memberToTemplateSafeMember(data.member),
oldChannel: channelToTemplateSafeChannel(data.oldChannel),
}),
{
userId: data.member.id,
roles: Array.from(data.member.roles.cache.keys()),
channel: data.oldChannel.id,
category: data.oldChannel.parentId,
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,41 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildVoiceChannel, GuildMember, User } from "discord.js";
import {
channelToTemplateSafeChannel,
memberToTemplateSafeMember,
userToTemplateSafeUser,
} from "../../../utils/templateSafeObjects";
interface LogVoiceChannelForceMoveData {
mod: User;
member: GuildMember;
oldChannel: BaseGuildVoiceChannel;
newChannel: BaseGuildVoiceChannel;
}
export function logVoiceChannelForceMove(
pluginData: GuildPluginData<LogsPluginType>,
data: LogVoiceChannelForceMoveData,
) {
return log(
pluginData,
LogType.VOICE_CHANNEL_FORCE_MOVE,
createTypedTemplateSafeValueContainer({
mod: userToTemplateSafeUser(data.mod),
member: memberToTemplateSafeMember(data.member),
oldChannel: channelToTemplateSafeChannel(data.oldChannel),
newChannel: channelToTemplateSafeChannel(data.newChannel),
}),
{
userId: data.member.id,
roles: Array.from(data.member.roles.cache.keys()),
channel: data.newChannel.id,
category: data.newChannel.parentId,
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,30 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildVoiceChannel, GuildMember } from "discord.js";
import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
interface LogVoiceChannelJoinData {
member: GuildMember;
channel: BaseGuildVoiceChannel;
}
export function logVoiceChannelJoin(pluginData: GuildPluginData<LogsPluginType>, data: LogVoiceChannelJoinData) {
return log(
pluginData,
LogType.VOICE_CHANNEL_JOIN,
createTypedTemplateSafeValueContainer({
member: memberToTemplateSafeMember(data.member),
channel: channelToTemplateSafeChannel(data.channel),
}),
{
userId: data.member.id,
roles: Array.from(data.member.roles.cache.keys()),
channel: data.channel.id,
category: data.channel.parentId,
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,30 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildVoiceChannel, GuildMember } from "discord.js";
import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
interface LogVoiceChannelLeaveData {
member: GuildMember;
channel: BaseGuildVoiceChannel;
}
export function logVoiceChannelLeave(pluginData: GuildPluginData<LogsPluginType>, data: LogVoiceChannelLeaveData) {
return log(
pluginData,
LogType.VOICE_CHANNEL_LEAVE,
createTypedTemplateSafeValueContainer({
member: memberToTemplateSafeMember(data.member),
channel: channelToTemplateSafeChannel(data.channel),
}),
{
userId: data.member.id,
roles: Array.from(data.member.roles.cache.keys()),
channel: data.channel.id,
category: data.channel.parentId,
bot: data.member.user.bot,
},
);
}

View file

@ -0,0 +1,32 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
import { log } from "../util/log";
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { BaseGuildVoiceChannel, GuildMember } from "discord.js";
import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects";
interface LogVoiceChannelMoveData {
member: GuildMember;
oldChannel: BaseGuildVoiceChannel;
newChannel: BaseGuildVoiceChannel;
}
export function logVoiceChannelMove(pluginData: GuildPluginData<LogsPluginType>, data: LogVoiceChannelMoveData) {
return log(
pluginData,
LogType.VOICE_CHANNEL_MOVE,
createTypedTemplateSafeValueContainer({
member: memberToTemplateSafeMember(data.member),
oldChannel: channelToTemplateSafeChannel(data.oldChannel),
newChannel: channelToTemplateSafeChannel(data.newChannel),
}),
{
userId: data.member.id,
roles: Array.from(data.member.roles.cache.keys()),
channel: data.newChannel.id,
category: data.newChannel.parentId,
bot: data.member.user.bot,
},
);
}

View file

@ -1,4 +1,5 @@
import * as t from "io-ts";
import { z } from "zod";
import { BasePluginType, typedGuildEventListener } from "knub";
import { GuildArchives } from "../../data/GuildArchives";
import { GuildCases } from "../../data/GuildCases";
@ -7,6 +8,26 @@ import { GuildSavedMessages } from "../../data/GuildSavedMessages";
import { RegExpRunner } from "../../RegExpRunner";
import { tMessageContent, tNullable } from "../../utils";
import { TRegex } from "../../validatorUtils";
import { LogType } from "../../data/LogType";
import { GuildMember } from "discord.js";
import {
TemplateSafeCase,
TemplateSafeChannel,
TemplateSafeEmoji,
TemplateSafeMember,
TemplateSafeRole,
TemplateSafeSavedMessage,
TemplateSafeStage,
TemplateSafeSticker,
TemplateSafeUnknownMember,
TemplateSafeUnknownUser,
TemplateSafeUser,
} from "../../utils/templateSafeObjects";
import {
TemplateSafeValue,
TemplateSafeValueContainer,
TypedTemplateSafeValueContainer,
} from "../../templateFormatter";
export const tLogFormats = t.record(t.string, t.union([t.string, tMessageContent]));
export type TLogFormats = t.TypeOf<typeof tLogFormats>;
@ -73,3 +94,428 @@ export interface LogsPluginType extends BasePluginType {
}
export const logsEvt = typedGuildEventListener<LogsPluginType>();
export const LogTypeData = z.object({
[LogType.MEMBER_WARN]: z.object({
mod: z.instanceof(TemplateSafeMember),
member: z.instanceof(TemplateSafeMember),
caseNumber: z.number(),
reason: z.string(),
}),
[LogType.MEMBER_MUTE]: z.object({
mod: z.instanceof(TemplateSafeUser),
user: z.instanceof(TemplateSafeUser),
caseNumber: z.number(),
reason: z.string(),
}),
[LogType.MEMBER_UNMUTE]: z.object({
mod: z.instanceof(TemplateSafeUser),
user: z.instanceof(TemplateSafeUser),
caseNumber: z.number(),
reason: z.string(),
}),
[LogType.MEMBER_MUTE_EXPIRED]: z.object({
member: z.instanceof(TemplateSafeMember).or(z.instanceof(TemplateSafeUnknownMember)),
}),
[LogType.MEMBER_KICK]: z.object({
mod: z.instanceof(TemplateSafeUser).or(z.null()),
user: z.instanceof(TemplateSafeUser),
caseNumber: z.number(),
reason: z.string(),
}),
[LogType.MEMBER_BAN]: z.object({
mod: z.instanceof(TemplateSafeUser).or(z.null()),
user: z.instanceof(TemplateSafeUser),
caseNumber: z.number(),
reason: z.string(),
}),
[LogType.MEMBER_UNBAN]: z.object({
mod: z.instanceof(TemplateSafeUser).or(z.null()),
userId: z.string(),
caseNumber: z.number(),
reason: z.string(),
}),
[LogType.MEMBER_FORCEBAN]: z.object({
mod: z.instanceof(TemplateSafeUser),
userId: z.string(),
caseNumber: z.number(),
reason: z.string(),
}),
[LogType.MEMBER_JOIN]: z.object({
member: z.instanceof(TemplateSafeMember),
new: z.string(),
account_age: z.string(),
}),
[LogType.MEMBER_LEAVE]: z.object({
member: z.instanceof(TemplateSafeMember),
}),
[LogType.MEMBER_ROLE_ADD]: z.object({
mod: z.instanceof(TemplateSafeUser).or(z.null()),
member: z.instanceof(TemplateSafeMember),
roles: z.string(),
}),
[LogType.MEMBER_ROLE_REMOVE]: z.object({
mod: z.instanceof(TemplateSafeUser).or(z.null()),
member: z.instanceof(TemplateSafeMember),
roles: z.string(),
}),
[LogType.MEMBER_NICK_CHANGE]: z.object({
member: z.instanceof(TemplateSafeMember),
oldNick: z.string(),
newNick: z.string(),
}),
[LogType.MEMBER_RESTORE]: z.object({
member: z.instanceof(TemplateSafeMember),
restoredData: z.string(),
}),
[LogType.CHANNEL_CREATE]: z.object({
channel: z.instanceof(TemplateSafeChannel),
}),
[LogType.CHANNEL_DELETE]: z.object({
channel: z.instanceof(TemplateSafeChannel),
}),
[LogType.CHANNEL_UPDATE]: z.object({
oldChannel: z.instanceof(TemplateSafeChannel),
newChannel: z.instanceof(TemplateSafeChannel),
differenceString: z.string(),
}),
[LogType.THREAD_CREATE]: z.object({
thread: z.instanceof(TemplateSafeChannel),
}),
[LogType.THREAD_DELETE]: z.object({
thread: z.instanceof(TemplateSafeChannel),
}),
[LogType.THREAD_UPDATE]: z.object({
oldThread: z.instanceof(TemplateSafeChannel),
newThread: z.instanceof(TemplateSafeChannel),
differenceString: z.string(),
}),
[LogType.ROLE_CREATE]: z.object({
role: z.instanceof(TemplateSafeRole),
}),
[LogType.ROLE_DELETE]: z.object({
role: z.instanceof(TemplateSafeRole),
}),
[LogType.ROLE_UPDATE]: z.object({
oldRole: z.instanceof(TemplateSafeRole),
newRole: z.instanceof(TemplateSafeRole),
differenceString: z.string(),
}),
[LogType.MESSAGE_EDIT]: z.object({
user: z.instanceof(TemplateSafeUser),
channel: z.instanceof(TemplateSafeChannel),
before: z.instanceof(TemplateSafeSavedMessage),
after: z.instanceof(TemplateSafeSavedMessage),
}),
[LogType.MESSAGE_DELETE]: z.object({
user: z.instanceof(TemplateSafeUser),
channel: z.instanceof(TemplateSafeChannel),
messageDate: z.string(),
message: z.instanceof(TemplateSafeSavedMessage),
}),
[LogType.MESSAGE_DELETE_BULK]: z.object({
count: z.number(),
authorIds: z.array(z.string()),
channel: z.instanceof(TemplateSafeChannel),
archiveUrl: z.string(),
}),
[LogType.MESSAGE_DELETE_BARE]: z.object({
messageId: z.string(),
channel: z.instanceof(TemplateSafeChannel),
}),
[LogType.VOICE_CHANNEL_JOIN]: z.object({
member: z.instanceof(TemplateSafeMember),
channel: z.instanceof(TemplateSafeChannel),
}),
[LogType.VOICE_CHANNEL_LEAVE]: z.object({
member: z.instanceof(TemplateSafeMember),
channel: z.instanceof(TemplateSafeChannel),
}),
[LogType.VOICE_CHANNEL_MOVE]: z.object({
member: z.instanceof(TemplateSafeMember),
oldChannel: z.instanceof(TemplateSafeChannel),
newChannel: z.instanceof(TemplateSafeChannel),
}),
[LogType.STAGE_INSTANCE_CREATE]: z.object({
stageInstance: z.instanceof(TemplateSafeStage),
stageChannel: z.instanceof(TemplateSafeChannel),
}),
[LogType.STAGE_INSTANCE_DELETE]: z.object({
stageInstance: z.instanceof(TemplateSafeStage),
stageChannel: z.instanceof(TemplateSafeChannel),
}),
[LogType.STAGE_INSTANCE_UPDATE]: z.object({
oldStageInstance: z.instanceof(TemplateSafeStage),
newStageInstance: z.instanceof(TemplateSafeStage),
stageChannel: z.instanceof(TemplateSafeChannel),
differenceString: z.string(),
}),
[LogType.EMOJI_CREATE]: z.object({
emoji: z.instanceof(TemplateSafeEmoji),
}),
[LogType.EMOJI_DELETE]: z.object({
emoji: z.instanceof(TemplateSafeEmoji),
}),
[LogType.EMOJI_UPDATE]: z.object({
oldEmoji: z.instanceof(TemplateSafeEmoji),
newEmoji: z.instanceof(TemplateSafeEmoji),
differenceString: z.string(),
}),
[LogType.STICKER_CREATE]: z.object({
sticker: z.instanceof(TemplateSafeSticker),
}),
[LogType.STICKER_DELETE]: z.object({
sticker: z.instanceof(TemplateSafeSticker),
}),
[LogType.STICKER_UPDATE]: z.object({
oldSticker: z.instanceof(TemplateSafeSticker),
newSticker: z.instanceof(TemplateSafeSticker),
differenceString: z.string(),
}),
[LogType.MESSAGE_SPAM_DETECTED]: z.object({
member: z.instanceof(TemplateSafeMember),
channel: z.instanceof(TemplateSafeChannel),
description: z.string(),
limit: z.number(),
interval: z.number(),
archiveUrl: z.string(),
}),
[LogType.CENSOR]: z.object({
user: z.instanceof(TemplateSafeUser),
channel: z.instanceof(TemplateSafeChannel),
reason: z.string(),
message: z.instanceof(TemplateSafeSavedMessage),
messageText: z.string(),
}),
[LogType.CLEAN]: z.object({
mod: z.instanceof(TemplateSafeUser),
channel: z.instanceof(TemplateSafeChannel),
count: z.number(),
archiveUrl: z.string(),
}),
[LogType.CASE_CREATE]: z.object({
mod: z.instanceof(TemplateSafeUser),
userId: z.string(),
caseNum: z.number(),
caseType: z.string(),
reason: z.string(),
}),
[LogType.MASSUNBAN]: z.object({
mod: z.instanceof(TemplateSafeUser),
count: z.number(),
reason: z.string(),
}),
[LogType.MASSBAN]: z.object({
mod: z.instanceof(TemplateSafeUser),
count: z.number(),
reason: z.string(),
}),
[LogType.MASSMUTE]: z.object({
mod: z.instanceof(TemplateSafeUser),
count: z.number(),
}),
[LogType.MEMBER_TIMED_MUTE]: z.object({
mod: z.instanceof(TemplateSafeUser),
user: z.instanceof(TemplateSafeUser),
time: z.string(),
caseNumber: z.number(),
reason: z.string(),
}),
[LogType.MEMBER_TIMED_UNMUTE]: z.object({
mod: z.instanceof(TemplateSafeUser),
user: z.instanceof(TemplateSafeUser),
time: z.string(),
caseNumber: z.number(),
reason: z.string(),
}),
[LogType.MEMBER_TIMED_BAN]: z.object({
mod: z.instanceof(TemplateSafeUser),
user: z.instanceof(TemplateSafeUser),
banTime: z.string(),
caseNumber: z.number(),
reason: z.string(),
}),
[LogType.MEMBER_TIMED_UNBAN]: z.object({
mod: z.instanceof(TemplateSafeUser).or(z.instanceof(TemplateSafeUnknownUser)),
userId: z.string(),
banTime: z.string(),
caseNumber: z.number(),
reason: z.string(),
}),
[LogType.MEMBER_JOIN_WITH_PRIOR_RECORDS]: z.object({
member: z.instanceof(TemplateSafeMember),
recentCaseSummary: z.string(),
}),
[LogType.OTHER_SPAM_DETECTED]: z.object({
member: z.instanceof(TemplateSafeMember),
description: z.string(),
limit: z.number(),
interval: z.number(),
}),
[LogType.MEMBER_ROLE_CHANGES]: z.object({
mod: z
.instanceof(TemplateSafeUser)
.or(z.instanceof(TemplateSafeUnknownUser))
.or(z.null()),
member: z.instanceof(TemplateSafeMember),
addedRoles: z.string(),
removedRoles: z.string(),
}),
[LogType.VOICE_CHANNEL_FORCE_MOVE]: z.object({
mod: z.instanceof(TemplateSafeUser),
member: z.instanceof(TemplateSafeMember),
oldChannel: z.instanceof(TemplateSafeChannel),
newChannel: z.instanceof(TemplateSafeChannel),
}),
[LogType.VOICE_CHANNEL_FORCE_DISCONNECT]: z.object({
mod: z.instanceof(TemplateSafeUser),
member: z.instanceof(TemplateSafeMember),
oldChannel: z.instanceof(TemplateSafeChannel),
}),
[LogType.CASE_UPDATE]: z.object({
mod: z.instanceof(TemplateSafeUser),
caseNumber: z.number(),
caseType: z.string(),
note: z.string(),
}),
[LogType.MEMBER_MUTE_REJOIN]: z.object({
member: z.instanceof(TemplateSafeMember),
}),
[LogType.SCHEDULED_MESSAGE]: z.object({
author: z.instanceof(TemplateSafeUser),
channel: z.instanceof(TemplateSafeChannel),
datetime: z.string(),
date: z.string(),
time: z.string(),
}),
[LogType.POSTED_SCHEDULED_MESSAGE]: z.object({
author: z.instanceof(TemplateSafeUser),
channel: z.instanceof(TemplateSafeChannel),
messageId: z.string(),
}),
[LogType.BOT_ALERT]: z.object({
body: z.string(),
}),
[LogType.AUTOMOD_ACTION]: z.object({
rule: z.string(),
user: z.instanceof(TemplateSafeUser),
users: z.array(z.instanceof(TemplateSafeUser)),
actionsTaken: z.string(),
matchSummary: z.string(),
}),
[LogType.SCHEDULED_REPEATED_MESSAGE]: z.object({
author: z.instanceof(TemplateSafeUser),
channel: z.instanceof(TemplateSafeChannel),
datetime: z.string(),
date: z.string(),
time: z.string(),
repeatInterval: z.string(),
repeatDetails: z.string(),
}),
[LogType.REPEATED_MESSAGE]: z.object({
author: z.instanceof(TemplateSafeUser),
channel: z.instanceof(TemplateSafeChannel),
datetime: z.string(),
date: z.string(),
time: z.string(),
repeatInterval: z.string(),
repeatDetails: z.string(),
}),
[LogType.MESSAGE_DELETE_AUTO]: z.object({
message: z.instanceof(TemplateSafeSavedMessage),
user: z.instanceof(TemplateSafeUser),
channel: z.instanceof(TemplateSafeChannel),
messageDate: z.string(),
}),
[LogType.SET_ANTIRAID_USER]: z.object({
level: z.string(),
user: z.instanceof(TemplateSafeUser),
}),
[LogType.SET_ANTIRAID_AUTO]: z.object({
level: z.string(),
}),
[LogType.MEMBER_NOTE]: z.object({
mod: z.instanceof(TemplateSafeUser),
user: z.instanceof(TemplateSafeUser),
caseNumber: z.number(),
reason: z.string(),
}),
[LogType.CASE_DELETE]: z.object({
mod: z.instanceof(TemplateSafeMember),
case: z.instanceof(TemplateSafeCase),
}),
[LogType.DM_FAILED]: z.object({
source: z.string(),
user: z.instanceof(TemplateSafeUser).or(z.instanceof(TemplateSafeUnknownUser)),
}),
});
export type ILogTypeData = z.infer<typeof LogTypeData>;

View file

@ -3,7 +3,12 @@ import { GuildPluginData } from "knub";
import { SavedMessage } from "../../../data/entities/SavedMessage";
import { LogType } from "../../../data/LogType";
import { logger } from "../../../logger";
import { renderTemplate, TemplateParseError } from "../../../templateFormatter";
import {
renderTemplate,
TemplateParseError,
TemplateSafeValueContainer,
TypedTemplateSafeValueContainer,
} from "../../../templateFormatter";
import {
messageSummary,
renderRecursively,
@ -13,17 +18,18 @@ import {
verboseUserName,
} from "../../../utils";
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
import { FORMAT_NO_TIMESTAMP, LogsPluginType, TLogChannel } from "../types";
import { FORMAT_NO_TIMESTAMP, ILogTypeData, LogsPluginType, TLogChannel } from "../types";
import {
getConfigAccessibleMemberLevel,
IConfigAccessibleMember,
memberToConfigAccessibleMember,
} from "../../../utils/configAccessibleObjects";
getTemplateSafeMemberLevel,
TemplateSafeMember,
memberToTemplateSafeMember,
TemplateSafeUser,
} from "../../../utils/templateSafeObjects";
export async function getLogMessage(
export async function getLogMessage<TLogType extends keyof ILogTypeData>(
pluginData: GuildPluginData<LogsPluginType>,
type: LogType,
data: any,
type: TLogType,
data: TypedTemplateSafeValueContainer<ILogTypeData[TLogType]>,
opts?: Pick<TLogChannel, "format" | "timestamp_format" | "include_embed_timestamp">,
): Promise<MessageOptions | null> {
const config = pluginData.config.get();
@ -42,10 +48,12 @@ export async function getLogMessage(
const isoTimestamp = time.toISOString();
const timestamp = timestampFormat ? time.format(timestampFormat) : "";
const values = {
const values = new TemplateSafeValueContainer({
...data,
timestamp,
userMention: async inputUserOrMember => {
userMention: async (
inputUserOrMember: TemplateSafeUser | TemplateSafeMember | TemplateSafeUser[] | TemplateSafeMember[],
) => {
if (!inputUserOrMember) return "";
const usersOrMembers = Array.isArray(inputUserOrMember) ? inputUserOrMember : [inputUserOrMember];
@ -53,20 +61,20 @@ export async function getLogMessage(
const mentions: string[] = [];
for (const userOrMember of usersOrMembers) {
let user;
let member: IConfigAccessibleMember | null = null;
let member: TemplateSafeMember | null = null;
if (userOrMember.user) {
member = userOrMember as IConfigAccessibleMember;
member = userOrMember as TemplateSafeMember;
user = member.user;
} else {
user = userOrMember;
const apiMember = await resolveMember(pluginData.client, pluginData.guild, user.id);
if (apiMember) {
member = memberToConfigAccessibleMember(apiMember);
member = memberToTemplateSafeMember(apiMember);
}
}
const level = member ? getConfigAccessibleMemberLevel(pluginData, member) : 0;
const level = member ? getTemplateSafeMemberLevel(pluginData, member) : 0;
const memberConfig =
(await pluginData.config.getMatchingConfig({
level,
@ -92,7 +100,7 @@ export async function getLogMessage(
if (!msg) return "";
return messageSummary(msg);
},
};
});
if (type === LogType.BOT_ALERT) {
const valuesWithoutTmplEval = { ...values };

View file

@ -0,0 +1,7 @@
import { GuildPluginData } from "knub";
import { LogsPluginType } from "../types";
import { LogType } from "../../../data/LogType";
export function isLogIgnored(pluginData: GuildPluginData<LogsPluginType>, type: LogType, ignoreId: string) {
return pluginData.state.guildLogs.isLogIgnored(type, ignoreId);
}

View file

@ -1,11 +1,12 @@
import { MessageMentionTypes, Snowflake, TextChannel } from "discord.js";
import { GuildPluginData } from "knub";
import { SavedMessage } from "../../../data/entities/SavedMessage";
import { LogType } from "../../../data/LogType";
import { allowTimeout } from "../../../RegExpRunner";
import { createChunkedMessage, get, noop } from "../../../utils";
import { LogsPluginType, TLogChannelMap } from "../types";
import { ILogTypeData, LogsPluginType, LogTypeData, TLogChannelMap } from "../types";
import { getLogMessage } from "./getLogMessage";
import { TemplateSafeValueContainer, TypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { LogType } from "../../../data/LogType";
const excludedUserProps = ["user", "member", "mod"];
const excludedRoleProps = ["message.member.roles", "member.roles"];
@ -14,7 +15,21 @@ function isRoleArray(value: any): value is string[] {
return Array.isArray(value);
}
export async function log(pluginData: GuildPluginData<LogsPluginType>, type: LogType, data: any) {
interface ExclusionData {
userId?: Snowflake | null;
bot?: boolean | null;
roles?: Snowflake[] | null;
channel?: Snowflake | null;
category?: Snowflake | null;
messageTextContent?: string | null;
}
export async function log<TLogType extends keyof ILogTypeData>(
pluginData: GuildPluginData<LogsPluginType>,
type: TLogType,
data: TypedTemplateSafeValueContainer<ILogTypeData[TLogType]>,
exclusionData: ExclusionData = {},
) {
const logChannels: TLogChannelMap = pluginData.config.get().channels;
const typeStr = LogType[type];
@ -25,94 +40,40 @@ export async function log(pluginData: GuildPluginData<LogsPluginType>, type: Log
if ((opts.include && opts.include.includes(typeStr)) || (opts.exclude && !opts.exclude.includes(typeStr))) {
// If this log entry is about an excluded user, skip it
// TODO: Quick and dirty solution, look into changing at some point
if (opts.excluded_users) {
for (const prop of excludedUserProps) {
if (data && data[prop] && opts.excluded_users.includes(data[prop].id)) {
continue logChannelLoop;
}
}
if (opts.excluded_users && exclusionData.userId && opts.excluded_users.includes(exclusionData.userId)) {
continue;
}
// If we're excluding bots and the logged user is a bot, skip it
if (opts.exclude_bots) {
for (const prop of excludedUserProps) {
if (data && data[prop] && data[prop].bot) {
if (opts.exclude_bots && exclusionData.bot) {
continue;
}
if (opts.excluded_roles && exclusionData.roles) {
for (const role of exclusionData.roles) {
if (opts.excluded_roles.includes(role)) {
continue logChannelLoop;
}
}
}
if (opts.excluded_roles) {
for (const value of Object.values(data || {})) {
if (value instanceof SavedMessage) {
const member = pluginData.guild.members.cache.get(value.user_id as Snowflake);
for (const role of member?.roles.cache || []) {
if (opts.excluded_roles.includes(role[0])) {
continue logChannelLoop;
}
}
}
}
for (const prop of excludedRoleProps) {
const roles = get(data, prop);
if (!isRoleArray(roles)) {
continue;
}
for (const role of roles) {
if (opts.excluded_roles.includes(role)) {
continue logChannelLoop;
}
}
}
if (opts.excluded_channels && exclusionData.channel && opts.excluded_channels.includes(exclusionData.channel)) {
continue;
}
// If this entry is from an excluded channel, skip it
if (opts.excluded_channels) {
if (
type === LogType.MESSAGE_DELETE ||
type === LogType.MESSAGE_DELETE_BARE ||
type === LogType.MESSAGE_EDIT ||
type === LogType.MESSAGE_SPAM_DETECTED ||
type === LogType.CENSOR ||
type === LogType.CLEAN
) {
if (opts.excluded_channels.includes(data.channel.id)) {
continue logChannelLoop;
}
}
if (
opts.excluded_categories &&
exclusionData.category &&
opts.excluded_categories.includes(exclusionData.category)
) {
continue;
}
// If this entry is from an excluded category, skip it
if (opts.excluded_categories) {
if (
type === LogType.MESSAGE_DELETE ||
type === LogType.MESSAGE_DELETE_BARE ||
type === LogType.MESSAGE_EDIT ||
type === LogType.MESSAGE_SPAM_DETECTED ||
type === LogType.CENSOR ||
type === LogType.CLEAN
) {
if (data.channel.parentId && opts.excluded_categories.includes(data.channel.parentId)) {
continue logChannelLoop;
}
}
}
// If this entry contains a message with an excluded regex, skip it
if (type === LogType.MESSAGE_DELETE && opts.excluded_message_regexes && data.message.data.content) {
if (opts.excluded_message_regexes && exclusionData.messageTextContent) {
for (const regex of opts.excluded_message_regexes) {
const matches = await pluginData.state.regexRunner.exec(regex, data.message.data.content).catch(allowTimeout);
if (matches) {
continue logChannelLoop;
}
}
}
if (type === LogType.MESSAGE_EDIT && opts.excluded_message_regexes && data.before.data.content) {
for (const regex of opts.excluded_message_regexes) {
const matches = await pluginData.state.regexRunner.exec(regex, data.before.data.content).catch(allowTimeout);
const matches = await pluginData.state.regexRunner
.exec(regex, exclusionData.messageTextContent)
.catch(allowTimeout);
if (matches) {
continue logChannelLoop;
}

View file

@ -1,51 +1,33 @@
import { MessageAttachment, Snowflake } from "discord.js";
import { BaseGuildTextChannel, Snowflake, ThreadChannel } from "discord.js";
import { GuildPluginData } from "knub";
import moment from "moment-timezone";
import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects";
import { SavedMessage } from "../../../data/entities/SavedMessage";
import { LogType } from "../../../data/LogType";
import { resolveUser, useMediaUrls } from "../../../utils";
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types";
import { resolveUser } from "../../../utils";
import { LogsPluginType } from "../types";
import { logMessageDelete } from "../logFunctions/logMessageDelete";
import { isLogIgnored } from "./isLogIgnored";
import { logMessageDeleteBare } from "../logFunctions/logMessageDeleteBare";
export async function onMessageDelete(pluginData: GuildPluginData<LogsPluginType>, savedMessage: SavedMessage) {
const user = await resolveUser(pluginData.client, savedMessage.user_id);
const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)!;
const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)! as
| BaseGuildTextChannel
| ThreadChannel;
if (isLogIgnored(pluginData, LogType.MESSAGE_DELETE, savedMessage.id)) {
return;
}
if (user) {
// Replace attachment URLs with media URLs
if (savedMessage.data.attachments) {
for (const attachment of savedMessage.data.attachments as MessageAttachment[]) {
attachment.url = useMediaUrls(attachment.url);
}
}
// See comment on FORMAT_NO_TIMESTAMP in types.ts
const config = pluginData.config.get();
const timestampFormat =
(config.format.timestamp !== FORMAT_NO_TIMESTAMP ? config.format.timestamp : null) ?? config.timestamp_format;
pluginData.state.guildLogs.log(
LogType.MESSAGE_DELETE,
{
user: userToConfigAccessibleUser(user),
channel: channelToConfigAccessibleChannel(channel),
messageDate: pluginData
.getPlugin(TimeAndDatePlugin)
.inGuildTz(moment.utc(savedMessage.data.timestamp, "x"))
.format(timestampFormat),
message: savedMessage,
},
savedMessage.id,
);
logMessageDelete(pluginData, {
user,
channel,
message: savedMessage,
});
} else {
pluginData.state.guildLogs.log(
LogType.MESSAGE_DELETE_BARE,
{
messageId: savedMessage.id,
channel: channelToConfigAccessibleChannel(channel),
},
savedMessage.id,
);
logMessageDeleteBare(pluginData, {
messageId: savedMessage.id,
channel,
});
}
}

View file

@ -1,24 +1,28 @@
import { Snowflake } from "discord.js";
import { BaseGuildTextChannel, Snowflake, ThreadChannel } from "discord.js";
import { GuildPluginData } from "knub";
import { SavedMessage } from "../../../data/entities/SavedMessage";
import { LogType } from "../../../data/LogType";
import { getBaseUrl } from "../../../pluginUtils";
import { LogsPluginType } from "../types";
import { logMessageDeleteBulk } from "../logFunctions/logMessageDeleteBulk";
import { isLogIgnored } from "./isLogIgnored";
export async function onMessageDeleteBulk(pluginData: GuildPluginData<LogsPluginType>, savedMessages: SavedMessage[]) {
const channel = pluginData.guild.channels.cache.get(savedMessages[0].channel_id as Snowflake);
if (isLogIgnored(pluginData, LogType.MESSAGE_DELETE, savedMessages[0].id)) {
return;
}
const channel = pluginData.guild.channels.cache.get(savedMessages[0].channel_id as Snowflake) as
| BaseGuildTextChannel
| ThreadChannel;
const archiveId = await pluginData.state.archives.createFromSavedMessages(savedMessages, pluginData.guild);
const archiveUrl = pluginData.state.archives.getUrl(getBaseUrl(pluginData), archiveId);
const authorIds = Array.from(new Set(savedMessages.map(item => `\`${item.user_id}\``))).join(", ");
const authorIds = Array.from(new Set(savedMessages.map(item => `\`${item.user_id}\``)));
pluginData.state.guildLogs.log(
LogType.MESSAGE_DELETE_BULK,
{
count: savedMessages.length,
authorIds,
channel,
archiveUrl,
},
savedMessages[0].id,
);
logMessageDeleteBulk(pluginData, {
count: savedMessages.length,
authorIds,
channel,
archiveUrl,
});
}

View file

@ -1,11 +1,12 @@
import { MessageEmbed, Snowflake } from "discord.js";
import { BaseGuildTextChannel, MessageEmbed, Snowflake, ThreadChannel } from "discord.js";
import { GuildPluginData } from "knub";
import cloneDeep from "lodash.clonedeep";
import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects";
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { SavedMessage } from "../../../data/entities/SavedMessage";
import { LogType } from "../../../data/LogType";
import { resolveUser } from "../../../utils";
import { LogsPluginType } from "../types";
import { logMessageEdit } from "../logFunctions/logMessageEdit";
export async function onMessageUpdate(
pluginData: GuildPluginData<LogsPluginType>,
@ -48,11 +49,13 @@ export async function onMessageUpdate(
}
const user = await resolveUser(pluginData.client, savedMessage.user_id);
const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)!;
const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)! as
| BaseGuildTextChannel
| ThreadChannel;
pluginData.state.guildLogs.log(LogType.MESSAGE_EDIT, {
user: userToConfigAccessibleUser(user),
channel: channelToConfigAccessibleChannel(channel),
logMessageEdit(pluginData, {
user,
channel,
before: oldSavedMessage,
after: savedMessage,
});