mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-05-10 12:25:02 +00:00
Finish preliminary rework, ready to test
This commit is contained in:
parent
57893e7f76
commit
d0a1beb809
177 changed files with 854 additions and 707 deletions
|
@ -45,6 +45,7 @@ import { onModActionsEvent } from "./functions/onModActionsEvent";
|
|||
import { offModActionsEvent } from "./functions/offModActionsEvent";
|
||||
import { updateCase } from "./functions/updateCase";
|
||||
import { Queue } from "../../Queue";
|
||||
import { GuildMember, Message } from "discord.js";
|
||||
|
||||
const defaultOptions = {
|
||||
config: {
|
||||
|
@ -158,13 +159,13 @@ export const ModActionsPlugin = zeppelinGuildPlugin<ModActionsPluginType>()({
|
|||
|
||||
public: {
|
||||
warnMember(pluginData) {
|
||||
return (member: Member, reason: string, warnOptions?: WarnOptions) => {
|
||||
return (member: GuildMember, reason: string, warnOptions?: WarnOptions) => {
|
||||
warnMember(pluginData, member, reason, warnOptions);
|
||||
};
|
||||
},
|
||||
|
||||
kickMember(pluginData) {
|
||||
return (member: Member, reason: string, kickOptions?: KickOptions) => {
|
||||
return (member: GuildMember, reason: string, kickOptions?: KickOptions) => {
|
||||
kickMember(pluginData, member, reason, kickOptions);
|
||||
};
|
||||
},
|
||||
|
|
|
@ -59,7 +59,7 @@ export const AddCaseCmd = modActionsCmd({
|
|||
return;
|
||||
}
|
||||
|
||||
const reason = formatReasonWithAttachments(args.reason, msg.attachments);
|
||||
const reason = formatReasonWithAttachments(args.reason, msg.attachments.array());
|
||||
|
||||
// Create the case
|
||||
const casesPlugin = pluginData.getPlugin(CasesPlugin);
|
||||
|
|
|
@ -6,7 +6,7 @@ import { isBanned } from "../functions/isBanned";
|
|||
import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs";
|
||||
import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments";
|
||||
import { banUserId } from "../functions/banUserId";
|
||||
import { getMemberLevel, waitForReaction } from "knub/dist/helpers";
|
||||
import { getMemberLevel } from "knub/dist/helpers";
|
||||
import humanizeDuration from "humanize-duration";
|
||||
import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin";
|
||||
import { CaseTypes } from "../../../data/CaseTypes";
|
||||
|
@ -49,7 +49,7 @@ export const BanCmd = modActionsCmd({
|
|||
}
|
||||
const time = args["time"] ? args["time"] : null;
|
||||
|
||||
const reason = formatReasonWithAttachments(args.reason, msg.attachments);
|
||||
const reason = formatReasonWithAttachments(args.reason, msg.attachments.array());
|
||||
const memberToBan = await resolveMember(pluginData.client, pluginData.guild, user.id);
|
||||
// The moderator who did the action is the message author or, if used, the specified -mod
|
||||
let mod = msg.member;
|
||||
|
@ -76,11 +76,11 @@ export const BanCmd = modActionsCmd({
|
|||
}
|
||||
|
||||
// Ask the mod if we should update the existing ban
|
||||
const alreadyBannedMsg = await msg.channel.createMessage("User is already banned, update ban?");
|
||||
const reply = await waitForReaction(pluginData.client, alreadyBannedMsg, ["✅", "❌"], msg.author.id);
|
||||
const alreadyBannedMsg = await msg.channel.send("User is already banned, update ban?");
|
||||
const reply = false; // await waitForReaction(pluginData.client, alreadyBannedMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton
|
||||
|
||||
alreadyBannedMsg.delete().catch(noop);
|
||||
if (!reply || reply.name === "❌") {
|
||||
if (!reply /* || reply.name === "❌"*/) {
|
||||
sendErrorMessage(pluginData, msg.channel, "User already banned, update cancelled by moderator");
|
||||
lock.unlock();
|
||||
return;
|
||||
|
@ -124,11 +124,11 @@ export const BanCmd = modActionsCmd({
|
|||
}
|
||||
} else {
|
||||
// Ask the mod if we should upgrade to a forceban as the user is not on the server
|
||||
const notOnServerMsg = await msg.channel.createMessage("User not found on the server, forceban instead?");
|
||||
const reply = await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id);
|
||||
const notOnServerMsg = await msg.channel.send("User not found on the server, forceban instead?");
|
||||
const reply = false; // await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); Waiting for waitForButton
|
||||
|
||||
notOnServerMsg.delete().catch(noop);
|
||||
if (!reply || reply.name === "❌") {
|
||||
if (!reply /*|| reply.name === "❌"*/) {
|
||||
sendErrorMessage(pluginData, msg.channel, "User not on server, ban cancelled by moderator");
|
||||
lock.unlock();
|
||||
return;
|
||||
|
|
|
@ -24,6 +24,6 @@ export const CaseCmd = modActionsCmd({
|
|||
|
||||
const casesPlugin = pluginData.getPlugin(CasesPlugin);
|
||||
const embed = await casesPlugin.getCaseEmbed(theCase.id, msg.author.id);
|
||||
msg.channel.createMessage(embed);
|
||||
msg.channel.send(embed);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@ import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields";
|
|||
import { getDefaultPrefix } from "knub/dist/commands/commandUtils";
|
||||
import { getGuildPrefix } from "../../../utils/getGuildPrefix";
|
||||
import { createPaginatedMessage } from "../../../utils/createPaginatedMessage";
|
||||
import { MessageEmbedOptions, User } from "discord.js";
|
||||
|
||||
const opts = {
|
||||
mod: ct.userId({ option: true }),
|
||||
|
@ -55,10 +56,10 @@ export const CasesModCmd = modActionsCmd({
|
|||
const lastCaseNum = page * casesPerPage;
|
||||
const title = `Most recent cases ${firstCaseNum}-${lastCaseNum} of ${totalCases} by ${modName}`;
|
||||
|
||||
const embed: EmbedOptions = {
|
||||
const embed: MessageEmbedOptions = {
|
||||
author: {
|
||||
name: title,
|
||||
icon_url: mod instanceof User ? mod.avatarURL || mod.defaultAvatarURL : undefined,
|
||||
iconURL: mod instanceof User ? mod.avatarURL() || mod.defaultAvatarURL : undefined,
|
||||
},
|
||||
fields: [
|
||||
...getChunkedEmbedFields(emptyEmbedValue, lines.join("\n")),
|
||||
|
|
|
@ -16,6 +16,7 @@ import { getGuildPrefix } from "../../../utils/getGuildPrefix";
|
|||
import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields";
|
||||
import { asyncMap } from "../../../utils/async";
|
||||
import { CaseTypes } from "../../../data/CaseTypes";
|
||||
import { MessageEmbedOptions, User } from "discord.js";
|
||||
|
||||
const opts = {
|
||||
expand: ct.bool({ option: true, isSwitch: true, shortcut: "e" }),
|
||||
|
@ -75,13 +76,13 @@ export const CasesUserCmd = modActionsCmd({
|
|||
: `${user.username}#${user.discriminator}`;
|
||||
|
||||
if (cases.length === 0) {
|
||||
msg.channel.createMessage(`No cases found for **${userName}**`);
|
||||
msg.channel.send(`No cases found for **${userName}**`);
|
||||
} else {
|
||||
const casesToDisplay = args.hidden ? cases : normalCases;
|
||||
|
||||
if (args.expand) {
|
||||
if (casesToDisplay.length > 8) {
|
||||
msg.channel.createMessage("Too many cases for expanded view. Please use compact view instead.");
|
||||
msg.channel.send("Too many cases for expanded view. Please use compact view instead.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -89,7 +90,7 @@ export const CasesUserCmd = modActionsCmd({
|
|||
const casesPlugin = pluginData.getPlugin(CasesPlugin);
|
||||
for (const theCase of casesToDisplay) {
|
||||
const embed = await casesPlugin.getCaseEmbed(theCase.id);
|
||||
msg.channel.createMessage(embed);
|
||||
msg.channel.send(embed);
|
||||
}
|
||||
} else {
|
||||
// Compact view (= regular message with a preview of each case)
|
||||
|
@ -121,13 +122,13 @@ export const CasesUserCmd = modActionsCmd({
|
|||
const chunkStart = i * linesPerChunk + 1;
|
||||
const chunkEnd = Math.min((i + 1) * linesPerChunk, lines.length);
|
||||
|
||||
const embed: EmbedOptions = {
|
||||
const embed: MessageEmbedOptions = {
|
||||
author: {
|
||||
name:
|
||||
lineChunks.length === 1
|
||||
? `Cases for ${userName} (${lines.length} total)`
|
||||
: `Cases ${chunkStart}–${chunkEnd} of ${lines.length} for ${userName}`,
|
||||
icon_url: user instanceof User ? user.avatarURL || user.defaultAvatarURL : undefined,
|
||||
icon_url: user instanceof User ? user.avatarURL() || user.defaultAvatarURL : undefined,
|
||||
},
|
||||
fields: [
|
||||
...getChunkedEmbedFields(emptyEmbedValue, linesInChunk.join("\n")),
|
||||
|
@ -135,7 +136,7 @@ export const CasesUserCmd = modActionsCmd({
|
|||
],
|
||||
};
|
||||
|
||||
msg.channel.createMessage({ embed });
|
||||
msg.channel.send({ embed });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { LogType } from "../../../data/LogType";
|
|||
import moment from "moment-timezone";
|
||||
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin";
|
||||
import { Case } from "../../../data/entities/Case";
|
||||
import { TextChannel } from "discord.js";
|
||||
|
||||
export const DeleteCaseCmd = modActionsCmd({
|
||||
trigger: ["delete_case", "deletecase"],
|
||||
|
@ -49,7 +50,7 @@ export const DeleteCaseCmd = modActionsCmd({
|
|||
if (!args.force) {
|
||||
const cases = pluginData.getPlugin(CasesPlugin);
|
||||
const embedContent = await cases.getCaseEmbed(theCase);
|
||||
message.channel.createMessage({
|
||||
message.channel.send({
|
||||
content: "Delete the following case? Answer 'Yes' to continue, 'No' to cancel.",
|
||||
embed: embedContent.embed,
|
||||
});
|
||||
|
@ -62,7 +63,7 @@ export const DeleteCaseCmd = modActionsCmd({
|
|||
);
|
||||
const normalizedReply = (reply?.content || "").toLowerCase().trim();
|
||||
if (normalizedReply !== "yes" && normalizedReply !== "y") {
|
||||
message.channel.createMessage("Cancelled. Case was not deleted.");
|
||||
message.channel.send("Cancelled. Case was not deleted.");
|
||||
cancelled++;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -61,14 +61,17 @@ export const ForcebanCmd = modActionsCmd({
|
|||
mod = args.mod;
|
||||
}
|
||||
|
||||
const reason = formatReasonWithAttachments(args.reason, msg.attachments);
|
||||
const reason = formatReasonWithAttachments(args.reason, msg.attachments.array());
|
||||
|
||||
ignoreEvent(pluginData, IgnoredEventType.Ban, user.id);
|
||||
pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, user.id);
|
||||
|
||||
try {
|
||||
// FIXME: Use banUserId()?
|
||||
await pluginData.guild.banMember(user.id, 1, reason != null ? encodeURIComponent(reason) : undefined);
|
||||
await pluginData.guild.bans.create(user.id, {
|
||||
days: 1,
|
||||
reason: reason != null ? encodeURIComponent(reason) : undefined,
|
||||
});
|
||||
} catch {
|
||||
sendErrorMessage(pluginData, msg.channel, "Failed to forceban member");
|
||||
return;
|
||||
|
|
|
@ -15,6 +15,7 @@ import { LogType } from "../../../data/LogType";
|
|||
import { performance } from "perf_hooks";
|
||||
import { humanizeDurationShort } from "../../../humanizeDurationShort";
|
||||
import { load } from "js-yaml";
|
||||
import { TextChannel } from "discord.js";
|
||||
|
||||
export const MassbanCmd = modActionsCmd({
|
||||
trigger: "massban",
|
||||
|
@ -35,14 +36,14 @@ export const MassbanCmd = modActionsCmd({
|
|||
}
|
||||
|
||||
// Ask for ban reason (cleaner this way instead of trying to cram it into the args)
|
||||
msg.channel.createMessage("Ban reason? `cancel` to cancel");
|
||||
msg.channel.send("Ban reason? `cancel` to cancel");
|
||||
const banReasonReply = await waitForReply(pluginData.client, msg.channel as TextChannel, msg.author.id);
|
||||
if (!banReasonReply || !banReasonReply.content || banReasonReply.content.toLowerCase().trim() === "cancel") {
|
||||
sendErrorMessage(pluginData, msg.channel, "Cancelled");
|
||||
return;
|
||||
}
|
||||
|
||||
const banReason = formatReasonWithAttachments(banReasonReply.content, msg.attachments);
|
||||
const banReason = formatReasonWithAttachments(banReasonReply.content, msg.attachments.array());
|
||||
|
||||
// Verify we can act on each of the users specified
|
||||
for (const userId of args.userIds) {
|
||||
|
@ -60,7 +61,7 @@ export const MassbanCmd = modActionsCmd({
|
|||
pluginData.state.massbanQueue.length === 0
|
||||
? "Banning..."
|
||||
: `Massban queued. Waiting for previous massban to finish (max wait ${maxWaitTimeFormatted}).`;
|
||||
const loadingMsg = await msg.channel.createMessage(initialLoadingText);
|
||||
const loadingMsg = await msg.channel.send(initialLoadingText);
|
||||
|
||||
const waitTimeStart = performance.now();
|
||||
const waitingInterval = setInterval(() => {
|
||||
|
@ -95,7 +96,10 @@ export const MassbanCmd = modActionsCmd({
|
|||
ignoreEvent(pluginData, IgnoredEventType.Ban, userId, 120 * 1000);
|
||||
pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, userId, 120 * 1000);
|
||||
|
||||
await pluginData.guild.banMember(userId, 1, banReason != null ? encodeURIComponent(banReason) : undefined);
|
||||
await pluginData.guild.bans.create(userId, {
|
||||
days: 1,
|
||||
reason: banReason != null ? encodeURIComponent(banReason) : undefined,
|
||||
});
|
||||
|
||||
await casesPlugin.createCase({
|
||||
userId,
|
||||
|
|
|
@ -10,6 +10,7 @@ import { waitForReply } from "knub/dist/helpers";
|
|||
import { ignoreEvent } from "../functions/ignoreEvent";
|
||||
import { CasesPlugin } from "../../Cases/CasesPlugin";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { TextChannel } from "discord.js";
|
||||
|
||||
export const MassunbanCmd = modActionsCmd({
|
||||
trigger: "massunban",
|
||||
|
@ -30,14 +31,14 @@ export const MassunbanCmd = modActionsCmd({
|
|||
}
|
||||
|
||||
// Ask for unban reason (cleaner this way instead of trying to cram it into the args)
|
||||
msg.channel.createMessage("Unban reason? `cancel` to cancel");
|
||||
msg.channel.send("Unban reason? `cancel` to cancel");
|
||||
const unbanReasonReply = await waitForReply(pluginData.client, msg.channel as TextChannel, msg.author.id);
|
||||
if (!unbanReasonReply || !unbanReasonReply.content || unbanReasonReply.content.toLowerCase().trim() === "cancel") {
|
||||
sendErrorMessage(pluginData, msg.channel, "Cancelled");
|
||||
return;
|
||||
}
|
||||
|
||||
const unbanReason = formatReasonWithAttachments(unbanReasonReply.content, msg.attachments);
|
||||
const unbanReason = formatReasonWithAttachments(unbanReasonReply.content, msg.attachments.array());
|
||||
|
||||
// Ignore automatic unban cases and logs for these users
|
||||
// We'll create our own cases below and post a single "mass unbanned" log instead
|
||||
|
@ -48,7 +49,7 @@ export const MassunbanCmd = modActionsCmd({
|
|||
});
|
||||
|
||||
// Show a loading indicator since this can take a while
|
||||
const loadingMsg = await msg.channel.createMessage("Unbanning...");
|
||||
const loadingMsg = await msg.channel.send("Unbanning...");
|
||||
|
||||
// Unban each user and count failed unbans (if any)
|
||||
const failedUnbans: Array<{ userId: string; reason: UnbanFailReasons }> = [];
|
||||
|
@ -60,7 +61,7 @@ export const MassunbanCmd = modActionsCmd({
|
|||
}
|
||||
|
||||
try {
|
||||
await pluginData.guild.unbanMember(userId, unbanReason != null ? encodeURIComponent(unbanReason) : undefined);
|
||||
await pluginData.guild.bans.remove(userId, unbanReason != null ? encodeURIComponent(unbanReason) : undefined);
|
||||
|
||||
await casesPlugin.createCase({
|
||||
userId,
|
||||
|
|
|
@ -8,6 +8,7 @@ import { waitForReply } from "knub/dist/helpers";
|
|||
import { LogType } from "../../../data/LogType";
|
||||
import { logger } from "../../../logger";
|
||||
import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin";
|
||||
import { TextChannel } from "discord.js";
|
||||
|
||||
export const MassmuteCmd = modActionsCmd({
|
||||
trigger: "massmute",
|
||||
|
@ -28,7 +29,7 @@ export const MassmuteCmd = modActionsCmd({
|
|||
}
|
||||
|
||||
// Ask for mute reason
|
||||
msg.channel.createMessage("Mute reason? `cancel` to cancel");
|
||||
msg.channel.send("Mute reason? `cancel` to cancel");
|
||||
const muteReasonReceived = await waitForReply(pluginData.client, msg.channel as TextChannel, msg.author.id);
|
||||
if (
|
||||
!muteReasonReceived ||
|
||||
|
@ -39,7 +40,7 @@ export const MassmuteCmd = modActionsCmd({
|
|||
return;
|
||||
}
|
||||
|
||||
const muteReason = formatReasonWithAttachments(muteReasonReceived.content, msg.attachments);
|
||||
const muteReason = formatReasonWithAttachments(muteReasonReceived.content, msg.attachments.array());
|
||||
|
||||
// Verify we can act upon all users
|
||||
for (const userId of args.userIds) {
|
||||
|
@ -58,7 +59,7 @@ export const MassmuteCmd = modActionsCmd({
|
|||
});
|
||||
|
||||
// Show loading indicator
|
||||
const loadingMsg = await msg.channel.createMessage("Muting...");
|
||||
const loadingMsg = await msg.channel.send("Muting...");
|
||||
|
||||
// Mute everyone and count fails
|
||||
const modId = msg.author.id;
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
import { modActionsCmd } from "../types";
|
||||
import { commandTypeHelpers as ct } from "../../../commandTypes";
|
||||
import { Case } from "../../../data/entities/Case";
|
||||
import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
|
||||
import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments";
|
||||
import { CasesPlugin } from "../../Cases/CasesPlugin";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { CaseTypes } from "../../../data/CaseTypes";
|
||||
import { errorMessage, noop, resolveMember, resolveUser, stripObjectToScalars } from "../../../utils";
|
||||
import { canActOn, sendErrorMessage } from "../../../pluginUtils";
|
||||
import { noop, resolveMember, resolveUser } from "../../../utils";
|
||||
import { isBanned } from "../functions/isBanned";
|
||||
import { waitForReaction } from "knub/dist/helpers";
|
||||
import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs";
|
||||
import { warnMember } from "../functions/warnMember";
|
||||
|
||||
import { actualMuteUserCmd } from "../functions/actualMuteUserCmd";
|
||||
|
||||
|
@ -62,11 +54,11 @@ export const MuteCmd = modActionsCmd({
|
|||
return;
|
||||
} else {
|
||||
// Ask the mod if we should upgrade to a forcemute as the user is not on the server
|
||||
const notOnServerMsg = await msg.channel.createMessage("User not found on the server, forcemute instead?");
|
||||
const reply = await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id);
|
||||
const notOnServerMsg = await msg.channel.send("User not found on the server, forcemute instead?");
|
||||
const reply = false; // await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton
|
||||
|
||||
notOnServerMsg.delete().catch(noop);
|
||||
if (!reply || reply.name === "❌") {
|
||||
if (!reply /*|| reply.name === "❌"*/) {
|
||||
sendErrorMessage(pluginData, msg.channel, "User not on server, mute cancelled by moderator");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -25,13 +25,13 @@ export const NoteCmd = modActionsCmd({
|
|||
return;
|
||||
}
|
||||
|
||||
if (!args.note && msg.attachments.length === 0) {
|
||||
if (!args.note && msg.attachments.size === 0) {
|
||||
sendErrorMessage(pluginData, msg.channel, "Text or attachment required");
|
||||
return;
|
||||
}
|
||||
|
||||
const userName = `${user.username}#${user.discriminator}`;
|
||||
const reason = formatReasonWithAttachments(args.note, msg.attachments);
|
||||
const reason = formatReasonWithAttachments(args.note, msg.attachments.array());
|
||||
|
||||
const casesPlugin = pluginData.getPlugin(CasesPlugin);
|
||||
const createdCase = await casesPlugin.createCase({
|
||||
|
|
|
@ -28,7 +28,7 @@ export const SoftbanCmd = modActionsCmd({
|
|||
|
||||
async run({ pluginData, message: msg, args }) {
|
||||
await actualKickMemberCmd(pluginData, msg, { clean: true, ...args });
|
||||
await msg.channel.createMessage(
|
||||
await msg.channel.send(
|
||||
"Softban will be removed in the future - please use the kick command with the `-clean` argument instead!",
|
||||
);
|
||||
},
|
||||
|
|
|
@ -45,11 +45,11 @@ export const UnbanCmd = modActionsCmd({
|
|||
}
|
||||
|
||||
pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, user.id);
|
||||
const reason = formatReasonWithAttachments(args.reason, msg.attachments);
|
||||
const reason = formatReasonWithAttachments(args.reason, msg.attachments.array());
|
||||
|
||||
try {
|
||||
ignoreEvent(pluginData, IgnoredEventType.Unban, user.id);
|
||||
await pluginData.guild.unbanMember(user.id, reason != null ? encodeURIComponent(reason) : undefined);
|
||||
await pluginData.guild.bans.remove(user.id, reason != null ? encodeURIComponent(reason) : undefined);
|
||||
} catch {
|
||||
sendErrorMessage(pluginData, msg.channel, "Failed to unban member; are you sure they're banned?");
|
||||
return;
|
||||
|
|
|
@ -5,7 +5,6 @@ import { resolveUser, resolveMember, noop } from "../../../utils";
|
|||
import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin";
|
||||
import { actualUnmuteCmd } from "../functions/actualUnmuteUserCmd";
|
||||
import { isBanned } from "../functions/isBanned";
|
||||
import { waitForReaction } from "knub/dist/helpers";
|
||||
|
||||
const opts = {
|
||||
mod: ct.member({ option: true }),
|
||||
|
@ -61,11 +60,11 @@ export const UnmuteCmd = modActionsCmd({
|
|||
return;
|
||||
} else {
|
||||
// Ask the mod if we should upgrade to a forceunmute as the user is not on the server
|
||||
const notOnServerMsg = await msg.channel.createMessage("User not found on the server, forceunmute instead?");
|
||||
const reply = await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id);
|
||||
const notOnServerMsg = await msg.channel.send("User not found on the server, forceunmute instead?");
|
||||
const reply = false; //await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton
|
||||
|
||||
notOnServerMsg.delete().catch(noop);
|
||||
if (!reply || reply.name === "❌") {
|
||||
if (!reply /*|| reply.name === "❌"*/) {
|
||||
sendErrorMessage(pluginData, msg.channel, "User not on server, unmute cancelled by moderator");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ import { LogType } from "../../../data/LogType";
|
|||
import { CaseTypes } from "../../../data/CaseTypes";
|
||||
import { errorMessage, resolveMember, resolveUser, stripObjectToScalars } from "../../../utils";
|
||||
import { isBanned } from "../functions/isBanned";
|
||||
import { waitForReaction } from "knub/dist/helpers";
|
||||
import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs";
|
||||
import { warnMember } from "../functions/warnMember";
|
||||
import { TextChannel } from "discord.js";
|
||||
|
||||
export const WarnCmd = modActionsCmd({
|
||||
trigger: "warn",
|
||||
|
@ -56,7 +56,7 @@ export const WarnCmd = modActionsCmd({
|
|||
let mod = msg.member;
|
||||
if (args.mod) {
|
||||
if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) {
|
||||
msg.channel.createMessage(errorMessage("You don't have permission to use -mod"));
|
||||
msg.channel.send(errorMessage("You don't have permission to use -mod"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -64,19 +64,19 @@ export const WarnCmd = modActionsCmd({
|
|||
}
|
||||
|
||||
const config = pluginData.config.get();
|
||||
const reason = formatReasonWithAttachments(args.reason, msg.attachments);
|
||||
const reason = formatReasonWithAttachments(args.reason, msg.attachments.array());
|
||||
|
||||
const casesPlugin = pluginData.getPlugin(CasesPlugin);
|
||||
const priorWarnAmount = await casesPlugin.getCaseTypeAmountForUserId(memberToWarn.id, CaseTypes.Warn);
|
||||
if (config.warn_notify_enabled && priorWarnAmount >= config.warn_notify_threshold) {
|
||||
const tooManyWarningsMsg = await msg.channel.createMessage(
|
||||
const tooManyWarningsMsg = await msg.channel.send(
|
||||
config.warn_notify_message.replace("{priorWarnings}", `${priorWarnAmount}`),
|
||||
);
|
||||
|
||||
const reply = await waitForReaction(pluginData.client, tooManyWarningsMsg, ["✅", "❌"], msg.author.id);
|
||||
const reply = false; //await waitForReaction(pluginData.client, tooManyWarningsMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton
|
||||
tooManyWarningsMsg.delete();
|
||||
if (!reply || reply.name === "❌") {
|
||||
msg.channel.createMessage(errorMessage("Warn cancelled by moderator"));
|
||||
if (!reply /*|| reply.name === "❌"*/) {
|
||||
msg.channel.send(errorMessage("Warn cancelled by moderator"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAu
|
|||
import { LogType } from "../../../data/LogType";
|
||||
import { stripObjectToScalars, resolveUser, UnknownUser } from "../../../utils";
|
||||
import { Case } from "../../../data/entities/Case";
|
||||
import { GuildAuditLogs, User } from "discord.js";
|
||||
|
||||
/**
|
||||
* Create a BAN case automatically when a user is banned manually.
|
||||
|
@ -15,7 +16,8 @@ import { Case } from "../../../data/entities/Case";
|
|||
*/
|
||||
export const CreateBanCaseOnManualBanEvt = modActionsEvt({
|
||||
event: "guildBanAdd",
|
||||
async listener({ pluginData, args: { guild, user } }) {
|
||||
async listener({ pluginData, args: { ban } }) {
|
||||
const user = ban.user;
|
||||
if (isEventIgnored(pluginData, IgnoredEventType.Ban, user.id)) {
|
||||
clearIgnoredEvents(pluginData, IgnoredEventType.Ban, user.id);
|
||||
return;
|
||||
|
@ -23,7 +25,7 @@ export const CreateBanCaseOnManualBanEvt = modActionsEvt({
|
|||
|
||||
const relevantAuditLogEntry = await safeFindRelevantAuditLogEntry(
|
||||
pluginData,
|
||||
ErisConstants.AuditLogActions.MEMBER_BAN_ADD,
|
||||
GuildAuditLogs.Actions.MEMBER_BAN_ADD as number,
|
||||
user.id,
|
||||
);
|
||||
|
||||
|
@ -34,7 +36,7 @@ export const CreateBanCaseOnManualBanEvt = modActionsEvt({
|
|||
let reason = "";
|
||||
|
||||
if (relevantAuditLogEntry) {
|
||||
const modId = relevantAuditLogEntry.user.id;
|
||||
const modId = relevantAuditLogEntry.executor!.id;
|
||||
const auditLogId = relevantAuditLogEntry.id;
|
||||
|
||||
mod = await resolveUser(pluginData.client, modId);
|
||||
|
|
|
@ -9,6 +9,7 @@ import { LogType } from "../../../data/LogType";
|
|||
import { resolveUser, stripObjectToScalars, UnknownUser } from "../../../utils";
|
||||
import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry";
|
||||
import { Case } from "../../../data/entities/Case";
|
||||
import { GuildAuditLogs, User } from "discord.js";
|
||||
|
||||
/**
|
||||
* Create a KICK case automatically when a user is kicked manually.
|
||||
|
@ -24,7 +25,7 @@ export const CreateKickCaseOnManualKickEvt = modActionsEvt({
|
|||
|
||||
const kickAuditLogEntry = await safeFindRelevantAuditLogEntry(
|
||||
pluginData,
|
||||
ErisConstants.AuditLogActions.MEMBER_KICK,
|
||||
GuildAuditLogs.Actions.MEMBER_KICK as number,
|
||||
member.id,
|
||||
);
|
||||
|
||||
|
@ -40,7 +41,7 @@ export const CreateKickCaseOnManualKickEvt = modActionsEvt({
|
|||
`Tried to create duplicate case for audit log entry ${kickAuditLogEntry.id}, existing case id ${createdCase.id}`,
|
||||
);
|
||||
} else {
|
||||
mod = await resolveUser(pluginData.client, kickAuditLogEntry.user.id);
|
||||
mod = await resolveUser(pluginData.client, kickAuditLogEntry.executor!.id);
|
||||
|
||||
const config = mod instanceof UnknownUser ? pluginData.config.get() : await pluginData.config.getForUser(mod);
|
||||
|
||||
|
@ -48,7 +49,7 @@ export const CreateKickCaseOnManualKickEvt = modActionsEvt({
|
|||
const casesPlugin = pluginData.getPlugin(CasesPlugin);
|
||||
createdCase = await casesPlugin.createCase({
|
||||
userId: member.id,
|
||||
modId: kickAuditLogEntry.user.id,
|
||||
modId: mod.id,
|
||||
type: CaseTypes.Kick,
|
||||
auditLogId: kickAuditLogEntry.id,
|
||||
reason: kickAuditLogEntry.reason || undefined,
|
||||
|
|
|
@ -8,6 +8,7 @@ import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAu
|
|||
import { stripObjectToScalars, resolveUser, UnknownUser } from "../../../utils";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { Case } from "../../../data/entities/Case";
|
||||
import { GuildAuditLogs, User } from "discord.js";
|
||||
|
||||
/**
|
||||
* Create an UNBAN case automatically when a user is unbanned manually.
|
||||
|
@ -15,7 +16,8 @@ import { Case } from "../../../data/entities/Case";
|
|||
*/
|
||||
export const CreateUnbanCaseOnManualUnbanEvt = modActionsEvt({
|
||||
event: "guildBanRemove",
|
||||
async listener({ pluginData, args: { guild, user } }) {
|
||||
async listener({ pluginData, args: { ban } }) {
|
||||
const user = ban.user;
|
||||
if (isEventIgnored(pluginData, IgnoredEventType.Unban, user.id)) {
|
||||
clearIgnoredEvents(pluginData, IgnoredEventType.Unban, user.id);
|
||||
return;
|
||||
|
@ -23,7 +25,7 @@ export const CreateUnbanCaseOnManualUnbanEvt = modActionsEvt({
|
|||
|
||||
const relevantAuditLogEntry = await safeFindRelevantAuditLogEntry(
|
||||
pluginData,
|
||||
ErisConstants.AuditLogActions.MEMBER_BAN_REMOVE,
|
||||
GuildAuditLogs.Actions.MEMBER_BAN_REMOVE as number,
|
||||
user.id,
|
||||
);
|
||||
|
||||
|
@ -33,7 +35,7 @@ export const CreateUnbanCaseOnManualUnbanEvt = modActionsEvt({
|
|||
let mod: User | UnknownUser | null = null;
|
||||
|
||||
if (relevantAuditLogEntry) {
|
||||
const modId = relevantAuditLogEntry.user.id;
|
||||
const modId = relevantAuditLogEntry.executor!.id;
|
||||
const auditLogId = relevantAuditLogEntry.id;
|
||||
|
||||
mod = await resolveUser(pluginData.client, modId);
|
||||
|
|
|
@ -4,13 +4,14 @@ import { LogType } from "../../../data/LogType";
|
|||
|
||||
import { resolveMember } from "../../../utils";
|
||||
import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions";
|
||||
import { TextChannel, Constants, Permissions } from "discord.js";
|
||||
|
||||
/**
|
||||
* Show an alert if a member with prior notes joins the server
|
||||
*/
|
||||
export const PostAlertOnMemberJoinEvt = modActionsEvt({
|
||||
event: "guildMemberAdd",
|
||||
async listener({ pluginData, args: { guild, member } }) {
|
||||
async listener({ pluginData, args: { member } }) {
|
||||
const config = pluginData.config.get();
|
||||
|
||||
if (!config.alert_on_rejoin) return;
|
||||
|
@ -38,15 +39,15 @@ export const PostAlertOnMemberJoinEvt = modActionsEvt({
|
|||
}
|
||||
|
||||
const botMember = await resolveMember(pluginData.client, pluginData.guild, pluginData.client.user!.id);
|
||||
const botPerms = alertChannel.permissionsOf(botMember ?? pluginData.client.user!.id);
|
||||
if (!hasDiscordPermissions(botPerms, Constants.Permissions.sendMessages)) {
|
||||
const botPerms = alertChannel.permissionsFor(botMember ?? pluginData.client.user!.id);
|
||||
if (!hasDiscordPermissions(botPerms, Permissions.FLAGS.SEND_MESSAGES)) {
|
||||
logs.log(LogType.BOT_ALERT, {
|
||||
body: `Missing "Send Messages" permissions for the \`alert_channel\` configured in \`mod_actions\`: \`${alertChannelId}\``,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await alertChannel.createMessage(
|
||||
await alertChannel.send(
|
||||
`<@!${member.id}> (${member.user.username}#${member.user.discriminator} \`${member.id}\`) joined with ${actions.length} prior record(s)`,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import { formatReasonWithAttachments } from "./formatReasonWithAttachments";
|
|||
import { kickMember } from "./kickMember";
|
||||
import { ignoreEvent } from "./ignoreEvent";
|
||||
import { isBanned } from "./isBanned";
|
||||
import { GuildMember, TextChannel } from "discord.js";
|
||||
|
||||
export async function actualKickMemberCmd(
|
||||
pluginData: GuildPluginData<ModActionsPluginType>,
|
||||
|
@ -16,7 +17,7 @@ export async function actualKickMemberCmd(
|
|||
args: {
|
||||
user: string;
|
||||
reason: string;
|
||||
mod: Member;
|
||||
mod: GuildMember;
|
||||
notify?: string;
|
||||
"notify-channel"?: TextChannel;
|
||||
clean?: boolean;
|
||||
|
@ -81,7 +82,7 @@ export async function actualKickMemberCmd(
|
|||
ignoreEvent(pluginData, IgnoredEventType.Ban, memberToKick.id);
|
||||
|
||||
try {
|
||||
await memberToKick.ban(1, encodeURIComponent("kick -clean"));
|
||||
await memberToKick.ban({ days: 1, reason: encodeURIComponent("kick -clean") });
|
||||
} catch {
|
||||
sendErrorMessage(pluginData, msg.channel, "Failed to ban the user to clean messages (-clean)");
|
||||
}
|
||||
|
@ -90,14 +91,14 @@ export async function actualKickMemberCmd(
|
|||
ignoreEvent(pluginData, IgnoredEventType.Unban, memberToKick.id);
|
||||
|
||||
try {
|
||||
await pluginData.guild.unbanMember(memberToKick.id, encodeURIComponent("kick -clean"));
|
||||
await pluginData.guild.bans.remove(memberToKick.id, encodeURIComponent("kick -clean"));
|
||||
} catch {
|
||||
sendErrorMessage(pluginData, msg.channel, "Failed to unban the user after banning them (-clean)");
|
||||
}
|
||||
}
|
||||
|
||||
if (kickResult.status === "failed") {
|
||||
msg.channel.createMessage(errorMessage(`Failed to kick user`));
|
||||
msg.channel.send(errorMessage(`Failed to kick user`));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import { MutesPlugin } from "../../Mutes/MutesPlugin";
|
|||
import { readContactMethodsFromArgs } from "./readContactMethodsFromArgs";
|
||||
import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError";
|
||||
import { logger } from "../../../logger";
|
||||
import { User, Message, TextChannel, GuildMember } from "discord.js";
|
||||
|
||||
/**
|
||||
* The actual function run by both !mute and !forcemute.
|
||||
|
@ -17,16 +18,16 @@ import { logger } from "../../../logger";
|
|||
export async function actualMuteUserCmd(
|
||||
pluginData: GuildPluginData<ModActionsPluginType>,
|
||||
user: User | UnknownUser,
|
||||
msg: Message<GuildTextableChannel>,
|
||||
args: { time?: number; reason?: string; mod: Member; notify?: string; "notify-channel"?: TextChannel },
|
||||
msg: Message,
|
||||
args: { time?: number; reason?: string; mod: GuildMember; notify?: string; "notify-channel"?: TextChannel },
|
||||
) {
|
||||
// The moderator who did the action is the message author or, if used, the specified -mod
|
||||
let mod: Member = msg.member;
|
||||
let mod: GuildMember = msg.member!;
|
||||
let pp: User | null = null;
|
||||
|
||||
if (args.mod) {
|
||||
if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) {
|
||||
sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod");
|
||||
sendErrorMessage(pluginData, msg.channel as TextChannel, "You don't have permission to use -mod");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -35,7 +36,7 @@ export async function actualMuteUserCmd(
|
|||
}
|
||||
|
||||
const timeUntilUnmute = args.time && humanizeDuration(args.time);
|
||||
const reason = args.reason ? formatReasonWithAttachments(args.reason, msg.attachments) : undefined;
|
||||
const reason = args.reason ? formatReasonWithAttachments(args.reason, msg.attachments.array()) : undefined;
|
||||
|
||||
let muteResult: MuteResult;
|
||||
const mutesPlugin = pluginData.getPlugin(MutesPlugin);
|
||||
|
@ -44,7 +45,7 @@ export async function actualMuteUserCmd(
|
|||
try {
|
||||
contactMethods = readContactMethodsFromArgs(args);
|
||||
} catch (e) {
|
||||
sendErrorMessage(pluginData, msg.channel, e.message);
|
||||
sendErrorMessage(pluginData, msg.channel as TextChannel, e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -58,16 +59,16 @@ export async function actualMuteUserCmd(
|
|||
});
|
||||
} catch (e) {
|
||||
if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) {
|
||||
sendErrorMessage(pluginData, msg.channel, "Could not mute the user: no mute role set in config");
|
||||
sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not mute the user: no mute role set in config");
|
||||
} else if (isDiscordRESTError(e) && e.code === 10007) {
|
||||
sendErrorMessage(pluginData, msg.channel, "Could not mute the user: unknown member");
|
||||
sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not mute the user: unknown member");
|
||||
} else {
|
||||
logger.error(`Failed to mute user ${user.id}: ${e.stack}`);
|
||||
if (user.id == null) {
|
||||
// tslint-disable-next-line:no-console
|
||||
console.trace("[DEBUG] Null user.id for mute");
|
||||
}
|
||||
sendErrorMessage(pluginData, msg.channel, "Could not mute the user");
|
||||
sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not mute the user");
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -102,5 +103,5 @@ export async function actualMuteUserCmd(
|
|||
}
|
||||
|
||||
if (muteResult.notifyResult.text) response += ` (${muteResult.notifyResult.text})`;
|
||||
sendSuccessMessage(pluginData, msg.channel, response);
|
||||
sendSuccessMessage(pluginData, msg.channel as TextChannel, response);
|
||||
}
|
||||
|
|
|
@ -6,12 +6,13 @@ import { sendErrorMessage, sendSuccessMessage, hasPermission } from "../../../pl
|
|||
import { formatReasonWithAttachments } from "./formatReasonWithAttachments";
|
||||
import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin";
|
||||
import humanizeDuration from "humanize-duration";
|
||||
import { User, Message, GuildMember, TextChannel } from "discord.js";
|
||||
|
||||
export async function actualUnmuteCmd(
|
||||
pluginData: GuildPluginData<ModActionsPluginType>,
|
||||
user: User | UnknownUser,
|
||||
msg: Message,
|
||||
args: { time?: number; reason?: string; mod?: Member },
|
||||
args: { time?: number; reason?: string; mod?: GuildMember },
|
||||
) {
|
||||
// The moderator who did the action is the message author or, if used, the specified -mod
|
||||
let mod = msg.author;
|
||||
|
@ -19,7 +20,7 @@ export async function actualUnmuteCmd(
|
|||
|
||||
if (args.mod) {
|
||||
if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg, channelId: msg.channel.id }))) {
|
||||
sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod");
|
||||
sendErrorMessage(pluginData, msg.channel as TextChannel, "You don't have permission to use -mod");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -27,7 +28,7 @@ export async function actualUnmuteCmd(
|
|||
pp = msg.author;
|
||||
}
|
||||
|
||||
const reason = args.reason ? formatReasonWithAttachments(args.reason, msg.attachments) : undefined;
|
||||
const reason = args.reason ? formatReasonWithAttachments(args.reason, msg.attachments.array()) : undefined;
|
||||
|
||||
const mutesPlugin = pluginData.getPlugin(MutesPlugin);
|
||||
const result = await mutesPlugin.unmuteUser(user.id, args.time, {
|
||||
|
@ -37,7 +38,7 @@ export async function actualUnmuteCmd(
|
|||
});
|
||||
|
||||
if (!result) {
|
||||
sendErrorMessage(pluginData, msg.channel, "User is not muted!");
|
||||
sendErrorMessage(pluginData, msg.channel as TextChannel, "User is not muted!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -46,7 +47,7 @@ export async function actualUnmuteCmd(
|
|||
const timeUntilUnmute = args.time && humanizeDuration(args.time);
|
||||
sendSuccessMessage(
|
||||
pluginData,
|
||||
msg.channel,
|
||||
msg.channel as TextChannel,
|
||||
asSingleLine(`
|
||||
Unmuting **${user.username}#${user.discriminator}**
|
||||
in ${timeUntilUnmute} (Case #${result.case.case_number})
|
||||
|
@ -55,7 +56,7 @@ export async function actualUnmuteCmd(
|
|||
} else {
|
||||
sendSuccessMessage(
|
||||
pluginData,
|
||||
msg.channel,
|
||||
msg.channel as TextChannel,
|
||||
asSingleLine(`
|
||||
Unmuted **${user.username}#${user.discriminator}**
|
||||
(Case #${result.case.case_number})
|
||||
|
|
|
@ -17,6 +17,7 @@ import { CasesPlugin } from "../../Cases/CasesPlugin";
|
|||
import { CaseTypes } from "../../../data/CaseTypes";
|
||||
import { logger } from "../../../logger";
|
||||
import humanizeDuration from "humanize-duration";
|
||||
import { DiscordAPIError, User } from "discord.js";
|
||||
|
||||
/**
|
||||
* Ban the specified user id, whether or not they're actually on the server at the time. Generates a case.
|
||||
|
@ -77,14 +78,13 @@ export async function banUserId(
|
|||
ignoreEvent(pluginData, IgnoredEventType.Ban, userId);
|
||||
try {
|
||||
const deleteMessageDays = Math.min(30, Math.max(0, banOptions.deleteMessageDays ?? 1));
|
||||
await pluginData.guild.banMember(
|
||||
userId,
|
||||
deleteMessageDays,
|
||||
reason != null ? encodeURIComponent(reason) : undefined,
|
||||
);
|
||||
await pluginData.guild.bans.create(userId, {
|
||||
days: deleteMessageDays,
|
||||
reason: reason != null ? encodeURIComponent(reason) : undefined,
|
||||
});
|
||||
} catch (e) {
|
||||
let errorMessage;
|
||||
if (e instanceof DiscordRESTError) {
|
||||
if (e instanceof DiscordAPIError) {
|
||||
errorMessage = `API error ${e.code}: ${e.message}`;
|
||||
} else {
|
||||
logger.warn(`Error applying ban to ${userId}: ${e}`);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
export function formatReasonWithAttachments(reason: string, attachments: Attachment[]) {
|
||||
import { MessageAttachment } from "discord.js";
|
||||
|
||||
export function formatReasonWithAttachments(reason: string, attachments: MessageAttachment[]) {
|
||||
const attachmentUrls = attachments.map(a => a.url);
|
||||
return ((reason || "") + " " + attachmentUrls.join(" ")).trim();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { GuildPluginData } from "knub";
|
||||
import { ModActionsPluginType } from "../types";
|
||||
import { UserNotificationMethod } from "../../../utils";
|
||||
import { TextChannel } from "discord.js";
|
||||
|
||||
export function getDefaultContactMethods(
|
||||
pluginData: GuildPluginData<ModActionsPluginType>,
|
||||
|
|
|
@ -4,6 +4,7 @@ import { isDiscordHTTPError, isDiscordRESTError, SECONDS, sleep } from "../../..
|
|||
import { LogsPlugin } from "../../Logs/LogsPlugin";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions";
|
||||
import { Permissions } from "discord.js";
|
||||
|
||||
export async function isBanned(
|
||||
pluginData: GuildPluginData<ModActionsPluginType>,
|
||||
|
@ -11,7 +12,7 @@ export async function isBanned(
|
|||
timeout: number = 5 * SECONDS,
|
||||
): Promise<boolean> {
|
||||
const botMember = pluginData.guild.members.cache.get(pluginData.client.user!.id);
|
||||
if (botMember && !hasDiscordPermissions(botMember.permissions, Constants.Permissions.banMembers)) {
|
||||
if (botMember && !hasDiscordPermissions(botMember.permissions, Permissions.FLAGS.BAN_MEMBERS)) {
|
||||
pluginData.getPlugin(LogsPlugin).log(LogType.BOT_ALERT, {
|
||||
body: `Missing "Ban Members" permission to check for existing bans`,
|
||||
});
|
||||
|
@ -19,7 +20,7 @@ export async function isBanned(
|
|||
}
|
||||
|
||||
try {
|
||||
const potentialBan = await Promise.race([pluginData.guild.getBan(userId), sleep(timeout)]);
|
||||
const potentialBan = await Promise.race([pluginData.guild.bans.fetch({ user: userId }), sleep(timeout)]);
|
||||
return potentialBan != null;
|
||||
} catch (e) {
|
||||
if (isDiscordRESTError(e) && e.code === 10026) {
|
||||
|
|
|
@ -15,13 +15,14 @@ import { LogType } from "../../../data/LogType";
|
|||
import { ignoreEvent } from "./ignoreEvent";
|
||||
import { CaseTypes } from "../../../data/CaseTypes";
|
||||
import { CasesPlugin } from "../../Cases/CasesPlugin";
|
||||
import { GuildMember } from "discord.js";
|
||||
|
||||
/**
|
||||
* Kick the specified server member. Generates a case.
|
||||
*/
|
||||
export async function kickMember(
|
||||
pluginData: GuildPluginData<ModActionsPluginType>,
|
||||
member: Member,
|
||||
member: GuildMember,
|
||||
reason?: string,
|
||||
kickOptions: KickOptions = {},
|
||||
): Promise<KickResult> {
|
||||
|
|
|
@ -30,7 +30,7 @@ export async function outdatedTempbansLoop(pluginData: GuildPluginData<ModAction
|
|||
);
|
||||
try {
|
||||
ignoreEvent(pluginData, IgnoredEventType.Unban, tempban.user_id);
|
||||
await pluginData.guild.unbanMember(tempban.user_id, reason != null ? encodeURIComponent(reason) : undefined);
|
||||
await pluginData.guild.bans.remove(tempban.user_id, reason != null ? encodeURIComponent(reason) : undefined);
|
||||
} catch (e) {
|
||||
pluginData.state.serverLogs.log(LogType.BOT_ALERT, {
|
||||
body: `Encountered an error trying to automatically unban ${tempban.user_id} after tempban timeout`,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { TextChannel } from "discord.js";
|
||||
import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils";
|
||||
|
||||
export function readContactMethodsFromArgs(args: {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { Message, TextChannel } from "discord.js";
|
||||
import { CaseTypes } from "../../../data/CaseTypes";
|
||||
import { Case } from "../../../data/entities/Case";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
|
@ -14,16 +15,16 @@ export async function updateCase(pluginData, msg: Message, args) {
|
|||
}
|
||||
|
||||
if (!theCase) {
|
||||
sendErrorMessage(pluginData, msg.channel, "Case not found");
|
||||
sendErrorMessage(pluginData, msg.channel as TextChannel, "Case not found");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args.note && msg.attachments.length === 0) {
|
||||
sendErrorMessage(pluginData, msg.channel, "Text or attachment required");
|
||||
if (!args.note && msg.attachments.size === 0) {
|
||||
sendErrorMessage(pluginData, msg.channel as TextChannel, "Text or attachment required");
|
||||
return;
|
||||
}
|
||||
|
||||
const note = formatReasonWithAttachments(args.note, msg.attachments);
|
||||
const note = formatReasonWithAttachments(args.note, msg.attachments.array());
|
||||
|
||||
const casesPlugin = pluginData.getPlugin(CasesPlugin);
|
||||
await casesPlugin.createCaseNote({
|
||||
|
@ -39,5 +40,5 @@ export async function updateCase(pluginData, msg: Message, args) {
|
|||
note,
|
||||
});
|
||||
|
||||
sendSuccessMessage(pluginData, msg.channel, `Case \`#${theCase.case_number}\` updated`);
|
||||
sendSuccessMessage(pluginData, msg.channel as TextChannel, `Case \`#${theCase.case_number}\` updated`);
|
||||
}
|
||||
|
|
|
@ -10,15 +10,15 @@ import {
|
|||
ucfirst,
|
||||
UserNotificationResult,
|
||||
} from "../../../utils";
|
||||
import { waitForReaction } from "knub/dist/helpers";
|
||||
import { CasesPlugin } from "../../Cases/CasesPlugin";
|
||||
import { CaseTypes } from "../../../data/CaseTypes";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { renderTemplate } from "../../../templateFormatter";
|
||||
import { GuildMember } from "discord.js";
|
||||
|
||||
export async function warnMember(
|
||||
pluginData: GuildPluginData<ModActionsPluginType>,
|
||||
member: Member,
|
||||
member: GuildMember,
|
||||
reason: string,
|
||||
warnOptions: WarnOptions = {},
|
||||
): Promise<WarnResult> {
|
||||
|
@ -42,13 +42,13 @@ export async function warnMember(
|
|||
}
|
||||
|
||||
if (!notifyResult.success) {
|
||||
if (warnOptions.retryPromptChannel && pluginData.guild.channels.has(warnOptions.retryPromptChannel.id)) {
|
||||
const failedMsg = await warnOptions.retryPromptChannel.createMessage(
|
||||
if (warnOptions.retryPromptChannel && pluginData.guild.channels.resolve(warnOptions.retryPromptChannel.id)) {
|
||||
const failedMsg = await warnOptions.retryPromptChannel.send(
|
||||
"Failed to message the user. Log the warning anyway?",
|
||||
);
|
||||
const reply = await waitForReaction(pluginData.client, failedMsg, ["✅", "❌"]);
|
||||
const reply = false; //await waitForReaction(pluginData.client, failedMsg, ["✅", "❌"]); FIXME waiting on waitForButton
|
||||
failedMsg.delete();
|
||||
if (!reply || reply.name === "❌") {
|
||||
if (!reply /*|| reply.name === "❌"*/) {
|
||||
return {
|
||||
status: "failed",
|
||||
error: "Failed to message user",
|
||||
|
|
|
@ -11,6 +11,7 @@ import { GuildTempbans } from "../../data/GuildTempbans";
|
|||
import Timeout = NodeJS.Timeout;
|
||||
import { EventEmitter } from "events";
|
||||
import { Queue } from "../../Queue";
|
||||
import { TextChannel } from "discord.js";
|
||||
|
||||
export const ConfigSchema = t.type({
|
||||
dm_on_warn: t.boolean,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue