Skip to content

Commit

Permalink
database logging of manual mod actions
Browse files Browse the repository at this point in the history
  • Loading branch information
Robin-Sch committed Apr 5, 2024
1 parent 03529bc commit b36258e
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 3 deletions.
2 changes: 0 additions & 2 deletions src/events/ClientReady.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ export default {
for (const mute of muteRows) {
const muteID = mute.id;

// TODO: make sure user leave + join back doesn't bypass mute, so add the muted role back when user joins and endtime hasn't passed yet

try {
console.log('auto unmute');
const guild = await client.guilds.fetch(mute.guild);
Expand Down
21 changes: 21 additions & 0 deletions src/events/channelDelete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ChannelType, DMChannel, Events, GuildChannel, TextChannel } from 'discord.js';
import { closeTicket } from '../utils/tickets';

export default {
name: Events.ChannelDelete,

async execute(channel: DMChannel | GuildChannel) {
if (channel.type !== ChannelType.GuildText || !(channel instanceof TextChannel)) return;

const result = await closeTicket(channel.id, channel.guildId); // not passing Channel is it's already deleted (by the event)
if (result.success && result.embed && result.memberID) {
// Ticket was a mail ticket
try {
const member = await channel.client.users.fetch(result.memberID);
await member.send({ embeds: [result.embed] });
} catch (e) {
//
}
}
},
};
31 changes: 31 additions & 0 deletions src/events/guildBanAdd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { AuditLogEvent, Events, GuildBan } from 'discord.js';
import { v4 as uuidv4 } from 'uuid';

import { query } from '../utils/postgres';

export default {
name: Events.GuildBanAdd,

async execute(ban: GuildBan) {
const logs = await ban.guild.fetchAuditLogs({ type: AuditLogEvent.MemberBanAdd, limit: 1 });
const log = logs.entries.first();
if (!log || log.executorId === ban.client.user.id) return;

const { executorId: moderatorID, targetId: memberID, reason, createdAt } = log;

await query('INSERT INTO guilds (id) VALUES ($1) ON CONFLICT DO NOTHING;', [ban.guild.id]);
await query('INSERT INTO users (id) VALUES ($1) ON CONFLICT DO NOTHING;', [memberID]);
await query('INSERT INTO users (id) VALUES ($1) ON CONFLICT DO NOTHING;', [moderatorID]);

const id = uuidv4();

await query('INSERT INTO bans (id, guild, member, reason, moderator, time) VALUES ($1,$2,$3,$4,$5,$6);', [
id,
ban.guild.id,
memberID,
reason,
moderatorID,
createdAt,
]);
},
};
31 changes: 31 additions & 0 deletions src/events/guildBanRemove.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { AuditLogEvent, Events, GuildBan } from 'discord.js';
import { v4 as uuidv4 } from 'uuid';

import { query } from '../utils/postgres';

export default {
name: Events.GuildBanRemove,

async execute(ban: GuildBan) {
const logs = await ban.guild.fetchAuditLogs({ type: AuditLogEvent.MemberBanRemove, limit: 1 });
const log = logs.entries.first();
if (!log || log.executorId === ban.client.user.id) return;

const { executorId: moderatorID, targetId: memberID, reason, createdAt } = log;

await query('INSERT INTO guilds (id) VALUES ($1) ON CONFLICT DO NOTHING;', [ban.guild.id]);
await query('INSERT INTO users (id) VALUES ($1) ON CONFLICT DO NOTHING;', [memberID]);
await query('INSERT INTO users (id) VALUES ($1) ON CONFLICT DO NOTHING;', [moderatorID]);

const id = uuidv4();

await query('INSERT INTO unbans (id, guild, member, reason, moderator, time) VALUES ($1,$2,$3,$4,$5,$6);', [
id,
ban.guild.id,
memberID,
reason,
moderatorID,
createdAt,
]);
},
};
25 changes: 25 additions & 0 deletions src/events/guildMemberAdd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Events, GuildMember } from 'discord.js';

import { query } from '../utils/postgres';

export default {
name: Events.GuildMemberAdd,

async execute(member: GuildMember) {
const { rows: muteRows } = await query(`SELECT reason FROM mutes WHERE member = $1 AND guild = $2 AND unmuted IS NULL;`, [member.id, member.guild.id]);

if (muteRows.length !== 0) {
let mutedRole: string | undefined;
const { rows: guildRows } = await query('SELECT muterole FROM guilds WHERE id = $1;', [member.guild.id]);
if (guildRows[0].length !== 0 && guildRows[0].muterole) mutedRole = guildRows[0].muterole;
else mutedRole = member.guild.roles.cache.find((role) => role.name.toLowerCase() == 'muted' || role.name.toLowerCase() == 'mute')?.id;
if (!mutedRole) return;

try {
await member.roles.add(mutedRole, muteRows[0].reason);
} catch (e) {
//
}
}
},
};
58 changes: 58 additions & 0 deletions src/events/guildMemberUpdate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { AuditLogEvent, Events, GuildMember } from 'discord.js';
import { v4 as uuidv4 } from 'uuid';

import { query } from '../utils/postgres';

export default {
name: Events.GuildMemberUpdate,

async execute(oldMember: GuildMember, newMember: GuildMember) {
// TODO: check if muted role is added/removed manually

let mutedRole: string | undefined;
const { rows: guildRows } = await query('SELECT muterole FROM guilds WHERE id = $1;', [newMember.guild.id]);
if (guildRows[0].length !== 0 && guildRows[0].muterole) mutedRole = guildRows[0].muterole;
else mutedRole = newMember.guild.roles.cache.find((role) => role.name.toLowerCase() == 'muted' || role.name.toLowerCase() == 'mute')?.id;
if (!mutedRole) return;

const wasMuted = oldMember.roles.cache.has(mutedRole);
const isMuted = newMember.roles.cache.has(mutedRole);

if (wasMuted !== isMuted) {
const logs = await newMember.guild.fetchAuditLogs({ type: AuditLogEvent.MemberRoleUpdate, limit: 1 });
const log = logs.entries.first();
if (!log || log.executorId === newMember.client.user.id) return;

const { executorId: moderatorID, targetId: memberID, reason, createdAt } = log;

console.log(moderatorID, memberID, reason, createdAt, wasMuted, isMuted);

await query('INSERT INTO guilds (id) VALUES ($1) ON CONFLICT DO NOTHING;', [newMember.guild.id]);
await query('INSERT INTO users (id) VALUES ($1) ON CONFLICT DO NOTHING;', [memberID]);
await query('INSERT INTO users (id) VALUES ($1) ON CONFLICT DO NOTHING;', [moderatorID]);

const id = uuidv4();

if (wasMuted && !isMuted) {
await query('INSERT INTO unmutes (id, guild, member, reason, moderator, time) VALUES ($1,$2,$3,$4,$5,$6);', [
id,
newMember.guild.id,
memberID,
reason,
moderatorID,
createdAt,
]);
await query('UPDATE mutes SET unmuted = true WHERE member = $1 AND guild = $2;', [memberID, newMember.guild.id]);
} else if (!wasMuted && isMuted) {
await query('INSERT INTO mutes (id, guild, member, reason, moderator, time) VALUES ($1,$2,$3,$4,$5,$6);', [
id,
newMember.guild.id,
memberID,
reason,
moderatorID,
createdAt,
]);
}
}
},
};
10 changes: 9 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ declare module 'discord.js' {
}

const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.DirectMessages],
intents: [
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildInvites,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildModeration,
GatewayIntentBits.Guilds,
GatewayIntentBits.MessageContent,
],
partials: [Partials.Channel], // Channel is required for DM messages
});
const commands: SlashCommandBuilder[] = [];
Expand Down

0 comments on commit b36258e

Please sign in to comment.