src/commands/slash/Main/hub/invite.ts
import Constants, { emojis } from '#utils/Constants.js';
import db from '#utils/Db.js';
import { t } from '#utils/Locale.js';
import Logger from '#utils/Logger.js';
import { captureException } from '@sentry/node';
import { CacheType, ChatInputCommandInteraction, EmbedBuilder } from 'discord.js';
import ms from 'ms';
import HubCommand from './index.js';
export default class Invite extends HubCommand {
readonly cooldown = 3000; // 3 seconds
async execute(interaction: ChatInputCommandInteraction<CacheType>) {
const subcommand = interaction.options.getSubcommand();
const { userManager } = interaction.client;
const locale = await userManager.getUserLocale(interaction.user.id);
switch (subcommand) {
case 'create': {
const hubName = interaction.options.getString('hub', true);
const expiryStr = interaction.options.getString('expiry');
const duration = expiryStr ? ms(expiryStr) : undefined;
const expires = new Date(Date.now() + (duration || 60 * 60 * 4000));
const hubInDb = await db.hub.findFirst({
where: {
name: hubName,
private: true,
OR: [
{ ownerId: interaction.user.id },
{ moderators: { some: { userId: interaction.user.id, position: 'manager' } } },
],
},
});
if (!hubInDb) {
await this.replyEmbed(interaction, t('hub.notFound_mod', locale, { emoji: emojis.no }), {
ephemeral: true,
});
return;
}
if (!Date.parse(expires.toString())) {
await interaction.reply({
content: `${emojis.no} Invalid Expiry Duration provided!`,
ephemeral: true,
});
return;
}
const createdInvite = await db.hubInvite.create({
data: {
hub: { connect: { name: hubName } },
expires,
},
});
const embed = new EmbedBuilder()
.setDescription(
t('hub.invite.create.success', locale, {
inviteCode: createdInvite.code,
docs_link: Constants.Links.Docs,
expiry: `<t:${Math.round(createdInvite.expires.getTime() / 1000)}:R>`,
}),
)
.setColor('Green')
.setTimestamp();
await interaction.reply({
embeds: [embed],
ephemeral: true,
});
break;
}
case 'revoke': {
const code = interaction.options.getString('code', true);
const inviteInDb = await db.hubInvite.findFirst({
where: {
code,
hub: {
OR: [
{ ownerId: interaction.user.id },
{ moderators: { some: { userId: interaction.user.id, position: 'manager' } } },
],
},
},
});
if (!inviteInDb) {
await interaction.reply({
content: t('hub.invite.revoke.invalidCode', locale, { emoji: emojis.no }),
ephemeral: true,
});
return;
}
try {
await db.hubInvite.delete({ where: { code } });
await this.replyEmbed(
interaction,
t('hub.invite.revoke.success', locale, { emoji: emojis.yes, inviteCode: code }),
{ ephemeral: true },
);
}
catch (e) {
Logger.error(e);
captureException(e);
await this.replyEmbed(
interaction,
t('errors.unknown', locale, {
emoji: emojis.no,
support_invite: Constants.Links.SupportInvite,
}),
{
ephemeral: true,
},
).catch(() => null);
return;
}
break;
}
case 'list': {
const hubName = interaction.options.getString('hub', true);
const hubInDb = await db.hub.findFirst({
where: {
name: hubName,
OR: [
{ ownerId: interaction.user.id },
{ moderators: { some: { userId: interaction.user.id, position: 'manager' } } },
],
},
});
if (!hubInDb?.private) {
await this.replyEmbed(
interaction,
t('hub.invite.list.notPrivate', locale, { emoji: emojis.no }),
{ ephemeral: true },
);
return;
}
const invitesInDb = await db.hubInvite.findMany({ where: { hubId: hubInDb.id } });
if (invitesInDb.length === 0) {
await this.replyEmbed(
interaction,
t('hub.invite.list.noInvites', locale, { emoji: emojis.no }),
{ ephemeral: true },
);
return;
}
const inviteArr = invitesInDb.map(
(inv, index) =>
`${index + 1}. \`${inv.code}\` - <t:${Math.round(inv.expires.getTime() / 1000)}:R>`,
);
const inviteEmbed = new EmbedBuilder()
.setTitle(t('hub.invite.list.title', locale))
.setDescription(inviteArr.join('\n'))
.setColor('Yellow')
.setTimestamp();
await interaction.reply({
embeds: [inviteEmbed],
ephemeral: true,
});
break;
}
default:
break;
}
}
}