Skip to content

Commit

Permalink
mute/unmute
Browse files Browse the repository at this point in the history
  • Loading branch information
Kathund committed Aug 1, 2024
1 parent c265403 commit 7fecbc3
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/commands/automod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const data = new SlashCommandBuilder()
)
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages)
.setDMPermission(false);

export interface UserPermit {
id: string;
removeTime: number;
Expand Down
74 changes: 71 additions & 3 deletions src/commands/user.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// MAX MUTE TIME 2419200000
import {
ChatInputCommandInteraction,
SlashCommandBuilder,
Expand All @@ -9,6 +8,7 @@ import {
ButtonStyle
} from 'discord.js';
import Infraction, { getUserInfractions } from '../functions/Infraction';
import ms from 'ms';

export const data = new SlashCommandBuilder()
.setName('user')
Expand Down Expand Up @@ -43,6 +43,26 @@ export const data = new SlashCommandBuilder()
option.setName('reason').setDescription('The reason for the kick').setRequired(false)
)
)
.addSubcommand((subcommand) =>
subcommand
.setName('mute')
.setDescription('Mute a user')
.addUserOption((option) => option.setName('user').setDescription('The user to mute').setRequired(true))
.addStringOption((option) => option.setName('time').setDescription('How long to mute').setRequired(true))
.addStringOption((option) =>
option.setName('reason').setDescription('The reason for the mute').setRequired(false)
)
)
.addSubcommand((subcommand) =>
subcommand
.setName('unmute')
.setDescription('unmute a user')
.addUserOption((option) => option.setName('user').setDescription('The user to mute').setRequired(true))
.addStringOption((option) => option.setName('time').setDescription('How long to mute').setRequired(true))
.addStringOption((option) =>
option.setName('reason').setDescription('The reason for the mute').setRequired(false)
)
)
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages)
.setDMPermission(false);

Expand Down Expand Up @@ -113,8 +133,10 @@ export async function execute(interaction: ChatInputCommandInteraction): Promise
automatic: false,
reason: reason,
type: 'WARN',
long: null,
user: { id: commandUser.id, staff: false, bot: commandUser.bot },
staff: { id: interaction.user.id, staff: true, bot: interaction.user.bot }
staff: { id: interaction.user.id, staff: true, bot: interaction.user.bot },
timestamp: Date.now()
})
.log()
.save();
Expand All @@ -127,14 +149,60 @@ export async function execute(interaction: ChatInputCommandInteraction): Promise
automatic: false,
reason: reason,
type: 'KICK',
long: null,
user: { id: commandUser.id, staff: false, bot: commandUser.bot },
staff: { id: interaction.user.id, staff: true, bot: interaction.user.bot }
staff: { id: interaction.user.id, staff: true, bot: interaction.user.bot },
timestamp: Date.now()
})
.log()
.save();
await interaction.reply({ content: `<@${commandUser.id}> has been kicked`, ephemeral: true });
break;
}
case 'mute': {
const time = interaction.options.getString('time');
const reason = interaction.options.getString('reason') || 'No reason provided';
if (!time) {
await interaction.reply({ content: 'Please provide a time', ephemeral: true });
return;
}
const long = ms(time);
if (2419200000 < long) {
await interaction.reply({ content: 'You cannot mute someone for longer then 28d', ephemeral: true });
return;
}
user.timeout(long, reason);
new Infraction({
automatic: false,
reason: reason,
type: 'MUTE',
long,
user: { id: commandUser.id, staff: false, bot: commandUser.bot },
staff: { id: interaction.user.id, staff: true, bot: interaction.user.bot },
timestamp: Date.now()
})
.log()
.save();
await interaction.reply({ content: `<@${commandUser.id}> has been muted`, ephemeral: true });
break;
}
case 'unmute': {
const reason = interaction.options.getString('reason') || 'No reason provided';
user.timeout(null, reason);
new Infraction({
automatic: false,
reason: reason,
type: 'UNMUTE',
long: null,
user: { id: commandUser.id, staff: false, bot: commandUser.bot },
staff: { id: interaction.user.id, staff: true, bot: interaction.user.bot },
timestamp: Date.now()
})
.log()
.save();
await interaction.reply({ content: `<@${commandUser.id}> has been unmuted`, ephemeral: true });
break;
}
default: {
await interaction.reply({ content: 'Invalid subcommand Please provide a valid subcommand', ephemeral: true });
}
Expand Down
66 changes: 54 additions & 12 deletions src/functions/Infraction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,30 @@ export interface InfractionUser {
bot: boolean;
}

export type InfractionType = 'EVENT' | 'WARN' | 'KICK' | 'BAN';
export type InfractionType = 'EVENT' | 'WARN' | 'KICK' | 'BAN' | 'MUTE' | 'UNMUTE';

export interface InfractionInfomation {
automatic: boolean;
reason: string;
long: number | null;
type: InfractionType;
user: InfractionUser;
staff: InfractionUser;
timestamp: number;
}

const InteractionUserSchema = new Schema({ id: String, staff: Boolean, bot: Boolean });
const InfractionSchema = new Schema({
automatic: Boolean,
reason: String,
long: {
type: Number,
default: null
},
type: String,
user: InteractionUserSchema,
staff: InteractionUserSchema
staff: InteractionUserSchema,
timestamp: Number
});
const InfractionModel = model('infraction', InfractionSchema);

Expand All @@ -33,73 +40,107 @@ class Infraction {
constructor(infraction: InfractionInfomation) {
this.infraction = infraction;
}

public save() {
return new InfractionModel({
automatic: this.infraction.automatic,
reason: this.infraction.reason,
long: this.infraction.long,
type: this.infraction.type,
user: this.infraction.user,
staff: this.infraction.staff
staff: this.infraction.staff,
timestamp: this.infraction.timestamp
}).save();
}

public setAutomatic(automatic: boolean): this {
this.infraction.automatic = automatic;
return this;
}

public setReason(reason: string): this {
this.infraction.reason = reason;
return this;
}

public setLong(long: number | null): this {
this.infraction.long = long;
return this;
}

public setType(type: InfractionType): this {
this.infraction.type = type;
return this;
}

public setUser(user: InfractionUser): this {
this.infraction.user = user;
return this;
}

public setStaff(staff: InfractionUser): this {
this.infraction.staff = staff;
return this;
}
public getInfraction(): InfractionInfomation {
return this.infraction;

public setTimestamp(timestamp: number): this {
this.infraction.timestamp = timestamp;
return this;
}

public getAutomatic(): boolean {
return this.infraction.automatic;
}

public getReason(): string {
return this.infraction.reason;
}

public getLong(): number | null {
return this.infraction.long;
}

public getType(): InfractionType {
return this.infraction.type;
}

public getUser(): InfractionUser {
return this.infraction.user;
}
public getStaff(): InfractionUser | null {

public getStaff(): InfractionUser {
return this.infraction.staff;
}
public isAutomatic(): boolean {
return this.infraction.automatic;

public getTimestamp(): number {
return this.infraction.timestamp;
}

public toString(): string {
return `Infraction: ${this.infraction.reason}\nType: ${this.infraction.type}\nAutomatic: ${
this.infraction.automatic ? 'Yes' : 'No'
}\nUser: <@${this.infraction.user.id}>\nStaff: ${
return `Infraction: ${this.infraction.reason}\nType: ${this.infraction.type}\nLong: ${
this.infraction.long
}\nAutomatic: ${this.infraction.automatic ? 'Yes' : 'No'}\nUser: <@${this.infraction.user.id}>\nStaff: ${
this.infraction.staff ? `<@${this.infraction.staff.id}>` : 'None'
}`;
}\nTimestamp: <t:${Math.floor(
this.infraction.timestamp / 1000
)}:t> (<t:${Math.floor(this.infraction.timestamp / 1000)}:R>)`;
}

public log(): this {
const channel = guild.channels.cache.get(infractionLogchannel);
if (!channel || channel.type !== ChannelType.GuildText) return this;
channel.send(this.toString());
return this;
}
}

export interface InfractionReturn {
success: boolean;
info: string;
infraction?: Infraction;
infractions?: Infraction[];
}

export async function getUserInfractions(id: string): Promise<InfractionReturn> {
const userInfractions = await InfractionModel.find({ 'user.id': id });
if (!userInfractions) return { success: false, info: 'No infractions found' };
Expand All @@ -109,4 +150,5 @@ export async function getUserInfractions(id: string): Promise<InfractionReturn>
userInfractions.forEach((infraction) => foundInfraction.push(new Infraction(infraction)));
return { success: true, info: `User has ${foundInfraction.length} infractions`, infractions: foundInfraction };
}

export default Infraction;

0 comments on commit 7fecbc3

Please sign in to comment.