mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-05-10 20:35:02 +00:00
Add case_id to mutes. Add !mutes command to list mutes.
This commit is contained in:
parent
60c434999e
commit
7a372533ec
9 changed files with 131 additions and 3 deletions
|
@ -9,6 +9,14 @@ export class GuildCases {
|
|||
this.guildId = guildId;
|
||||
}
|
||||
|
||||
async get(ids: number[]): Promise<Case[]> {
|
||||
const result = await knex("cases")
|
||||
.whereIn("id", ids)
|
||||
.select();
|
||||
|
||||
return result.map(r => new Case(r));
|
||||
}
|
||||
|
||||
async find(id: number): Promise<Case> {
|
||||
const result = await knex("cases")
|
||||
.where("guild_id", this.guildId)
|
||||
|
|
|
@ -69,6 +69,22 @@ export class GuildMutes {
|
|||
}
|
||||
}
|
||||
|
||||
async getActiveMutes(): Promise<Mute[]> {
|
||||
const result = await knex("mutes")
|
||||
.where("guild_id", this.guildId)
|
||||
.where(q => q.whereRaw("expires_at > NOW()").orWhereNull("expires_at"))
|
||||
.select();
|
||||
|
||||
return result.map(r => new Mute(r));
|
||||
}
|
||||
|
||||
async setCaseId(userId, caseId) {
|
||||
await knex("mutes")
|
||||
.where("guild_id", this.guildId)
|
||||
.where("user_id", userId)
|
||||
.update({ case_id: caseId });
|
||||
}
|
||||
|
||||
async clear(userId) {
|
||||
return knex("mutes")
|
||||
.where("guild_id", this.guildId)
|
||||
|
|
|
@ -3,6 +3,7 @@ import Model from "./Model";
|
|||
export default class Mute extends Model {
|
||||
public guild_id: string;
|
||||
public user_id: string;
|
||||
public case_id: number;
|
||||
public created_at: string;
|
||||
public expires_at: string;
|
||||
}
|
||||
|
|
|
@ -2,9 +2,11 @@ import { decorators as d, Plugin, waitForReaction } from "knub";
|
|||
import { Constants as ErisConstants, Guild, Member, Message, TextChannel, User } from "eris";
|
||||
import moment from "moment-timezone";
|
||||
import humanizeDuration from "humanize-duration";
|
||||
import chunk from "lodash.chunk";
|
||||
import { GuildCases } from "../data/GuildCases";
|
||||
import {
|
||||
convertDelayStringToMS,
|
||||
DBDateFormat,
|
||||
disableLinkPreviews,
|
||||
errorMessage,
|
||||
findRelevantAuditLogEntry,
|
||||
|
@ -36,8 +38,8 @@ interface IIgnoredEvent {
|
|||
const CASE_LIST_REASON_MAX_LENGTH = 80;
|
||||
|
||||
export class ModActionsPlugin extends Plugin {
|
||||
public mutes: GuildMutes;
|
||||
protected cases: GuildCases;
|
||||
protected mutes: GuildMutes;
|
||||
protected serverLogs: GuildLogs;
|
||||
|
||||
protected muteClearIntervalId: Timer;
|
||||
|
@ -355,7 +357,14 @@ export class ModActionsPlugin extends Plugin {
|
|||
this.muteMember(args.member, muteTime, args.reason);
|
||||
|
||||
// Create a case
|
||||
await this.createCase(args.member.id, msg.author.id, CaseType.Mute, null, args.reason);
|
||||
const caseId = await this.createCase(
|
||||
args.member.id,
|
||||
msg.author.id,
|
||||
CaseType.Mute,
|
||||
null,
|
||||
args.reason
|
||||
);
|
||||
await this.mutes.setCaseId(args.member.id, caseId);
|
||||
|
||||
// Message the user informing them of the mute
|
||||
let messageSent = true;
|
||||
|
@ -441,6 +450,78 @@ export class ModActionsPlugin extends Plugin {
|
|||
});
|
||||
}
|
||||
|
||||
@d.command("mutes")
|
||||
@d.permission("view")
|
||||
async mutesCmd(msg: Message) {
|
||||
const lines = [];
|
||||
|
||||
// Active, logged mutes
|
||||
const activeMutes = await this.mutes.getActiveMutes();
|
||||
activeMutes.sort((a, b) => {
|
||||
if (a.expires_at == null && b.expires_at != null) return 1;
|
||||
if (b.expires_at == null && a.expires_at != null) return -1;
|
||||
if (a.expires_at == null && b.expires_at == null) {
|
||||
return a.created_at > b.created_at ? 1 : -1;
|
||||
}
|
||||
return a.expires_at > b.expires_at ? 1 : -1;
|
||||
});
|
||||
|
||||
const caseIds = activeMutes.map(m => m.case_id).filter(v => !!v);
|
||||
const cases = caseIds ? await this.cases.get(caseIds) : [];
|
||||
const casesById = cases.reduce((map, c) => map.set(c.id, c), new Map());
|
||||
|
||||
lines.push(
|
||||
...activeMutes.map(mute => {
|
||||
const user = this.bot.users.get(mute.user_id);
|
||||
const username = user ? `${user.username}#${user.discriminator}` : "Unknown#0000";
|
||||
const theCase = casesById[mute.case_id] || null;
|
||||
const caseName = theCase ? `Case #${theCase.case_number}` : "No case";
|
||||
|
||||
let line = `\`${caseName}\` **${username}** (\`${mute.user_id}\`)`;
|
||||
|
||||
if (mute.expires_at) {
|
||||
const timeUntilExpiry = moment().diff(moment(mute.expires_at, DBDateFormat));
|
||||
const humanizedTime = humanizeDuration(timeUntilExpiry, { largest: 2, round: true });
|
||||
line += ` (expires in ${humanizedTime})`;
|
||||
} else {
|
||||
line += ` (doesn't expire)`;
|
||||
}
|
||||
|
||||
const mutedAt = moment(mute.created_at, DBDateFormat);
|
||||
line += ` (muted at ${mutedAt.format("YYYY-MM-DD HH:mm:ss")})`;
|
||||
|
||||
return line;
|
||||
})
|
||||
);
|
||||
|
||||
// Manually added mute roles
|
||||
const muteUserIds = activeMutes.reduce((set, m) => set.add(m.user_id), new Set());
|
||||
const manuallyMutedMembers = [];
|
||||
const muteRole = this.configValue("mute_role");
|
||||
|
||||
if (muteRole) {
|
||||
this.guild.members.forEach(member => {
|
||||
if (muteUserIds.has(member.id)) return;
|
||||
if (member.roles.includes(muteRole)) manuallyMutedMembers.push(member);
|
||||
});
|
||||
}
|
||||
|
||||
lines.push(
|
||||
...manuallyMutedMembers.map(member => {
|
||||
return `\`Manual mute\` **${member.user.username}#${member.user.discriminator}** (\`${
|
||||
member.id
|
||||
}\`)`;
|
||||
})
|
||||
);
|
||||
|
||||
const chunks = chunk(lines, 15);
|
||||
for (const [i, chunkLines] of chunks.entries()) {
|
||||
let body = chunkLines.join("\n");
|
||||
if (i === 0) body = `Active mutes:\n\n${body}`;
|
||||
msg.channel.createMessage(body);
|
||||
}
|
||||
}
|
||||
|
||||
@d.command("kick", "<member:Member> [reason:string$]")
|
||||
@d.permission("kick")
|
||||
async kickCmd(msg, args) {
|
||||
|
|
|
@ -192,7 +192,7 @@ export class SpamPlugin extends Plugin {
|
|||
spamConfig.mute_time ? spamConfig.mute_time * 60 * 1000 : 120 * 1000,
|
||||
"Automatic spam detection"
|
||||
);
|
||||
await modActionsPlugin.createCase(
|
||||
const caseId = await modActionsPlugin.createCase(
|
||||
msg.member.id,
|
||||
this.bot.user.id,
|
||||
CaseType.Mute,
|
||||
|
@ -205,6 +205,8 @@ export class SpamPlugin extends Plugin {
|
|||
`),
|
||||
true
|
||||
);
|
||||
await modActionsPlugin.mutes.setCaseId(msg.member.id, caseId);
|
||||
|
||||
this.logs.log(LogType.MEMBER_MUTE_SPAM, {
|
||||
member: stripObjectToScalars(msg.member, ["user"]),
|
||||
channel: stripObjectToScalars(msg.channel),
|
||||
|
|
|
@ -274,3 +274,5 @@ export function getRoleMentions(str: string) {
|
|||
export function disableLinkPreviews(str: string): string {
|
||||
return str.replace(/(?<!\<)(https?:\/\/\S+)/gi, "<$1>");
|
||||
}
|
||||
|
||||
export const DBDateFormat = "YYYY-MM-DD HH:mm:ss";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue