mirror of
https://github.com/nx-bat/discordbot-ng.git
synced 2026-09-22 10:29:10 -04:00
Fix line endings
This commit is contained in:
+140
-140
@@ -1,141 +1,141 @@
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, Guild, GuildMember, InteractionContextType, MessageMentions, PermissionFlagsBits, SlashCommandBuilder, time, TimestampStyles, User } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
import { AltData, comprehensiveAltLookupFromDiscord, deferInteraction } from '../utils';
|
||||
|
||||
const mentionRegex = new RegExp(MessageMentions.UsersPattern);
|
||||
|
||||
export default {
|
||||
name: 'ban',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ban')
|
||||
.setDescription('Bans a user.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user mention, or ID, to ban.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('reason')
|
||||
.setDescription('The reason for the ban')
|
||||
.setRequired(false)
|
||||
.setMaxLength(400)
|
||||
)
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('hours')
|
||||
.setDescription('The duration of the ban, added with other options (0 for permanent).')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('minutes')
|
||||
.setDescription('The duration of the ban, added with other options (0 for permanent).')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('seconds')
|
||||
.setDescription('The duration of the ban, added with other options (0 for permanent).')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('delete-message-days')
|
||||
.setDescription('How far back to delete messages (in days, default: 0 days).')
|
||||
.setRequired(false)
|
||||
.setMinValue(0)
|
||||
.setMaxValue(7)
|
||||
)
|
||||
.addBooleanOption(option =>
|
||||
option
|
||||
.setName('full-ban')
|
||||
.setDescription('Whether or not to prevent the user from joining on known alts (and ban all existing alts).')
|
||||
.setRequired(false)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await deferInteraction(interaction);
|
||||
|
||||
if (!interaction.guild) return interaction.editReply('This command must be used in a server');
|
||||
|
||||
if (!interaction.guild.members.me) return interaction.editReply('An error has occurred. Please try again later.');
|
||||
|
||||
const input = interaction.options.getString('user', true);
|
||||
|
||||
const matches = mentionRegex.exec(input);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const idToUse = matches ? matches.groups!.id : input;
|
||||
const reason = interaction.options.getString('reason') ?? '';
|
||||
|
||||
const hours = (interaction.options.getNumber('hours') ?? 0) * 3.6e+6;
|
||||
const minutes = (interaction.options.getNumber('minutes') ?? 0) * 60000;
|
||||
const seconds = (interaction.options.getNumber('seconds') ?? 0) * 1000;
|
||||
|
||||
const duration = hours + minutes + seconds;
|
||||
|
||||
const deleteMessageDays = (interaction.options.getNumber('delete-message-days') ?? 0) * 86400;
|
||||
|
||||
const fullBan = interaction.options.getBoolean('full-ban') ?? false;
|
||||
|
||||
let banMember: GuildMember | null = null;
|
||||
|
||||
try {
|
||||
banMember = await interaction.guild.members.fetch(idToUse);
|
||||
} catch (e) {
|
||||
// Member not in server.
|
||||
}
|
||||
|
||||
const member = await interaction.guild.members.fetch(interaction.user.id);
|
||||
|
||||
if (banMember && member.roles.highest.comparePositionTo(banMember.roles.highest) <= 0) {
|
||||
return await interaction.editReply('You do not have permission to ban this user.');
|
||||
}
|
||||
|
||||
if (banMember && !banMember.bannable) {
|
||||
return await interaction.editReply('I do not have permission to ban this user.');
|
||||
}
|
||||
|
||||
const expiresAt = new Date(Date.now() + duration);
|
||||
|
||||
await Database.putBan(idToUse, duration > 0 ? expiresAt : null, fullBan);
|
||||
|
||||
try {
|
||||
await interaction.guild.bans.create(idToUse, {
|
||||
reason: (reason + ` ${fullBan ? 'Full banned' : 'Banned'} by ${interaction.user.username} (${interaction.user.id})${duration > 0 ? `. Expires at: ${time(expiresAt, TimestampStyles.ShortDateTime)}` : ''}`).trim(),
|
||||
deleteMessageSeconds: deleteMessageDays
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return await interaction.editReply("Error banning user (couldn't ban).");
|
||||
}
|
||||
|
||||
if (fullBan) {
|
||||
const alts = await comprehensiveAltLookupFromDiscord(idToUse, interaction.guild);
|
||||
|
||||
await removeAllAlts([alts], interaction.guild, interaction.user, fullBan, reason, deleteMessageDays, duration, expiresAt);
|
||||
}
|
||||
|
||||
await interaction.editReply(`<@${idToUse}> (${idToUse}) has been ${fullBan ? 'full banned' : 'banned'}.`);
|
||||
}
|
||||
};
|
||||
|
||||
async function removeAllAlts(altData: AltData[], guild: Guild, moderator: User, fullBan: boolean, reason: string, deleteMessageDays: number, duration: number, expiresAt: Date) {
|
||||
for (const data of altData) {
|
||||
if (data.type == 'discord') {
|
||||
try {
|
||||
if (!data.banned) {
|
||||
await guild.members.kick(data.thisId as string, (reason + ` ${fullBan ? 'Full banned' : 'Banned'} by ${moderator.username} (${moderator.id})${duration > 0 ? `. Expires at: ${time(expiresAt, TimestampStyles.ShortDateTime)}` : ''}`).trim());
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
await removeAllAlts(data.alts, guild, moderator, fullBan, reason, deleteMessageDays, duration, expiresAt);
|
||||
}
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, Guild, GuildMember, InteractionContextType, MessageMentions, PermissionFlagsBits, SlashCommandBuilder, time, TimestampStyles, User } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
import { AltData, comprehensiveAltLookupFromDiscord, deferInteraction } from '../utils';
|
||||
|
||||
const mentionRegex = new RegExp(MessageMentions.UsersPattern);
|
||||
|
||||
export default {
|
||||
name: 'ban',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ban')
|
||||
.setDescription('Bans a user.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user mention, or ID, to ban.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('reason')
|
||||
.setDescription('The reason for the ban')
|
||||
.setRequired(false)
|
||||
.setMaxLength(400)
|
||||
)
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('hours')
|
||||
.setDescription('The duration of the ban, added with other options (0 for permanent).')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('minutes')
|
||||
.setDescription('The duration of the ban, added with other options (0 for permanent).')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('seconds')
|
||||
.setDescription('The duration of the ban, added with other options (0 for permanent).')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('delete-message-days')
|
||||
.setDescription('How far back to delete messages (in days, default: 0 days).')
|
||||
.setRequired(false)
|
||||
.setMinValue(0)
|
||||
.setMaxValue(7)
|
||||
)
|
||||
.addBooleanOption(option =>
|
||||
option
|
||||
.setName('full-ban')
|
||||
.setDescription('Whether or not to prevent the user from joining on known alts (and ban all existing alts).')
|
||||
.setRequired(false)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await deferInteraction(interaction);
|
||||
|
||||
if (!interaction.guild) return interaction.editReply('This command must be used in a server');
|
||||
|
||||
if (!interaction.guild.members.me) return interaction.editReply('An error has occurred. Please try again later.');
|
||||
|
||||
const input = interaction.options.getString('user', true);
|
||||
|
||||
const matches = mentionRegex.exec(input);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const idToUse = matches ? matches.groups!.id : input;
|
||||
const reason = interaction.options.getString('reason') ?? '';
|
||||
|
||||
const hours = (interaction.options.getNumber('hours') ?? 0) * 3.6e+6;
|
||||
const minutes = (interaction.options.getNumber('minutes') ?? 0) * 60000;
|
||||
const seconds = (interaction.options.getNumber('seconds') ?? 0) * 1000;
|
||||
|
||||
const duration = hours + minutes + seconds;
|
||||
|
||||
const deleteMessageDays = (interaction.options.getNumber('delete-message-days') ?? 0) * 86400;
|
||||
|
||||
const fullBan = interaction.options.getBoolean('full-ban') ?? false;
|
||||
|
||||
let banMember: GuildMember | null = null;
|
||||
|
||||
try {
|
||||
banMember = await interaction.guild.members.fetch(idToUse);
|
||||
} catch (e) {
|
||||
// Member not in server.
|
||||
}
|
||||
|
||||
const member = await interaction.guild.members.fetch(interaction.user.id);
|
||||
|
||||
if (banMember && member.roles.highest.comparePositionTo(banMember.roles.highest) <= 0) {
|
||||
return await interaction.editReply('You do not have permission to ban this user.');
|
||||
}
|
||||
|
||||
if (banMember && !banMember.bannable) {
|
||||
return await interaction.editReply('I do not have permission to ban this user.');
|
||||
}
|
||||
|
||||
const expiresAt = new Date(Date.now() + duration);
|
||||
|
||||
await Database.putBan(idToUse, duration > 0 ? expiresAt : null, fullBan);
|
||||
|
||||
try {
|
||||
await interaction.guild.bans.create(idToUse, {
|
||||
reason: (reason + ` ${fullBan ? 'Full banned' : 'Banned'} by ${interaction.user.username} (${interaction.user.id})${duration > 0 ? `. Expires at: ${time(expiresAt, TimestampStyles.ShortDateTime)}` : ''}`).trim(),
|
||||
deleteMessageSeconds: deleteMessageDays
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return await interaction.editReply("Error banning user (couldn't ban).");
|
||||
}
|
||||
|
||||
if (fullBan) {
|
||||
const alts = await comprehensiveAltLookupFromDiscord(idToUse, interaction.guild);
|
||||
|
||||
await removeAllAlts([alts], interaction.guild, interaction.user, fullBan, reason, deleteMessageDays, duration, expiresAt);
|
||||
}
|
||||
|
||||
await interaction.editReply(`<@${idToUse}> (${idToUse}) has been ${fullBan ? 'full banned' : 'banned'}.`);
|
||||
}
|
||||
};
|
||||
|
||||
async function removeAllAlts(altData: AltData[], guild: Guild, moderator: User, fullBan: boolean, reason: string, deleteMessageDays: number, duration: number, expiresAt: Date) {
|
||||
for (const data of altData) {
|
||||
if (data.type == 'discord') {
|
||||
try {
|
||||
if (!data.banned) {
|
||||
await guild.members.kick(data.thisId as string, (reason + ` ${fullBan ? 'Full banned' : 'Banned'} by ${moderator.username} (${moderator.id})${duration > 0 ? `. Expires at: ${time(expiresAt, TimestampStyles.ShortDateTime)}` : ''}`).trim());
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
await removeAllAlts(data.alts, guild, moderator, fullBan, reason, deleteMessageDays, duration, expiresAt);
|
||||
}
|
||||
}
|
||||
+47
-47
@@ -1,48 +1,48 @@
|
||||
import { ApplicationIntegrationType, AutocompleteInteraction, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
import { KnowledgebaseItem } from '../types';
|
||||
|
||||
export default {
|
||||
name: 'cite',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('cite')
|
||||
.setDescription('Cite content from the knowledgebase.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages)
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('name')
|
||||
.setDescription('The name of the entry.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
if (!interaction.guild) return interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Must be ran in guild.' });
|
||||
|
||||
await interaction.deferReply();
|
||||
|
||||
const id = interaction.options.getInteger('name', true);
|
||||
|
||||
const item = await Database.getFromKnowledgebase(id);
|
||||
|
||||
if (!item) return interaction.editReply('Knowledgebase item not found.');
|
||||
|
||||
return interaction.editReply(item.content);
|
||||
},
|
||||
autoComplete: async function (client: Client, interaction: AutocompleteInteraction) {
|
||||
if (!interaction.guild) return interaction.respond([]);
|
||||
|
||||
const items: KnowledgebaseItem[] = await Database.getAllKnowledgebaseItems(interaction.guild.id);
|
||||
|
||||
const value = interaction.options.getFocused();
|
||||
|
||||
const toRespond = items.filter(i => !value ? true : i.content.includes(value));
|
||||
if (toRespond.length > 25) toRespond.length = 25;
|
||||
|
||||
interaction.respond(toRespond.map(p => ({
|
||||
name: p.name,
|
||||
value: p.id
|
||||
})));
|
||||
}
|
||||
import { ApplicationIntegrationType, AutocompleteInteraction, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
import { KnowledgebaseItem } from '../types';
|
||||
|
||||
export default {
|
||||
name: 'cite',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('cite')
|
||||
.setDescription('Cite content from the knowledgebase.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages)
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('name')
|
||||
.setDescription('The name of the entry.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
if (!interaction.guild) return interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Must be ran in guild.' });
|
||||
|
||||
await interaction.deferReply();
|
||||
|
||||
const id = interaction.options.getInteger('name', true);
|
||||
|
||||
const item = await Database.getFromKnowledgebase(id);
|
||||
|
||||
if (!item) return interaction.editReply('Knowledgebase item not found.');
|
||||
|
||||
return interaction.editReply(item.content);
|
||||
},
|
||||
autoComplete: async function (client: Client, interaction: AutocompleteInteraction) {
|
||||
if (!interaction.guild) return interaction.respond([]);
|
||||
|
||||
const items: KnowledgebaseItem[] = await Database.getAllKnowledgebaseItems(interaction.guild.id);
|
||||
|
||||
const value = interaction.options.getFocused();
|
||||
|
||||
const toRespond = items.filter(i => !value ? true : i.content.includes(value));
|
||||
if (toRespond.length > 25) toRespond.length = 25;
|
||||
|
||||
interaction.respond(toRespond.map(p => ({
|
||||
name: p.name,
|
||||
value: p.id
|
||||
})));
|
||||
}
|
||||
};
|
||||
+41
-41
@@ -1,42 +1,42 @@
|
||||
import { ActionRowBuilder, ApplicationIntegrationType, ButtonBuilder, ButtonStyle, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
|
||||
export default {
|
||||
name: 'devwatch',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('devwatch')
|
||||
.setDescription('Sends a dev watch role toggle button.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('content')
|
||||
.setDescription('The content of the message.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('button-label')
|
||||
.setDescription('The button label.')
|
||||
.setRequired(false)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
if (!interaction.channel || !interaction.channel.isSendable())
|
||||
return interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Missing permissions to send to channel.' });
|
||||
|
||||
const content = interaction.options.getString('content') ?? '';
|
||||
const label = interaction.options.getString('button-label') ?? 'Toggle DevWatch Role';
|
||||
|
||||
const button = new ButtonBuilder()
|
||||
.setCustomId('dev-watch')
|
||||
.setStyle(ButtonStyle.Primary)
|
||||
.setLabel(label);
|
||||
|
||||
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||
.addComponents(button);
|
||||
|
||||
await interaction.channel.send({ components: [row], content });
|
||||
|
||||
interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Sent.' });
|
||||
}
|
||||
import { ActionRowBuilder, ApplicationIntegrationType, ButtonBuilder, ButtonStyle, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
|
||||
export default {
|
||||
name: 'devwatch',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('devwatch')
|
||||
.setDescription('Sends a dev watch role toggle button.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('content')
|
||||
.setDescription('The content of the message.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('button-label')
|
||||
.setDescription('The button label.')
|
||||
.setRequired(false)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
if (!interaction.channel || !interaction.channel.isSendable())
|
||||
return interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Missing permissions to send to channel.' });
|
||||
|
||||
const content = interaction.options.getString('content') ?? '';
|
||||
const label = interaction.options.getString('button-label') ?? 'Toggle DevWatch Role';
|
||||
|
||||
const button = new ButtonBuilder()
|
||||
.setCustomId('dev-watch')
|
||||
.setStyle(ButtonStyle.Primary)
|
||||
.setLabel(label);
|
||||
|
||||
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||
.addComponents(button);
|
||||
|
||||
await interaction.channel.send({ components: [row], content });
|
||||
|
||||
interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Sent.' });
|
||||
}
|
||||
};
|
||||
+41
-41
@@ -1,42 +1,42 @@
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { config } from '../config';
|
||||
import { deferInteraction, getDiscordAlts, getE621User } from '../utils';
|
||||
|
||||
export default {
|
||||
name: 'finduser',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('finduser')
|
||||
.setDescription("Find a user's discord account based on their e621 usernamename or id.")
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The e621 username or e621 id to find the discord user of.')
|
||||
.setRequired(true)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await deferInteraction(interaction);
|
||||
|
||||
if (!interaction.guild) return interaction.editReply('This command must be used in a server');
|
||||
|
||||
const user = interaction.options.getString('user', true);
|
||||
|
||||
try {
|
||||
const e621User = await getE621User(user);
|
||||
|
||||
if (!e621User) {
|
||||
return interaction.editReply('I got lost along the way. Who again?');
|
||||
}
|
||||
|
||||
const content = await getDiscordAlts(e621User.id, interaction.guild, 1, [e621User.id]);
|
||||
|
||||
interaction.editReply(`[${e621User.name}](${config.E621_BASE_URL}/users/${e621User.id})<${e621User.id}>'s e621 and discord account(s):\n${content}`);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
||||
interaction.editReply('I got lost in the net.');
|
||||
}
|
||||
}
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { config } from '../config';
|
||||
import { deferInteraction, getDiscordAlts, getE621User } from '../utils';
|
||||
|
||||
export default {
|
||||
name: 'finduser',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('finduser')
|
||||
.setDescription("Find a user's discord account based on their e621 usernamename or id.")
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The e621 username or e621 id to find the discord user of.')
|
||||
.setRequired(true)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await deferInteraction(interaction);
|
||||
|
||||
if (!interaction.guild) return interaction.editReply('This command must be used in a server');
|
||||
|
||||
const user = interaction.options.getString('user', true);
|
||||
|
||||
try {
|
||||
const e621User = await getE621User(user);
|
||||
|
||||
if (!e621User) {
|
||||
return interaction.editReply('I got lost along the way. Who again?');
|
||||
}
|
||||
|
||||
const content = await getDiscordAlts(e621User.id, interaction.guild, 1, [e621User.id]);
|
||||
|
||||
interaction.editReply(`[${e621User.name}](${config.E621_BASE_URL}/users/${e621User.id})<${e621User.id}>'s e621 and discord account(s):\n${content}`);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
||||
interaction.editReply('I got lost in the net.');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,87 +1,87 @@
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, MessageMentions, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
|
||||
const mentionRegex = new RegExp(MessageMentions.UsersPattern);
|
||||
|
||||
export default {
|
||||
name: 'github-mapping',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('github-mapping')
|
||||
.setDescription('Maps github users to discord ids for releases.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('add')
|
||||
.setDescription('Add a user mapping.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('discord-user')
|
||||
.setDescription('The discord user id, or mention, of the user.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('github-name')
|
||||
.setDescription('The github username of the user (case sensitive).')
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription('Remove a user mapping.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('discord-user')
|
||||
.setDescription('The discord user id, or mention, of the user.')
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('list')
|
||||
.setDescription('List all github-discord mappings.')
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
||||
|
||||
const subcommand = await interaction.options.getSubcommand(true);
|
||||
|
||||
if (subcommand == 'add') {
|
||||
const discordUserInput = interaction.options.getString('discord-user', true);
|
||||
|
||||
const matches = mentionRegex.exec(discordUserInput);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const idToUse = matches ? matches.groups!.id : discordUserInput;
|
||||
|
||||
const githubName = interaction.options.getString('github-name', true);
|
||||
|
||||
const existingMappingId = await Database.getGithubFromDiscordId(idToUse);
|
||||
const existingMappingName = await Database.getDiscordIdFromGithub(githubName);
|
||||
|
||||
if (existingMappingId) return interaction.editReply(`Discord user id is already mapped to ${existingMappingId}`);
|
||||
if (existingMappingName) return interaction.editReply(`Github username is already mapped to <@${existingMappingName}> (${existingMappingName})`);
|
||||
|
||||
Database.putGithubUserMapping(idToUse, githubName);
|
||||
|
||||
return interaction.editReply('Mapping added.');
|
||||
} else if (subcommand == 'remove') {
|
||||
const discordUserInput = interaction.options.getString('discord-user', true);
|
||||
|
||||
const matches = mentionRegex.exec(discordUserInput);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const idToUse = matches ? matches.groups!.id : discordUserInput;
|
||||
|
||||
Database.removeGithubUserMapping(idToUse);
|
||||
return interaction.editReply('Mapping removed.');
|
||||
} else if (subcommand == 'list') {
|
||||
const allMappings = await Database.getAllGithubUserMappings();
|
||||
|
||||
return interaction.editReply(allMappings.map(m => `- <@${m.discord_id}> (${m.discord_id}) - ${m.github_username}`).join('\n'));
|
||||
}
|
||||
}
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, MessageMentions, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
|
||||
const mentionRegex = new RegExp(MessageMentions.UsersPattern);
|
||||
|
||||
export default {
|
||||
name: 'github-mapping',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('github-mapping')
|
||||
.setDescription('Maps github users to discord ids for releases.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('add')
|
||||
.setDescription('Add a user mapping.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('discord-user')
|
||||
.setDescription('The discord user id, or mention, of the user.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('github-name')
|
||||
.setDescription('The github username of the user (case sensitive).')
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription('Remove a user mapping.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('discord-user')
|
||||
.setDescription('The discord user id, or mention, of the user.')
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('list')
|
||||
.setDescription('List all github-discord mappings.')
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
||||
|
||||
const subcommand = await interaction.options.getSubcommand(true);
|
||||
|
||||
if (subcommand == 'add') {
|
||||
const discordUserInput = interaction.options.getString('discord-user', true);
|
||||
|
||||
const matches = mentionRegex.exec(discordUserInput);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const idToUse = matches ? matches.groups!.id : discordUserInput;
|
||||
|
||||
const githubName = interaction.options.getString('github-name', true);
|
||||
|
||||
const existingMappingId = await Database.getGithubFromDiscordId(idToUse);
|
||||
const existingMappingName = await Database.getDiscordIdFromGithub(githubName);
|
||||
|
||||
if (existingMappingId) return interaction.editReply(`Discord user id is already mapped to ${existingMappingId}`);
|
||||
if (existingMappingName) return interaction.editReply(`Github username is already mapped to <@${existingMappingName}> (${existingMappingName})`);
|
||||
|
||||
Database.putGithubUserMapping(idToUse, githubName);
|
||||
|
||||
return interaction.editReply('Mapping added.');
|
||||
} else if (subcommand == 'remove') {
|
||||
const discordUserInput = interaction.options.getString('discord-user', true);
|
||||
|
||||
const matches = mentionRegex.exec(discordUserInput);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const idToUse = matches ? matches.groups!.id : discordUserInput;
|
||||
|
||||
Database.removeGithubUserMapping(idToUse);
|
||||
return interaction.editReply('Mapping removed.');
|
||||
} else if (subcommand == 'list') {
|
||||
const allMappings = await Database.getAllGithubUserMappings();
|
||||
|
||||
return interaction.editReply(allMappings.map(m => `- <@${m.discord_id}> (${m.discord_id}) - ${m.github_username}`).join('\n'));
|
||||
}
|
||||
}
|
||||
};
|
||||
+126
-126
@@ -1,127 +1,127 @@
|
||||
import { ApplicationIntegrationType, AutocompleteInteraction, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, ModalBuilder, PermissionFlagsBits, SlashCommandBuilder, TextInputStyle } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
import { KnowledgebaseItem } from '../types';
|
||||
import { createTextInput, deferInteraction, logCustomEvent } from '../utils';
|
||||
|
||||
export default {
|
||||
name: 'knowledgebase',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('knowledgebase')
|
||||
.setDescription('Access the compendium of knowledge.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('add')
|
||||
.setDescription('Add to the knowledgebase.')
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription('Purge knowledge from the universe.')
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('name')
|
||||
.setDescription('The name of the entry to remove.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('edit')
|
||||
.setDescription('Edit a knowledgebase entry.')
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('name')
|
||||
.setDescription('The name of the entry to edit.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
if (!interaction.guild) return interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Must be ran in guild.' });
|
||||
|
||||
const subcommand = interaction.options.getSubcommand(true);
|
||||
|
||||
if (subcommand == 'add') {
|
||||
const modal = new ModalBuilder()
|
||||
.setCustomId('add-knowledgebase-item-modal')
|
||||
.setTitle('Add to knowledgebase');
|
||||
|
||||
const nameLabel = createTextInput('name', 'Knowledgebase Item Name', null, true, TextInputStyle.Short, 300, 1);
|
||||
const contentLabel = createTextInput('content', 'Item Content', null, true, TextInputStyle.Paragraph, 2000, 1);
|
||||
|
||||
modal.addLabelComponents(nameLabel, contentLabel);
|
||||
|
||||
return await interaction.showModal(modal);
|
||||
} else if (subcommand == 'remove') {
|
||||
await deferInteraction(interaction);
|
||||
const id = interaction.options.getInteger('name', true);
|
||||
|
||||
const item = await Database.getFromKnowledgebase(id);
|
||||
|
||||
if (!item) return interaction.editReply('Knowledgebase item not found.');
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: 'Knowledgebase Item Removed',
|
||||
description: null,
|
||||
color: 0xFF0000,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Name',
|
||||
value: item.name,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Content',
|
||||
value: item.content,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
await Database.removeFromKnowledgebase(id);
|
||||
|
||||
return interaction.editReply(`Removed knowledgebase entry \`${item.name}\`.`);
|
||||
} else if (subcommand == 'edit') {
|
||||
const id = interaction.options.getInteger('name', true);
|
||||
|
||||
const existingItem = await Database.getFromKnowledgebase(id);
|
||||
|
||||
if (!existingItem) return interaction.editReply('Knowledgebase item not found.');
|
||||
|
||||
const modal = new ModalBuilder()
|
||||
.setCustomId(`edit-knowledgebase-item-modal_${id}`)
|
||||
.setTitle(`Editing knowledgebase item ${existingItem.name.slice(0, 18)}`);
|
||||
|
||||
const contentLabel = createTextInput('content', 'New Content', null, true, TextInputStyle.Paragraph, 2000, 1);
|
||||
|
||||
modal.addLabelComponents(contentLabel);
|
||||
|
||||
return await interaction.showModal(modal);
|
||||
}
|
||||
},
|
||||
autoComplete: async function (client: Client, interaction: AutocompleteInteraction) {
|
||||
if (!interaction.guild) return interaction.respond([]);
|
||||
|
||||
const items: KnowledgebaseItem[] = await Database.getAllKnowledgebaseItems(interaction.guild.id);
|
||||
|
||||
const value = interaction.options.getFocused();
|
||||
|
||||
const toRespond = items.filter(i => !value ? true : i.name.includes(value));
|
||||
if (toRespond.length > 25) toRespond.length = 25;
|
||||
|
||||
interaction.respond(toRespond.map(p => ({
|
||||
name: p.name,
|
||||
value: p.id
|
||||
})));
|
||||
}
|
||||
import { ApplicationIntegrationType, AutocompleteInteraction, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, ModalBuilder, PermissionFlagsBits, SlashCommandBuilder, TextInputStyle } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
import { KnowledgebaseItem } from '../types';
|
||||
import { createTextInput, deferInteraction, logCustomEvent } from '../utils';
|
||||
|
||||
export default {
|
||||
name: 'knowledgebase',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('knowledgebase')
|
||||
.setDescription('Access the compendium of knowledge.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('add')
|
||||
.setDescription('Add to the knowledgebase.')
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription('Purge knowledge from the universe.')
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('name')
|
||||
.setDescription('The name of the entry to remove.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('edit')
|
||||
.setDescription('Edit a knowledgebase entry.')
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('name')
|
||||
.setDescription('The name of the entry to edit.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
if (!interaction.guild) return interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Must be ran in guild.' });
|
||||
|
||||
const subcommand = interaction.options.getSubcommand(true);
|
||||
|
||||
if (subcommand == 'add') {
|
||||
const modal = new ModalBuilder()
|
||||
.setCustomId('add-knowledgebase-item-modal')
|
||||
.setTitle('Add to knowledgebase');
|
||||
|
||||
const nameLabel = createTextInput('name', 'Knowledgebase Item Name', null, true, TextInputStyle.Short, 300, 1);
|
||||
const contentLabel = createTextInput('content', 'Item Content', null, true, TextInputStyle.Paragraph, 2000, 1);
|
||||
|
||||
modal.addLabelComponents(nameLabel, contentLabel);
|
||||
|
||||
return await interaction.showModal(modal);
|
||||
} else if (subcommand == 'remove') {
|
||||
await deferInteraction(interaction);
|
||||
const id = interaction.options.getInteger('name', true);
|
||||
|
||||
const item = await Database.getFromKnowledgebase(id);
|
||||
|
||||
if (!item) return interaction.editReply('Knowledgebase item not found.');
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: 'Knowledgebase Item Removed',
|
||||
description: null,
|
||||
color: 0xFF0000,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Name',
|
||||
value: item.name,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Content',
|
||||
value: item.content,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
await Database.removeFromKnowledgebase(id);
|
||||
|
||||
return interaction.editReply(`Removed knowledgebase entry \`${item.name}\`.`);
|
||||
} else if (subcommand == 'edit') {
|
||||
const id = interaction.options.getInteger('name', true);
|
||||
|
||||
const existingItem = await Database.getFromKnowledgebase(id);
|
||||
|
||||
if (!existingItem) return interaction.editReply('Knowledgebase item not found.');
|
||||
|
||||
const modal = new ModalBuilder()
|
||||
.setCustomId(`edit-knowledgebase-item-modal_${id}`)
|
||||
.setTitle(`Editing knowledgebase item ${existingItem.name.slice(0, 18)}`);
|
||||
|
||||
const contentLabel = createTextInput('content', 'New Content', null, true, TextInputStyle.Paragraph, 2000, 1);
|
||||
|
||||
modal.addLabelComponents(contentLabel);
|
||||
|
||||
return await interaction.showModal(modal);
|
||||
}
|
||||
},
|
||||
autoComplete: async function (client: Client, interaction: AutocompleteInteraction) {
|
||||
if (!interaction.guild) return interaction.respond([]);
|
||||
|
||||
const items: KnowledgebaseItem[] = await Database.getAllKnowledgebaseItems(interaction.guild.id);
|
||||
|
||||
const value = interaction.options.getFocused();
|
||||
|
||||
const toRespond = items.filter(i => !value ? true : i.name.includes(value));
|
||||
if (toRespond.length > 25) toRespond.length = 25;
|
||||
|
||||
interaction.respond(toRespond.map(p => ({
|
||||
name: p.name,
|
||||
value: p.id
|
||||
})));
|
||||
}
|
||||
};
|
||||
+133
-133
@@ -1,134 +1,134 @@
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, MessageMentions, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { config } from '../config';
|
||||
import { Database } from '../shared/Database';
|
||||
import { logCustomEvent, resolveUser } from '../utils';
|
||||
|
||||
const mentionRegex = new RegExp(MessageMentions.UsersPattern);
|
||||
|
||||
export default {
|
||||
name: 'link',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('link')
|
||||
.setDescription('Manually link discord users and e621 users.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('create')
|
||||
.setDescription('Create a link.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('discord-user')
|
||||
.setDescription('The discord user id, or mention, of the user.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('e621-id')
|
||||
.setDescription('The id of the e621 user.')
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription('Remove a link.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('discord-user')
|
||||
.setDescription('The discord user id, or mention, of the user.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('e621-id')
|
||||
.setDescription('The id of the e621 user.')
|
||||
.setRequired(true)
|
||||
)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
||||
|
||||
const subcommand = await interaction.options.getSubcommand(true);
|
||||
|
||||
const discordUserInput = interaction.options.getString('discord-user', true);
|
||||
|
||||
const matches = mentionRegex.exec(discordUserInput);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const idToUse = matches ? matches.groups!.id : discordUserInput;
|
||||
|
||||
const user = await resolveUser(client, idToUse, interaction.guild);
|
||||
|
||||
if (!user) return interaction.editReply('User not found.');
|
||||
|
||||
const e621Id = interaction.options.getInteger('e621-id', true);
|
||||
|
||||
if (subcommand == 'create') {
|
||||
const existingLinks = await Database.getDiscordIds(e621Id);
|
||||
|
||||
if (existingLinks.includes(user.id)) return interaction.editReply('Accounts already linked.');
|
||||
|
||||
await Database.putUser(e621Id, user);
|
||||
|
||||
await logCustomEvent(interaction.guild!, {
|
||||
title: 'Account Link Created',
|
||||
description: null,
|
||||
color: 0x00FF00,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'Admin',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Discord User',
|
||||
value: `<@${user.id}>\n${user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'E621 User',
|
||||
value: `${config.E621_BASE_URL}/users/${e621Id}`,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
interaction.editReply('Accounts linked');
|
||||
} else if (subcommand == 'remove') {
|
||||
const existingLinks = await Database.getDiscordIds(e621Id);
|
||||
|
||||
if (!existingLinks.includes(user.id)) return interaction.editReply('Accounts not linked.');
|
||||
|
||||
await Database.removeUser(e621Id, user.id);
|
||||
|
||||
await logCustomEvent(interaction.guild!, {
|
||||
title: 'Account Link Removed',
|
||||
description: null,
|
||||
color: 0x00FF00,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'Admin',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Discord User',
|
||||
value: `<@${user.id}>\n${user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'E621 User',
|
||||
value: `${config.E621_BASE_URL}/users/${e621Id}`,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
interaction.editReply('Accounts unlinked');
|
||||
}
|
||||
}
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, MessageMentions, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { config } from '../config';
|
||||
import { Database } from '../shared/Database';
|
||||
import { logCustomEvent, resolveUser } from '../utils';
|
||||
|
||||
const mentionRegex = new RegExp(MessageMentions.UsersPattern);
|
||||
|
||||
export default {
|
||||
name: 'link',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('link')
|
||||
.setDescription('Manually link discord users and e621 users.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('create')
|
||||
.setDescription('Create a link.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('discord-user')
|
||||
.setDescription('The discord user id, or mention, of the user.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('e621-id')
|
||||
.setDescription('The id of the e621 user.')
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription('Remove a link.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('discord-user')
|
||||
.setDescription('The discord user id, or mention, of the user.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('e621-id')
|
||||
.setDescription('The id of the e621 user.')
|
||||
.setRequired(true)
|
||||
)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
||||
|
||||
const subcommand = await interaction.options.getSubcommand(true);
|
||||
|
||||
const discordUserInput = interaction.options.getString('discord-user', true);
|
||||
|
||||
const matches = mentionRegex.exec(discordUserInput);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const idToUse = matches ? matches.groups!.id : discordUserInput;
|
||||
|
||||
const user = await resolveUser(client, idToUse, interaction.guild);
|
||||
|
||||
if (!user) return interaction.editReply('User not found.');
|
||||
|
||||
const e621Id = interaction.options.getInteger('e621-id', true);
|
||||
|
||||
if (subcommand == 'create') {
|
||||
const existingLinks = await Database.getDiscordIds(e621Id);
|
||||
|
||||
if (existingLinks.includes(user.id)) return interaction.editReply('Accounts already linked.');
|
||||
|
||||
await Database.putUser(e621Id, user);
|
||||
|
||||
await logCustomEvent(interaction.guild!, {
|
||||
title: 'Account Link Created',
|
||||
description: null,
|
||||
color: 0x00FF00,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'Admin',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Discord User',
|
||||
value: `<@${user.id}>\n${user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'E621 User',
|
||||
value: `${config.E621_BASE_URL}/users/${e621Id}`,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
interaction.editReply('Accounts linked');
|
||||
} else if (subcommand == 'remove') {
|
||||
const existingLinks = await Database.getDiscordIds(e621Id);
|
||||
|
||||
if (!existingLinks.includes(user.id)) return interaction.editReply('Accounts not linked.');
|
||||
|
||||
await Database.removeUser(e621Id, user.id);
|
||||
|
||||
await logCustomEvent(interaction.guild!, {
|
||||
title: 'Account Link Removed',
|
||||
description: null,
|
||||
color: 0x00FF00,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'Admin',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Discord User',
|
||||
value: `<@${user.id}>\n${user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'E621 User',
|
||||
value: `${config.E621_BASE_URL}/users/${e621Id}`,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
interaction.editReply('Accounts unlinked');
|
||||
}
|
||||
}
|
||||
};
|
||||
+27
-27
@@ -1,28 +1,28 @@
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { openModTicketModal } from '../utils';
|
||||
|
||||
export default {
|
||||
name: 'mod-ticket',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('mod-ticket')
|
||||
.setDescription('Opens a mod private ticket and pulls the user into it.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.KickMembers)
|
||||
.addUserOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The user to pull in to the ticket.')
|
||||
.setRequired(true)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
if (!interaction.guild) return interaction.editReply('This command must be used in a server.');
|
||||
|
||||
const user = interaction.options.getUser('user', true);
|
||||
const member = await interaction.guild.members.fetch(user.id);
|
||||
|
||||
if (!member) return interaction.editReply('Could not find member.');
|
||||
|
||||
openModTicketModal(interaction, member);
|
||||
}
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { openModTicketModal } from '../utils';
|
||||
|
||||
export default {
|
||||
name: 'mod-ticket',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('mod-ticket')
|
||||
.setDescription('Opens a mod private ticket and pulls the user into it.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.KickMembers)
|
||||
.addUserOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The user to pull in to the ticket.')
|
||||
.setRequired(true)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
if (!interaction.guild) return interaction.editReply('This command must be used in a server.');
|
||||
|
||||
const user = interaction.options.getUser('user', true);
|
||||
const member = await interaction.guild.members.fetch(user.id);
|
||||
|
||||
if (!member) return interaction.editReply('Could not find member.');
|
||||
|
||||
openModTicketModal(interaction, member);
|
||||
}
|
||||
};
|
||||
+35
-35
@@ -1,36 +1,36 @@
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, SlashCommandBuilder } from 'discord.js';
|
||||
import { config } from '../config';
|
||||
import { syncName } from '../utils';
|
||||
|
||||
export default {
|
||||
name: 'name-sync',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('name-sync')
|
||||
.setDescription('Sync your discord nickname to your e621 name.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall)
|
||||
.setContexts(InteractionContextType.Guild, InteractionContextType.BotDM)
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('id')
|
||||
.setDescription('The id of the e621 user to sync your nickname to.')
|
||||
.setRequired(false)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
||||
const id = interaction.options.getInteger('id');
|
||||
|
||||
const guild = await interaction.client.guilds.fetch(config.DISCORD_GUILD_ID!);
|
||||
|
||||
if (!guild) {
|
||||
return interaction.editReply('An error has occurred. Please try again later.');
|
||||
}
|
||||
|
||||
const member = await guild.members.fetch(interaction.user.id);
|
||||
|
||||
if (!member || !guild.members.me) {
|
||||
return interaction.editReply('An error has occurred. Please try again later.');
|
||||
}
|
||||
|
||||
await syncName(interaction, member, id);
|
||||
}
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, SlashCommandBuilder } from 'discord.js';
|
||||
import { config } from '../config';
|
||||
import { syncName } from '../utils';
|
||||
|
||||
export default {
|
||||
name: 'name-sync',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('name-sync')
|
||||
.setDescription('Sync your discord nickname to your e621 name.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall, ApplicationIntegrationType.UserInstall)
|
||||
.setContexts(InteractionContextType.Guild, InteractionContextType.BotDM)
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('id')
|
||||
.setDescription('The id of the e621 user to sync your nickname to.')
|
||||
.setRequired(false)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
||||
const id = interaction.options.getInteger('id');
|
||||
|
||||
const guild = await interaction.client.guilds.fetch(config.DISCORD_GUILD_ID!);
|
||||
|
||||
if (!guild) {
|
||||
return interaction.editReply('An error has occurred. Please try again later.');
|
||||
}
|
||||
|
||||
const member = await guild.members.fetch(interaction.user.id);
|
||||
|
||||
if (!member || !guild.members.me) {
|
||||
return interaction.editReply('An error has occurred. Please try again later.');
|
||||
}
|
||||
|
||||
await syncName(interaction, member, id);
|
||||
}
|
||||
};
|
||||
+238
-238
@@ -1,239 +1,239 @@
|
||||
import { ApplicationIntegrationType, AutocompleteInteraction, ChatInputCommandInteraction, Client, InteractionContextType, MessageMentions, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
import { deferInteraction, logCustomEvent, resolveUser } from '../utils';
|
||||
import { getNoteMessage } from '../utils/note-utils';
|
||||
|
||||
const mentionRegex = new RegExp(MessageMentions.UsersPattern);
|
||||
|
||||
export default {
|
||||
name: 'notes',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('notes')
|
||||
.setDescription('Add, view, or remove user notes.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('add')
|
||||
.setDescription('Add notes to a user.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user mention, or ID, to add a note to.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('reason')
|
||||
.setDescription('The reason for the note.')
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('edit')
|
||||
.setDescription('Edit notes on a user.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user mention, or ID, to edit the notes of.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('note')
|
||||
.setDescription('The note to edit.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('new-reason')
|
||||
.setDescription('The new reason for the note.')
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription('Remove notes from a user.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user mention, or ID, to remove a note from.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('note')
|
||||
.setDescription('The note to remove.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('list')
|
||||
.setDescription("List a user's notes")
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user mention, or ID, to list the notes of.')
|
||||
.setRequired(true)
|
||||
)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
const subcommand = interaction.options.getSubcommand(true);
|
||||
|
||||
const input = interaction.options.getString('user', true);
|
||||
|
||||
const matches = mentionRegex.exec(input);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const idToUse = matches ? matches.groups!.id : input;
|
||||
|
||||
await deferInteraction(interaction);
|
||||
|
||||
const user = await resolveUser(client, idToUse, interaction.guild);
|
||||
|
||||
if (!user) return interaction.editReply('User not found.');
|
||||
|
||||
if (subcommand == 'add') {
|
||||
const reason = interaction.options.getString('reason', true);
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: 'Note Added',
|
||||
description: null,
|
||||
color: 0x00FF00,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'Moderator',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${user.id}>\n${user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Note',
|
||||
value: reason,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
await Database.putNote(user.id, reason, interaction.user.id);
|
||||
|
||||
interaction.editReply(`Note added to <@${user.id}> (\`${user.username}\` | \`${user.id}\`).\n\nReason:\n${reason}`);
|
||||
} else if (subcommand == 'remove') {
|
||||
const noteId = interaction.options.getInteger('note', true);
|
||||
|
||||
const notes = await Database.getNotes(user.id);
|
||||
const note = notes.find(n => n.id == noteId);
|
||||
|
||||
if (!note) return interaction.editReply('Note not found.');
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: 'Note Removed',
|
||||
description: null,
|
||||
color: 0xFF0000,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'Moderator',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${user.id}>\n${user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Note',
|
||||
value: `${note.reason}\nBy: <@${note.mod_id}>`,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
await Database.removeNote(noteId);
|
||||
interaction.editReply('Removed note.');
|
||||
} else if (subcommand == 'edit') {
|
||||
const noteId = interaction.options.getInteger('note', true);
|
||||
|
||||
const notes = await Database.getNotes(user.id);
|
||||
const note = notes.find(n => n.id == noteId);
|
||||
|
||||
if (!note) return interaction.editReply('Note not found.');
|
||||
|
||||
const reason = interaction.options.getString('new-reason', true);
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: 'Note Edited',
|
||||
description: null,
|
||||
color: 0x00FF00,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'Moderator',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${user.id}>\n${user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Old reason',
|
||||
value: note.reason
|
||||
},
|
||||
{
|
||||
name: 'New reason',
|
||||
value: reason,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
await Database.editNote(noteId, note.reason, reason, interaction.user.id);
|
||||
|
||||
interaction.editReply(`Note on <@${user.id}> (\`${user.username}\` | \`${user.id}\`) edited.\n\nNew reason:\n${reason}`);
|
||||
} else if (subcommand == 'list') {
|
||||
const noteMessage = await getNoteMessage(user.id, 1);
|
||||
|
||||
if (!noteMessage) return interaction.editReply(`No notes found for <@${user.id}> (\`${user.username}\` | \`${user.id}\`)`);
|
||||
|
||||
interaction.editReply(noteMessage);
|
||||
}
|
||||
},
|
||||
autoComplete: async function (client: Client, interaction: AutocompleteInteraction) {
|
||||
const input = interaction.options.getString('user', true);
|
||||
|
||||
const matches = mentionRegex.exec(input);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const idToUse = matches ? matches.groups!.id : input;
|
||||
|
||||
if (!idToUse) return interaction.respond([]);
|
||||
|
||||
const value = interaction.options.getFocused().toLowerCase();
|
||||
|
||||
const notes = await Database.getNotes(idToUse);
|
||||
|
||||
const toRespond = notes.filter(w => !value ? true : w.reason.toLowerCase().includes(value));
|
||||
if (toRespond.length > 25) toRespond.length = 25;
|
||||
|
||||
interaction.respond(toRespond.map((w) => {
|
||||
return {
|
||||
name: w.reason.substring(0, 50),
|
||||
value: w.id
|
||||
};
|
||||
}));
|
||||
}
|
||||
import { ApplicationIntegrationType, AutocompleteInteraction, ChatInputCommandInteraction, Client, InteractionContextType, MessageMentions, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
import { deferInteraction, logCustomEvent, resolveUser } from '../utils';
|
||||
import { getNoteMessage } from '../utils/note-utils';
|
||||
|
||||
const mentionRegex = new RegExp(MessageMentions.UsersPattern);
|
||||
|
||||
export default {
|
||||
name: 'notes',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('notes')
|
||||
.setDescription('Add, view, or remove user notes.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('add')
|
||||
.setDescription('Add notes to a user.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user mention, or ID, to add a note to.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('reason')
|
||||
.setDescription('The reason for the note.')
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('edit')
|
||||
.setDescription('Edit notes on a user.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user mention, or ID, to edit the notes of.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('note')
|
||||
.setDescription('The note to edit.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('new-reason')
|
||||
.setDescription('The new reason for the note.')
|
||||
.setRequired(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription('Remove notes from a user.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user mention, or ID, to remove a note from.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption(option =>
|
||||
option
|
||||
.setName('note')
|
||||
.setDescription('The note to remove.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('list')
|
||||
.setDescription("List a user's notes")
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user mention, or ID, to list the notes of.')
|
||||
.setRequired(true)
|
||||
)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
const subcommand = interaction.options.getSubcommand(true);
|
||||
|
||||
const input = interaction.options.getString('user', true);
|
||||
|
||||
const matches = mentionRegex.exec(input);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const idToUse = matches ? matches.groups!.id : input;
|
||||
|
||||
await deferInteraction(interaction);
|
||||
|
||||
const user = await resolveUser(client, idToUse, interaction.guild);
|
||||
|
||||
if (!user) return interaction.editReply('User not found.');
|
||||
|
||||
if (subcommand == 'add') {
|
||||
const reason = interaction.options.getString('reason', true);
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: 'Note Added',
|
||||
description: null,
|
||||
color: 0x00FF00,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'Moderator',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${user.id}>\n${user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Note',
|
||||
value: reason,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
await Database.putNote(user.id, reason, interaction.user.id);
|
||||
|
||||
interaction.editReply(`Note added to <@${user.id}> (\`${user.username}\` | \`${user.id}\`).\n\nReason:\n${reason}`);
|
||||
} else if (subcommand == 'remove') {
|
||||
const noteId = interaction.options.getInteger('note', true);
|
||||
|
||||
const notes = await Database.getNotes(user.id);
|
||||
const note = notes.find(n => n.id == noteId);
|
||||
|
||||
if (!note) return interaction.editReply('Note not found.');
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: 'Note Removed',
|
||||
description: null,
|
||||
color: 0xFF0000,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'Moderator',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${user.id}>\n${user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Note',
|
||||
value: `${note.reason}\nBy: <@${note.mod_id}>`,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
await Database.removeNote(noteId);
|
||||
interaction.editReply('Removed note.');
|
||||
} else if (subcommand == 'edit') {
|
||||
const noteId = interaction.options.getInteger('note', true);
|
||||
|
||||
const notes = await Database.getNotes(user.id);
|
||||
const note = notes.find(n => n.id == noteId);
|
||||
|
||||
if (!note) return interaction.editReply('Note not found.');
|
||||
|
||||
const reason = interaction.options.getString('new-reason', true);
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: 'Note Edited',
|
||||
description: null,
|
||||
color: 0x00FF00,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'Moderator',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${user.id}>\n${user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Old reason',
|
||||
value: note.reason
|
||||
},
|
||||
{
|
||||
name: 'New reason',
|
||||
value: reason,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
await Database.editNote(noteId, note.reason, reason, interaction.user.id);
|
||||
|
||||
interaction.editReply(`Note on <@${user.id}> (\`${user.username}\` | \`${user.id}\`) edited.\n\nNew reason:\n${reason}`);
|
||||
} else if (subcommand == 'list') {
|
||||
const noteMessage = await getNoteMessage(user.id, 1);
|
||||
|
||||
if (!noteMessage) return interaction.editReply(`No notes found for <@${user.id}> (\`${user.username}\` | \`${user.id}\`)`);
|
||||
|
||||
interaction.editReply(noteMessage);
|
||||
}
|
||||
},
|
||||
autoComplete: async function (client: Client, interaction: AutocompleteInteraction) {
|
||||
const input = interaction.options.getString('user', true);
|
||||
|
||||
const matches = mentionRegex.exec(input);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const idToUse = matches ? matches.groups!.id : input;
|
||||
|
||||
if (!idToUse) return interaction.respond([]);
|
||||
|
||||
const value = interaction.options.getFocused().toLowerCase();
|
||||
|
||||
const notes = await Database.getNotes(idToUse);
|
||||
|
||||
const toRespond = notes.filter(w => !value ? true : w.reason.toLowerCase().includes(value));
|
||||
if (toRespond.length > 25) toRespond.length = 25;
|
||||
|
||||
interaction.respond(toRespond.map((w) => {
|
||||
return {
|
||||
name: w.reason.substring(0, 50),
|
||||
value: w.id
|
||||
};
|
||||
}));
|
||||
}
|
||||
};
|
||||
+251
-251
@@ -1,252 +1,252 @@
|
||||
import { ApplicationIntegrationType, AutocompleteInteraction, ChatInputCommandInteraction, Client, InteractionContextType, PermissionFlagsBits, SlashCommandBuilder, User } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
import { TicketPhrase } from '../types';
|
||||
import { logCustomEvent } from '../utils';
|
||||
|
||||
const MIN_PHRASE_LENGTH = 1;
|
||||
const MAX_PHRASE_LENGTH = 512;
|
||||
|
||||
type SubcommandGroup = 'admin' | 'personal';
|
||||
type Subcommand = 'add' | 'remove' | 'list' | 'dump' | 'purge';
|
||||
|
||||
export default {
|
||||
name: 'phrases',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('phrases')
|
||||
.setDescription('Manage notified phrases.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addSubcommandGroup(subcommandGroup =>
|
||||
subcommandGroup
|
||||
.setName('admin')
|
||||
.setDescription('Manage admin notified phrases.')
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('add')
|
||||
.setDescription('Add an admin notification phrase.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('phrase')
|
||||
.setDescription('The phrase to add.')
|
||||
.setRequired(true)
|
||||
.setMinLength(MIN_PHRASE_LENGTH)
|
||||
.setMaxLength(MAX_PHRASE_LENGTH)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription('Remove an admin notification phrase.')
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('phrase')
|
||||
.setDescription('The phrase to remove.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('list')
|
||||
.setDescription('Get a list of the current admin notification phrases.')
|
||||
)
|
||||
)
|
||||
.addSubcommandGroup(subcommandGroup =>
|
||||
subcommandGroup
|
||||
.setName('personal')
|
||||
.setDescription('Manage personal notified phrases.')
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('add')
|
||||
.setDescription('Add a personal notification phrase.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('phrase')
|
||||
.setDescription('The phrase to add.')
|
||||
.setRequired(true)
|
||||
.setMinLength(MIN_PHRASE_LENGTH)
|
||||
.setMaxLength(MAX_PHRASE_LENGTH)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription('Remove a personal notification phrase.')
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('phrase')
|
||||
.setDescription('The phrase to remove.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('list')
|
||||
.setDescription('Get a list of the current personal notification phrases.')
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('dump')
|
||||
.setDescription('List all notification phrases.')
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('purge')
|
||||
.setDescription("Purge a user's phrases.")
|
||||
.addUserOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The user to purge the phrases of.')
|
||||
.setRequired(true)
|
||||
)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
const subcommandGroup: SubcommandGroup | null = interaction.options.getSubcommandGroup() as SubcommandGroup;
|
||||
const subcommand: Subcommand | null = interaction.options.getSubcommand() as Subcommand;
|
||||
|
||||
switch (subcommand) {
|
||||
case 'add':
|
||||
return addPhrase(interaction, interaction.options.getString('phrase', true), subcommandGroup!);
|
||||
case 'remove':
|
||||
return removePhrase(interaction, interaction.options.getNumber('phrase', true), subcommandGroup!);
|
||||
case 'list':
|
||||
return listPhrases(interaction, subcommandGroup!);
|
||||
case 'dump':
|
||||
return dumpPhrases(interaction);
|
||||
case 'purge':
|
||||
return purgePhrases(interaction, interaction.options.getUser('user', true));
|
||||
}
|
||||
},
|
||||
autoComplete: async function (client: Client, interaction: AutocompleteInteraction) {
|
||||
const subcommandGroup: SubcommandGroup | null = interaction.options.getSubcommandGroup() as SubcommandGroup;
|
||||
|
||||
if (!subcommandGroup) return interaction.respond([]);
|
||||
|
||||
const value = interaction.options.getFocused();
|
||||
|
||||
const phrases: TicketPhrase[] = await Database.getTicketPhrasesFor(subcommandGroup == 'admin' ? 'admin' : interaction.user.id);
|
||||
|
||||
const toRespond = phrases.filter(p => !value ? true : p.phrase.includes(value));
|
||||
if (toRespond.length > 25) toRespond.length = 25;
|
||||
|
||||
interaction.respond(toRespond.map(p => ({
|
||||
name: p.phrase,
|
||||
value: p.id
|
||||
})));
|
||||
}
|
||||
};
|
||||
|
||||
async function purgePhrases(interaction: ChatInputCommandInteraction, user: User) {
|
||||
const phrases: TicketPhrase[] = await Database.getTicketPhrasesFor(user.id);
|
||||
|
||||
const count = await Database.removeAllTicketPhrasesFor(user.id);
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: 'Ticket Phrases Purged',
|
||||
description: null,
|
||||
color: 0xFF0000,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Target User',
|
||||
value: `<@${user.id}>\n${user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Count',
|
||||
value: count.toString(),
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
interaction.reply(`Purged the following phrases (${count}):\n${phrases.map(p => `- \`${p.phrase}\``).join('\n')}`);
|
||||
}
|
||||
|
||||
async function dumpPhrases(interaction: ChatInputCommandInteraction) {
|
||||
let content = '';
|
||||
|
||||
const guildSettings = await Database.getGuildSettings(interaction.guildId!);
|
||||
|
||||
await Database.getAllTicketPhrases((phrase: TicketPhrase) => {
|
||||
if (phrase.user_id == 'admin' && (!guildSettings || !guildSettings.admin_role_id)) return;
|
||||
|
||||
const mention = phrase.user_id == 'admin' ? `<@&${guildSettings?.admin_role_id}>` : `<@${phrase.user_id}>`;
|
||||
|
||||
content += `${mention}: \`${phrase.phrase}\`\n`;
|
||||
});
|
||||
|
||||
if (content.length == 0) return interaction.reply('No phrases found.');
|
||||
|
||||
interaction.reply('The following phrases are registered:\n\n' + content);
|
||||
}
|
||||
|
||||
async function addPhrase(interaction: ChatInputCommandInteraction, phrase: string, group: SubcommandGroup) {
|
||||
await Database.putTicketPhrase(group == 'admin' ? 'admin' : interaction.user.id, phrase);
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: `${group == 'admin' ? 'Admin ' : ''}Ticket Phrase Added`,
|
||||
description: null,
|
||||
color: 0x00FF00,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Phrase',
|
||||
value: phrase,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
interaction.reply(`Phrases matching "${phrase}" will now alert ${group == 'admin' ? 'admins' : 'you'}.`);
|
||||
}
|
||||
|
||||
async function removePhrase(interaction: ChatInputCommandInteraction, phraseId: number, group: SubcommandGroup) {
|
||||
const phrase = await Database.getTicketPhrase(phraseId);
|
||||
|
||||
if (!phrase) return interaction.reply('Phrase not found');
|
||||
|
||||
await Database.removeTicketPhrase(phraseId);
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: `${group == 'admin' ? 'Admin ' : ''}Ticket Phrase Removed`,
|
||||
description: null,
|
||||
color: 0xFF0000,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Phrase',
|
||||
value: phrase.phrase,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
interaction.reply(`Phrase will no longer alert ${group == 'admin' ? 'admins' : 'you'}.`);
|
||||
}
|
||||
|
||||
async function listPhrases(interaction: ChatInputCommandInteraction, group: SubcommandGroup) {
|
||||
const phrases = await Database.getTicketPhrasesFor(group == 'admin' ? 'admin' : interaction.user.id);
|
||||
|
||||
if (phrases.length == 0) return interaction.reply('No phrases registered');
|
||||
|
||||
interaction.reply(`The following phrases are registered:\n\n${phrases.map(p => (`- \`${p.phrase}\``)).join('\n')}`);
|
||||
import { ApplicationIntegrationType, AutocompleteInteraction, ChatInputCommandInteraction, Client, InteractionContextType, PermissionFlagsBits, SlashCommandBuilder, User } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
import { TicketPhrase } from '../types';
|
||||
import { logCustomEvent } from '../utils';
|
||||
|
||||
const MIN_PHRASE_LENGTH = 1;
|
||||
const MAX_PHRASE_LENGTH = 512;
|
||||
|
||||
type SubcommandGroup = 'admin' | 'personal';
|
||||
type Subcommand = 'add' | 'remove' | 'list' | 'dump' | 'purge';
|
||||
|
||||
export default {
|
||||
name: 'phrases',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('phrases')
|
||||
.setDescription('Manage notified phrases.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addSubcommandGroup(subcommandGroup =>
|
||||
subcommandGroup
|
||||
.setName('admin')
|
||||
.setDescription('Manage admin notified phrases.')
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('add')
|
||||
.setDescription('Add an admin notification phrase.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('phrase')
|
||||
.setDescription('The phrase to add.')
|
||||
.setRequired(true)
|
||||
.setMinLength(MIN_PHRASE_LENGTH)
|
||||
.setMaxLength(MAX_PHRASE_LENGTH)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription('Remove an admin notification phrase.')
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('phrase')
|
||||
.setDescription('The phrase to remove.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('list')
|
||||
.setDescription('Get a list of the current admin notification phrases.')
|
||||
)
|
||||
)
|
||||
.addSubcommandGroup(subcommandGroup =>
|
||||
subcommandGroup
|
||||
.setName('personal')
|
||||
.setDescription('Manage personal notified phrases.')
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('add')
|
||||
.setDescription('Add a personal notification phrase.')
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('phrase')
|
||||
.setDescription('The phrase to add.')
|
||||
.setRequired(true)
|
||||
.setMinLength(MIN_PHRASE_LENGTH)
|
||||
.setMaxLength(MAX_PHRASE_LENGTH)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription('Remove a personal notification phrase.')
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('phrase')
|
||||
.setDescription('The phrase to remove.')
|
||||
.setRequired(true)
|
||||
.setAutocomplete(true)
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('list')
|
||||
.setDescription('Get a list of the current personal notification phrases.')
|
||||
)
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('dump')
|
||||
.setDescription('List all notification phrases.')
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('purge')
|
||||
.setDescription("Purge a user's phrases.")
|
||||
.addUserOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The user to purge the phrases of.')
|
||||
.setRequired(true)
|
||||
)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
const subcommandGroup: SubcommandGroup | null = interaction.options.getSubcommandGroup() as SubcommandGroup;
|
||||
const subcommand: Subcommand | null = interaction.options.getSubcommand() as Subcommand;
|
||||
|
||||
switch (subcommand) {
|
||||
case 'add':
|
||||
return addPhrase(interaction, interaction.options.getString('phrase', true), subcommandGroup!);
|
||||
case 'remove':
|
||||
return removePhrase(interaction, interaction.options.getNumber('phrase', true), subcommandGroup!);
|
||||
case 'list':
|
||||
return listPhrases(interaction, subcommandGroup!);
|
||||
case 'dump':
|
||||
return dumpPhrases(interaction);
|
||||
case 'purge':
|
||||
return purgePhrases(interaction, interaction.options.getUser('user', true));
|
||||
}
|
||||
},
|
||||
autoComplete: async function (client: Client, interaction: AutocompleteInteraction) {
|
||||
const subcommandGroup: SubcommandGroup | null = interaction.options.getSubcommandGroup() as SubcommandGroup;
|
||||
|
||||
if (!subcommandGroup) return interaction.respond([]);
|
||||
|
||||
const value = interaction.options.getFocused();
|
||||
|
||||
const phrases: TicketPhrase[] = await Database.getTicketPhrasesFor(subcommandGroup == 'admin' ? 'admin' : interaction.user.id);
|
||||
|
||||
const toRespond = phrases.filter(p => !value ? true : p.phrase.includes(value));
|
||||
if (toRespond.length > 25) toRespond.length = 25;
|
||||
|
||||
interaction.respond(toRespond.map(p => ({
|
||||
name: p.phrase,
|
||||
value: p.id
|
||||
})));
|
||||
}
|
||||
};
|
||||
|
||||
async function purgePhrases(interaction: ChatInputCommandInteraction, user: User) {
|
||||
const phrases: TicketPhrase[] = await Database.getTicketPhrasesFor(user.id);
|
||||
|
||||
const count = await Database.removeAllTicketPhrasesFor(user.id);
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: 'Ticket Phrases Purged',
|
||||
description: null,
|
||||
color: 0xFF0000,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Target User',
|
||||
value: `<@${user.id}>\n${user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Count',
|
||||
value: count.toString(),
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
interaction.reply(`Purged the following phrases (${count}):\n${phrases.map(p => `- \`${p.phrase}\``).join('\n')}`);
|
||||
}
|
||||
|
||||
async function dumpPhrases(interaction: ChatInputCommandInteraction) {
|
||||
let content = '';
|
||||
|
||||
const guildSettings = await Database.getGuildSettings(interaction.guildId!);
|
||||
|
||||
await Database.getAllTicketPhrases((phrase: TicketPhrase) => {
|
||||
if (phrase.user_id == 'admin' && (!guildSettings || !guildSettings.admin_role_id)) return;
|
||||
|
||||
const mention = phrase.user_id == 'admin' ? `<@&${guildSettings?.admin_role_id}>` : `<@${phrase.user_id}>`;
|
||||
|
||||
content += `${mention}: \`${phrase.phrase}\`\n`;
|
||||
});
|
||||
|
||||
if (content.length == 0) return interaction.reply('No phrases found.');
|
||||
|
||||
interaction.reply('The following phrases are registered:\n\n' + content);
|
||||
}
|
||||
|
||||
async function addPhrase(interaction: ChatInputCommandInteraction, phrase: string, group: SubcommandGroup) {
|
||||
await Database.putTicketPhrase(group == 'admin' ? 'admin' : interaction.user.id, phrase);
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: `${group == 'admin' ? 'Admin ' : ''}Ticket Phrase Added`,
|
||||
description: null,
|
||||
color: 0x00FF00,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Phrase',
|
||||
value: phrase,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
interaction.reply(`Phrases matching "${phrase}" will now alert ${group == 'admin' ? 'admins' : 'you'}.`);
|
||||
}
|
||||
|
||||
async function removePhrase(interaction: ChatInputCommandInteraction, phraseId: number, group: SubcommandGroup) {
|
||||
const phrase = await Database.getTicketPhrase(phraseId);
|
||||
|
||||
if (!phrase) return interaction.reply('Phrase not found');
|
||||
|
||||
await Database.removeTicketPhrase(phraseId);
|
||||
|
||||
logCustomEvent(interaction.guild!, {
|
||||
title: `${group == 'admin' ? 'Admin ' : ''}Ticket Phrase Removed`,
|
||||
description: null,
|
||||
color: 0xFF0000,
|
||||
timestamp: new Date(),
|
||||
fields: [
|
||||
{
|
||||
name: 'User',
|
||||
value: `<@${interaction.user.id}>\n${interaction.user.username}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: 'Phrase',
|
||||
value: phrase.phrase,
|
||||
inline: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
interaction.reply(`Phrase will no longer alert ${group == 'admin' ? 'admins' : 'you'}.`);
|
||||
}
|
||||
|
||||
async function listPhrases(interaction: ChatInputCommandInteraction, group: SubcommandGroup) {
|
||||
const phrases = await Database.getTicketPhrasesFor(group == 'admin' ? 'admin' : interaction.user.id);
|
||||
|
||||
if (phrases.length == 0) return interaction.reply('No phrases registered');
|
||||
|
||||
interaction.reply(`The following phrases are registered:\n\n${phrases.map(p => (`- \`${p.phrase}\``)).join('\n')}`);
|
||||
}
|
||||
@@ -1,45 +1,45 @@
|
||||
import { ActionRowBuilder, ApplicationIntegrationType, ButtonBuilder, ButtonStyle, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
|
||||
export default {
|
||||
name: 'private-help',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('private-help')
|
||||
.setDescription('Setup a private help button.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('content')
|
||||
.setDescription('The content of the message.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('button-label')
|
||||
.setDescription('The button label.')
|
||||
.setRequired(false)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
if (!interaction.channel || !interaction.channel.isSendable())
|
||||
return interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Missing permissions to send to channel.' });
|
||||
|
||||
const content = interaction.options.getString('content') ?? '';
|
||||
const label = interaction.options.getString('button-label') ?? 'Get in contact';
|
||||
|
||||
const button = new ButtonBuilder()
|
||||
.setCustomId('private-help')
|
||||
.setStyle(ButtonStyle.Primary)
|
||||
.setLabel(label);
|
||||
|
||||
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||
.addComponents(button);
|
||||
|
||||
await interaction.channel.send({ components: [row], content });
|
||||
|
||||
await Database.setPrivateHelpChannel(interaction.guildId!, interaction.channelId);
|
||||
|
||||
interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Sent.' });
|
||||
}
|
||||
import { ActionRowBuilder, ApplicationIntegrationType, ButtonBuilder, ButtonStyle, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
|
||||
export default {
|
||||
name: 'private-help',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('private-help')
|
||||
.setDescription('Setup a private help button.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('content')
|
||||
.setDescription('The content of the message.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('button-label')
|
||||
.setDescription('The button label.')
|
||||
.setRequired(false)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
if (!interaction.channel || !interaction.channel.isSendable())
|
||||
return interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Missing permissions to send to channel.' });
|
||||
|
||||
const content = interaction.options.getString('content') ?? '';
|
||||
const label = interaction.options.getString('button-label') ?? 'Get in contact';
|
||||
|
||||
const button = new ButtonBuilder()
|
||||
.setCustomId('private-help')
|
||||
.setStyle(ButtonStyle.Primary)
|
||||
.setLabel(label);
|
||||
|
||||
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||
.addComponents(button);
|
||||
|
||||
await interaction.channel.send({ components: [row], content });
|
||||
|
||||
await Database.setPrivateHelpChannel(interaction.guildId!, interaction.channelId);
|
||||
|
||||
interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Sent.' });
|
||||
}
|
||||
};
|
||||
+44
-44
@@ -1,45 +1,45 @@
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { deferInteraction } from '../utils';
|
||||
import { getRecordMessageFromDiscordId } from '../utils/record-utils';
|
||||
|
||||
export default {
|
||||
name: 'records',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('records')
|
||||
.setDescription("Get a user's on-site records.")
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addUserOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user to find the e621 user of.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('id')
|
||||
.setDescription('The discord user id to find the e621 user of.')
|
||||
.setRequired(false)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await deferInteraction(interaction);
|
||||
|
||||
if (!interaction.guild) return interaction.editReply('This command must be used in a server');
|
||||
|
||||
const user = interaction.options.getUser('user');
|
||||
const id = interaction.options.getString('id');
|
||||
|
||||
if (!user && !id) {
|
||||
return interaction.reply({ content: 'No user or id given.', flags: [MessageFlags.Ephemeral] });
|
||||
}
|
||||
|
||||
const idToUse = (user?.id ?? id) as string;
|
||||
|
||||
const recordMessage = await getRecordMessageFromDiscordId(idToUse, 1, interaction.guild);
|
||||
|
||||
if (!recordMessage) return interaction.editReply('No records found on any linked accounts.');
|
||||
|
||||
interaction.editReply(recordMessage);
|
||||
}
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { deferInteraction } from '../utils';
|
||||
import { getRecordMessageFromDiscordId } from '../utils/record-utils';
|
||||
|
||||
export default {
|
||||
name: 'records',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('records')
|
||||
.setDescription("Get a user's on-site records.")
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addUserOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user to find the e621 user of.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('id')
|
||||
.setDescription('The discord user id to find the e621 user of.')
|
||||
.setRequired(false)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await deferInteraction(interaction);
|
||||
|
||||
if (!interaction.guild) return interaction.editReply('This command must be used in a server');
|
||||
|
||||
const user = interaction.options.getUser('user');
|
||||
const id = interaction.options.getString('id');
|
||||
|
||||
if (!user && !id) {
|
||||
return interaction.reply({ content: 'No user or id given.', flags: [MessageFlags.Ephemeral] });
|
||||
}
|
||||
|
||||
const idToUse = (user?.id ?? id) as string;
|
||||
|
||||
const recordMessage = await getRecordMessageFromDiscordId(idToUse, 1, interaction.guild);
|
||||
|
||||
if (!recordMessage) return interaction.editReply('No records found on any linked accounts.');
|
||||
|
||||
interaction.editReply(recordMessage);
|
||||
}
|
||||
};
|
||||
+50
-50
@@ -1,51 +1,51 @@
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, PermissionFlagsBits, RateLimitError, SlashCommandBuilder } from 'discord.js';
|
||||
import { msToHuman } from '../utils';
|
||||
import { Database } from '../shared/Database';
|
||||
|
||||
export default {
|
||||
name: 'rename',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('rename')
|
||||
.setDescription('Rename the general channel.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('new-name')
|
||||
.setDescription('The new name of the general channel.')
|
||||
.setRequired(true)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
const guildSettings = await Database.getGuildSettings(interaction.guildId!);
|
||||
|
||||
if (!guildSettings || !guildSettings.general_chat_id) {
|
||||
return interaction.reply('No general chat id found.');
|
||||
}
|
||||
|
||||
const name = interaction.options.getString('new-name', true);
|
||||
|
||||
if (name.length > 100) {
|
||||
return interaction.reply('Name must be less than 100 characters in length.');
|
||||
}
|
||||
|
||||
const channel = await interaction.guild!.channels.fetch(guildSettings.general_chat_id)!;
|
||||
|
||||
if (!channel) {
|
||||
return interaction.reply('No general chat id found.');
|
||||
}
|
||||
|
||||
try {
|
||||
await channel.setName(name);
|
||||
|
||||
interaction.reply(`Renamed general to ${channel.name}`);
|
||||
} catch (e: any) {
|
||||
if (e instanceof RateLimitError) {
|
||||
return interaction.reply(`Name change limited. Try again in ${msToHuman(e.retryAfter)}`);
|
||||
}
|
||||
|
||||
console.error(e);
|
||||
return interaction.reply('An error has occurred.');
|
||||
}
|
||||
}
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, InteractionContextType, PermissionFlagsBits, RateLimitError, SlashCommandBuilder } from 'discord.js';
|
||||
import { msToHuman } from '../utils';
|
||||
import { Database } from '../shared/Database';
|
||||
|
||||
export default {
|
||||
name: 'rename',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('rename')
|
||||
.setDescription('Rename the general channel.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('new-name')
|
||||
.setDescription('The new name of the general channel.')
|
||||
.setRequired(true)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
const guildSettings = await Database.getGuildSettings(interaction.guildId!);
|
||||
|
||||
if (!guildSettings || !guildSettings.general_chat_id) {
|
||||
return interaction.reply('No general chat id found.');
|
||||
}
|
||||
|
||||
const name = interaction.options.getString('new-name', true);
|
||||
|
||||
if (name.length > 100) {
|
||||
return interaction.reply('Name must be less than 100 characters in length.');
|
||||
}
|
||||
|
||||
const channel = await interaction.guild!.channels.fetch(guildSettings.general_chat_id)!;
|
||||
|
||||
if (!channel) {
|
||||
return interaction.reply('No general chat id found.');
|
||||
}
|
||||
|
||||
try {
|
||||
await channel.setName(name);
|
||||
|
||||
interaction.reply(`Renamed general to ${channel.name}`);
|
||||
} catch (e: any) {
|
||||
if (e instanceof RateLimitError) {
|
||||
return interaction.reply(`Name change limited. Try again in ${msToHuman(e.retryAfter)}`);
|
||||
}
|
||||
|
||||
console.error(e);
|
||||
return interaction.reply('An error has occurred.');
|
||||
}
|
||||
}
|
||||
};
|
||||
+302
-302
@@ -1,303 +1,303 @@
|
||||
import { ApplicationIntegrationType, ChannelType, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
|
||||
export default {
|
||||
name: 'settings',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('settings')
|
||||
.setDescription('Change server settings.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('general-channel')
|
||||
.setDescription('Set the general channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('tickets-channel')
|
||||
.setDescription('Set the ticket logs channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('event-logs-channel')
|
||||
.setDescription('Set the event logs channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('discord-logs-channel')
|
||||
.setDescription('Set the discord logs channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('audit-logs-channel')
|
||||
.setDescription('Set the audit logs channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('voice-logs-channel')
|
||||
.setDescription('Set the voice logs channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('new-member-channel')
|
||||
.setDescription('Set the new member logs channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('moderator-channel')
|
||||
.setDescription('Set the site moderator channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addRoleOption(option =>
|
||||
option
|
||||
.setName('admin-role')
|
||||
.setDescription('Set the admin role.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addRoleOption(option =>
|
||||
option
|
||||
.setName('private-helper-role')
|
||||
.setDescription('Set the private helper role.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addRoleOption(option =>
|
||||
option
|
||||
.setName('devwatch-role')
|
||||
.setDescription('Set the DevWatch role.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('add-staff-category')
|
||||
.setDescription('Add a category to staff categories.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('remove-staff-category')
|
||||
.setDescription('Remove a category from staff categories.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('add-safe-channel')
|
||||
.setDescription('Add a SFW channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('remove-safe-channel')
|
||||
.setDescription('Remove a SFW channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('add-link-skip-channel')
|
||||
.setDescription('Add a link skip channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('remove-link-skip-channel')
|
||||
.setDescription('Remove a link skip channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('github-release-channel')
|
||||
.setDescription('Set the github release channel.')
|
||||
.setRequired(false)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
||||
|
||||
let response = '';
|
||||
|
||||
const settings = await Database.getGuildSettings(interaction.guildId!);
|
||||
|
||||
if (!settings) {
|
||||
await Database.putGuild(interaction.guildId!);
|
||||
}
|
||||
|
||||
const generalChannel = interaction.options.getChannel('general-channel');
|
||||
|
||||
if (generalChannel) {
|
||||
await Database.setGuildGeneralChatId(interaction.guildId!, generalChannel.id);
|
||||
|
||||
response += `General channel set to ${generalChannel}.\n`;
|
||||
}
|
||||
|
||||
const ticketsChannel = interaction.options.getChannel('tickets-channel');
|
||||
|
||||
if (ticketsChannel) {
|
||||
await Database.setGuildTicketsLogsChannelId(interaction.guildId!, ticketsChannel.id);
|
||||
|
||||
response += `Tickets logs channel set to ${ticketsChannel}.\n`;
|
||||
}
|
||||
|
||||
const eventLogsChannel = interaction.options.getChannel('event-logs-channel');
|
||||
|
||||
if (eventLogsChannel) {
|
||||
await Database.setGuildEventsLogsChannelId(interaction.guildId!, eventLogsChannel.id);
|
||||
|
||||
response += `Event logs channel set to ${eventLogsChannel}.\n`;
|
||||
}
|
||||
|
||||
const discordLogsChannel = interaction.options.getChannel('discord-logs-channel');
|
||||
|
||||
if (discordLogsChannel) {
|
||||
await Database.setGuildDiscordLogsChannelId(interaction.guildId!, discordLogsChannel.id);
|
||||
|
||||
response += `Discord logs channel set to ${discordLogsChannel}.\n`;
|
||||
}
|
||||
|
||||
const auditLogsChannel = interaction.options.getChannel('audit-logs-channel');
|
||||
|
||||
if (auditLogsChannel) {
|
||||
await Database.setGuildAuditLogsChannelId(interaction.guildId!, auditLogsChannel.id);
|
||||
|
||||
response += `Audit logs channel set to ${auditLogsChannel}.\n`;
|
||||
}
|
||||
|
||||
const voiceLogsChannel = interaction.options.getChannel('voice-logs-channel');
|
||||
|
||||
if (voiceLogsChannel) {
|
||||
await Database.setGuildVoiceLogsChannelId(interaction.guildId!, voiceLogsChannel.id);
|
||||
|
||||
response += `Voice logs channel set to ${voiceLogsChannel}.\n`;
|
||||
}
|
||||
|
||||
const newMemberLogsChannel = interaction.options.getChannel('new-member-channel');
|
||||
|
||||
if (newMemberLogsChannel) {
|
||||
await Database.setGuildNewMemberLogsChannel(interaction.guildId!, newMemberLogsChannel.id);
|
||||
|
||||
response += `New member logs channel set to ${newMemberLogsChannel}.\n`;
|
||||
}
|
||||
|
||||
const moderatorChannel = interaction.options.getChannel('moderator-channel');
|
||||
|
||||
if (moderatorChannel) {
|
||||
await Database.setGuildModeratorChannel(interaction.guildId!, moderatorChannel.id);
|
||||
|
||||
response += `Moderator channel set to ${moderatorChannel}.\n`;
|
||||
}
|
||||
|
||||
const adminRole = interaction.options.getRole('admin-role');
|
||||
|
||||
if (adminRole) {
|
||||
await Database.setGuildAdminRole(interaction.guildId!, adminRole.id);
|
||||
|
||||
response += `Admin role set to ${adminRole}.\n`;
|
||||
}
|
||||
|
||||
const privateHelperRole = interaction.options.getRole('private-helper-role');
|
||||
|
||||
if (privateHelperRole) {
|
||||
await Database.setGuildPrivateHelperRole(interaction.guildId!, privateHelperRole.id);
|
||||
|
||||
response += `Private helper role set to ${privateHelperRole}.\n`;
|
||||
}
|
||||
|
||||
const devWatchRole = interaction.options.getRole('devwatch-role');
|
||||
|
||||
if (devWatchRole) {
|
||||
await Database.setGuildDevWatchRole(interaction.guildId!, devWatchRole.id);
|
||||
|
||||
response += `DevWatch role set to ${devWatchRole}.\n`;
|
||||
}
|
||||
|
||||
const addCategory = interaction.options.getChannel('add-staff-category');
|
||||
if (addCategory) {
|
||||
if (addCategory.type == ChannelType.GuildCategory) {
|
||||
await Database.putGuildArraySetting('staff_categories', interaction.guildId!, addCategory.id);
|
||||
|
||||
response += `Added ${addCategory.toString()} as a staff category.\n`;
|
||||
} else {
|
||||
response += `Error adding staff category: ${addCategory.toString()} isn't a category.`;
|
||||
}
|
||||
}
|
||||
|
||||
const removeCategory = interaction.options.getChannel('remove-staff-category');
|
||||
if (removeCategory) {
|
||||
if (removeCategory.type == ChannelType.GuildCategory) {
|
||||
if (await Database.removeGuildArraySetting('staff_categories', interaction.guildId!, removeCategory.id)) {
|
||||
response += `Removed ${removeCategory.toString()} as a staff category\n`;
|
||||
} else {
|
||||
response += `Error removing staff category: ${removeCategory.toString()} isn't a staff category.`;
|
||||
}
|
||||
} else {
|
||||
response += `Error removing staff category: ${removeCategory.toString()} isn't a category.`;
|
||||
}
|
||||
}
|
||||
|
||||
const addSafeChannel = interaction.options.getChannel('add-safe-channel');
|
||||
if (addSafeChannel) {
|
||||
if (addSafeChannel.type == ChannelType.GuildText) {
|
||||
await Database.putGuildArraySetting('safe_channels', interaction.guildId!, addSafeChannel.id);
|
||||
|
||||
response += `Added ${addSafeChannel.toString()} as a SFW cannel.\n`;
|
||||
} else {
|
||||
response += `Error adding SFW channel: ${addSafeChannel.toString()} isn't a text channel.`;
|
||||
}
|
||||
}
|
||||
|
||||
const removeSafeChannel = interaction.options.getChannel('remove-safe-channel');
|
||||
if (removeSafeChannel) {
|
||||
if (removeSafeChannel.type == ChannelType.GuildText) {
|
||||
if (await Database.removeGuildArraySetting('safe_channels', interaction.guildId!, removeSafeChannel.id)) {
|
||||
response += `Removed ${removeSafeChannel.toString()} as a safe channel\n`;
|
||||
} else {
|
||||
response += `Error removing safe channel: ${removeSafeChannel.toString()} isn't a safe channel.`;
|
||||
}
|
||||
} else {
|
||||
response += `Error removing safe channel: ${removeSafeChannel.toString()} isn't a text channel.`;
|
||||
}
|
||||
}
|
||||
|
||||
const addLinkSkipChannel = interaction.options.getChannel('add-link-skip-channel');
|
||||
if (addLinkSkipChannel) {
|
||||
if (addLinkSkipChannel.type == ChannelType.GuildText) {
|
||||
await Database.putGuildArraySetting('link_skip_channels', interaction.guildId!, addLinkSkipChannel.id);
|
||||
|
||||
response += `Added ${addLinkSkipChannel.toString()} as a link skip channel.\n`;
|
||||
} else {
|
||||
response += `Error adding link skip channel: ${addLinkSkipChannel.toString()} isn't a text channel.`;
|
||||
}
|
||||
}
|
||||
|
||||
const removeLinkSkipChannel = interaction.options.getChannel('remove-link-skip-channel');
|
||||
if (removeLinkSkipChannel) {
|
||||
if (removeLinkSkipChannel.type == ChannelType.GuildText) {
|
||||
if (await Database.removeGuildArraySetting('link_skip_channels', interaction.guildId!, removeLinkSkipChannel.id)) {
|
||||
response += `Removed ${removeLinkSkipChannel.toString()} as a staff category\n`;
|
||||
} else {
|
||||
response += `Error removing link skip channel: ${removeLinkSkipChannel.toString()} isn't a link skip channel.`;
|
||||
}
|
||||
} else {
|
||||
response += `Error removing link skip channel: ${removeLinkSkipChannel.toString()} isn't a text channel.`;
|
||||
}
|
||||
}
|
||||
|
||||
const githubReleaseChannel = interaction.options.getChannel('github-release-channel');
|
||||
|
||||
if (githubReleaseChannel) {
|
||||
await Database.setGuildGithubReleaseChannel(interaction.guildId!, githubReleaseChannel.id);
|
||||
|
||||
response += `Github releases channel set to ${githubReleaseChannel}.\n`;
|
||||
}
|
||||
|
||||
if (response.length == 0) return interaction.editReply({ content: 'No settings provided.' });
|
||||
|
||||
interaction.editReply({ content: response });
|
||||
}
|
||||
import { ApplicationIntegrationType, ChannelType, ChatInputCommandInteraction, Client, InteractionContextType, MessageFlags, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { Database } from '../shared/Database';
|
||||
|
||||
export default {
|
||||
name: 'settings',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('settings')
|
||||
.setDescription('Change server settings.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageGuild)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('general-channel')
|
||||
.setDescription('Set the general channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('tickets-channel')
|
||||
.setDescription('Set the ticket logs channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('event-logs-channel')
|
||||
.setDescription('Set the event logs channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('discord-logs-channel')
|
||||
.setDescription('Set the discord logs channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('audit-logs-channel')
|
||||
.setDescription('Set the audit logs channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('voice-logs-channel')
|
||||
.setDescription('Set the voice logs channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('new-member-channel')
|
||||
.setDescription('Set the new member logs channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('moderator-channel')
|
||||
.setDescription('Set the site moderator channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addRoleOption(option =>
|
||||
option
|
||||
.setName('admin-role')
|
||||
.setDescription('Set the admin role.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addRoleOption(option =>
|
||||
option
|
||||
.setName('private-helper-role')
|
||||
.setDescription('Set the private helper role.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addRoleOption(option =>
|
||||
option
|
||||
.setName('devwatch-role')
|
||||
.setDescription('Set the DevWatch role.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('add-staff-category')
|
||||
.setDescription('Add a category to staff categories.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('remove-staff-category')
|
||||
.setDescription('Remove a category from staff categories.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('add-safe-channel')
|
||||
.setDescription('Add a SFW channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('remove-safe-channel')
|
||||
.setDescription('Remove a SFW channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('add-link-skip-channel')
|
||||
.setDescription('Add a link skip channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('remove-link-skip-channel')
|
||||
.setDescription('Remove a link skip channel.')
|
||||
.setRequired(false)
|
||||
)
|
||||
.addChannelOption(option =>
|
||||
option
|
||||
.setName('github-release-channel')
|
||||
.setDescription('Set the github release channel.')
|
||||
.setRequired(false)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
||||
|
||||
let response = '';
|
||||
|
||||
const settings = await Database.getGuildSettings(interaction.guildId!);
|
||||
|
||||
if (!settings) {
|
||||
await Database.putGuild(interaction.guildId!);
|
||||
}
|
||||
|
||||
const generalChannel = interaction.options.getChannel('general-channel');
|
||||
|
||||
if (generalChannel) {
|
||||
await Database.setGuildGeneralChatId(interaction.guildId!, generalChannel.id);
|
||||
|
||||
response += `General channel set to ${generalChannel}.\n`;
|
||||
}
|
||||
|
||||
const ticketsChannel = interaction.options.getChannel('tickets-channel');
|
||||
|
||||
if (ticketsChannel) {
|
||||
await Database.setGuildTicketsLogsChannelId(interaction.guildId!, ticketsChannel.id);
|
||||
|
||||
response += `Tickets logs channel set to ${ticketsChannel}.\n`;
|
||||
}
|
||||
|
||||
const eventLogsChannel = interaction.options.getChannel('event-logs-channel');
|
||||
|
||||
if (eventLogsChannel) {
|
||||
await Database.setGuildEventsLogsChannelId(interaction.guildId!, eventLogsChannel.id);
|
||||
|
||||
response += `Event logs channel set to ${eventLogsChannel}.\n`;
|
||||
}
|
||||
|
||||
const discordLogsChannel = interaction.options.getChannel('discord-logs-channel');
|
||||
|
||||
if (discordLogsChannel) {
|
||||
await Database.setGuildDiscordLogsChannelId(interaction.guildId!, discordLogsChannel.id);
|
||||
|
||||
response += `Discord logs channel set to ${discordLogsChannel}.\n`;
|
||||
}
|
||||
|
||||
const auditLogsChannel = interaction.options.getChannel('audit-logs-channel');
|
||||
|
||||
if (auditLogsChannel) {
|
||||
await Database.setGuildAuditLogsChannelId(interaction.guildId!, auditLogsChannel.id);
|
||||
|
||||
response += `Audit logs channel set to ${auditLogsChannel}.\n`;
|
||||
}
|
||||
|
||||
const voiceLogsChannel = interaction.options.getChannel('voice-logs-channel');
|
||||
|
||||
if (voiceLogsChannel) {
|
||||
await Database.setGuildVoiceLogsChannelId(interaction.guildId!, voiceLogsChannel.id);
|
||||
|
||||
response += `Voice logs channel set to ${voiceLogsChannel}.\n`;
|
||||
}
|
||||
|
||||
const newMemberLogsChannel = interaction.options.getChannel('new-member-channel');
|
||||
|
||||
if (newMemberLogsChannel) {
|
||||
await Database.setGuildNewMemberLogsChannel(interaction.guildId!, newMemberLogsChannel.id);
|
||||
|
||||
response += `New member logs channel set to ${newMemberLogsChannel}.\n`;
|
||||
}
|
||||
|
||||
const moderatorChannel = interaction.options.getChannel('moderator-channel');
|
||||
|
||||
if (moderatorChannel) {
|
||||
await Database.setGuildModeratorChannel(interaction.guildId!, moderatorChannel.id);
|
||||
|
||||
response += `Moderator channel set to ${moderatorChannel}.\n`;
|
||||
}
|
||||
|
||||
const adminRole = interaction.options.getRole('admin-role');
|
||||
|
||||
if (adminRole) {
|
||||
await Database.setGuildAdminRole(interaction.guildId!, adminRole.id);
|
||||
|
||||
response += `Admin role set to ${adminRole}.\n`;
|
||||
}
|
||||
|
||||
const privateHelperRole = interaction.options.getRole('private-helper-role');
|
||||
|
||||
if (privateHelperRole) {
|
||||
await Database.setGuildPrivateHelperRole(interaction.guildId!, privateHelperRole.id);
|
||||
|
||||
response += `Private helper role set to ${privateHelperRole}.\n`;
|
||||
}
|
||||
|
||||
const devWatchRole = interaction.options.getRole('devwatch-role');
|
||||
|
||||
if (devWatchRole) {
|
||||
await Database.setGuildDevWatchRole(interaction.guildId!, devWatchRole.id);
|
||||
|
||||
response += `DevWatch role set to ${devWatchRole}.\n`;
|
||||
}
|
||||
|
||||
const addCategory = interaction.options.getChannel('add-staff-category');
|
||||
if (addCategory) {
|
||||
if (addCategory.type == ChannelType.GuildCategory) {
|
||||
await Database.putGuildArraySetting('staff_categories', interaction.guildId!, addCategory.id);
|
||||
|
||||
response += `Added ${addCategory.toString()} as a staff category.\n`;
|
||||
} else {
|
||||
response += `Error adding staff category: ${addCategory.toString()} isn't a category.`;
|
||||
}
|
||||
}
|
||||
|
||||
const removeCategory = interaction.options.getChannel('remove-staff-category');
|
||||
if (removeCategory) {
|
||||
if (removeCategory.type == ChannelType.GuildCategory) {
|
||||
if (await Database.removeGuildArraySetting('staff_categories', interaction.guildId!, removeCategory.id)) {
|
||||
response += `Removed ${removeCategory.toString()} as a staff category\n`;
|
||||
} else {
|
||||
response += `Error removing staff category: ${removeCategory.toString()} isn't a staff category.`;
|
||||
}
|
||||
} else {
|
||||
response += `Error removing staff category: ${removeCategory.toString()} isn't a category.`;
|
||||
}
|
||||
}
|
||||
|
||||
const addSafeChannel = interaction.options.getChannel('add-safe-channel');
|
||||
if (addSafeChannel) {
|
||||
if (addSafeChannel.type == ChannelType.GuildText) {
|
||||
await Database.putGuildArraySetting('safe_channels', interaction.guildId!, addSafeChannel.id);
|
||||
|
||||
response += `Added ${addSafeChannel.toString()} as a SFW cannel.\n`;
|
||||
} else {
|
||||
response += `Error adding SFW channel: ${addSafeChannel.toString()} isn't a text channel.`;
|
||||
}
|
||||
}
|
||||
|
||||
const removeSafeChannel = interaction.options.getChannel('remove-safe-channel');
|
||||
if (removeSafeChannel) {
|
||||
if (removeSafeChannel.type == ChannelType.GuildText) {
|
||||
if (await Database.removeGuildArraySetting('safe_channels', interaction.guildId!, removeSafeChannel.id)) {
|
||||
response += `Removed ${removeSafeChannel.toString()} as a safe channel\n`;
|
||||
} else {
|
||||
response += `Error removing safe channel: ${removeSafeChannel.toString()} isn't a safe channel.`;
|
||||
}
|
||||
} else {
|
||||
response += `Error removing safe channel: ${removeSafeChannel.toString()} isn't a text channel.`;
|
||||
}
|
||||
}
|
||||
|
||||
const addLinkSkipChannel = interaction.options.getChannel('add-link-skip-channel');
|
||||
if (addLinkSkipChannel) {
|
||||
if (addLinkSkipChannel.type == ChannelType.GuildText) {
|
||||
await Database.putGuildArraySetting('link_skip_channels', interaction.guildId!, addLinkSkipChannel.id);
|
||||
|
||||
response += `Added ${addLinkSkipChannel.toString()} as a link skip channel.\n`;
|
||||
} else {
|
||||
response += `Error adding link skip channel: ${addLinkSkipChannel.toString()} isn't a text channel.`;
|
||||
}
|
||||
}
|
||||
|
||||
const removeLinkSkipChannel = interaction.options.getChannel('remove-link-skip-channel');
|
||||
if (removeLinkSkipChannel) {
|
||||
if (removeLinkSkipChannel.type == ChannelType.GuildText) {
|
||||
if (await Database.removeGuildArraySetting('link_skip_channels', interaction.guildId!, removeLinkSkipChannel.id)) {
|
||||
response += `Removed ${removeLinkSkipChannel.toString()} as a staff category\n`;
|
||||
} else {
|
||||
response += `Error removing link skip channel: ${removeLinkSkipChannel.toString()} isn't a link skip channel.`;
|
||||
}
|
||||
} else {
|
||||
response += `Error removing link skip channel: ${removeLinkSkipChannel.toString()} isn't a text channel.`;
|
||||
}
|
||||
}
|
||||
|
||||
const githubReleaseChannel = interaction.options.getChannel('github-release-channel');
|
||||
|
||||
if (githubReleaseChannel) {
|
||||
await Database.setGuildGithubReleaseChannel(interaction.guildId!, githubReleaseChannel.id);
|
||||
|
||||
response += `Github releases channel set to ${githubReleaseChannel}.\n`;
|
||||
}
|
||||
|
||||
if (response.length == 0) return interaction.editReply({ content: 'No settings provided.' });
|
||||
|
||||
interaction.editReply({ content: response });
|
||||
}
|
||||
};
|
||||
+80
-80
@@ -1,81 +1,81 @@
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, GuildMember, InteractionContextType, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { deferInteraction } from '../utils';
|
||||
|
||||
export default {
|
||||
name: 'softban',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('softban')
|
||||
.setDescription('Bans and immediately unbans a user to purge messages.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.KickMembers)
|
||||
.addUserOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user to softban.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('reason')
|
||||
.setDescription('The reason for the softban')
|
||||
.setRequired(false)
|
||||
.setMaxLength(400)
|
||||
)
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('days')
|
||||
.setDescription('How far back to delete messages (in days, default: 7 days).')
|
||||
.setRequired(false)
|
||||
.setMinValue(0)
|
||||
.setMaxValue(7)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await deferInteraction(interaction);
|
||||
|
||||
if (!interaction.guild) return interaction.editReply('This command must be used in a server');
|
||||
|
||||
if (!interaction.guild.members.me) return interaction.editReply('An error has occurred. Please try again later.');
|
||||
|
||||
const user = interaction.options.getUser('user', true);
|
||||
const reason = interaction.options.getString('reason') ?? '';
|
||||
const seconds = (interaction.options.getNumber('days') ?? 7) * 86400;
|
||||
|
||||
let banMember: GuildMember | null = null;
|
||||
|
||||
try {
|
||||
banMember = await interaction.guild.members.fetch(user.id);
|
||||
} catch (e) {
|
||||
// Member not in server.
|
||||
}
|
||||
|
||||
const member = await interaction.guild.members.fetch(interaction.user.id);
|
||||
|
||||
if (banMember && member.roles.highest.comparePositionTo(banMember.roles.highest) <= 0) {
|
||||
return await interaction.editReply('You do not have permission to softban this user.');
|
||||
}
|
||||
|
||||
if (banMember && !banMember.bannable) {
|
||||
return await interaction.editReply('I do not have permission to softban this user.');
|
||||
}
|
||||
|
||||
try {
|
||||
await interaction.guild.bans.create(user, {
|
||||
reason: (reason + ` Softban by ${interaction.user.username} (${interaction.user.id})`).trim(),
|
||||
deleteMessageSeconds: seconds
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return await interaction.editReply("Error softbanning user (couldn't ban).");
|
||||
}
|
||||
|
||||
try {
|
||||
await interaction.guild.bans.remove(user);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return await interaction.editReply("Error softbanning user (couldn't remove ban).");
|
||||
}
|
||||
|
||||
await interaction.editReply('Softban successful');
|
||||
}
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, GuildMember, InteractionContextType, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { deferInteraction } from '../utils';
|
||||
|
||||
export default {
|
||||
name: 'softban',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('softban')
|
||||
.setDescription('Bans and immediately unbans a user to purge messages.')
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.KickMembers)
|
||||
.addUserOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user to softban.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('reason')
|
||||
.setDescription('The reason for the softban')
|
||||
.setRequired(false)
|
||||
.setMaxLength(400)
|
||||
)
|
||||
.addNumberOption(option =>
|
||||
option
|
||||
.setName('days')
|
||||
.setDescription('How far back to delete messages (in days, default: 7 days).')
|
||||
.setRequired(false)
|
||||
.setMinValue(0)
|
||||
.setMaxValue(7)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
await deferInteraction(interaction);
|
||||
|
||||
if (!interaction.guild) return interaction.editReply('This command must be used in a server');
|
||||
|
||||
if (!interaction.guild.members.me) return interaction.editReply('An error has occurred. Please try again later.');
|
||||
|
||||
const user = interaction.options.getUser('user', true);
|
||||
const reason = interaction.options.getString('reason') ?? '';
|
||||
const seconds = (interaction.options.getNumber('days') ?? 7) * 86400;
|
||||
|
||||
let banMember: GuildMember | null = null;
|
||||
|
||||
try {
|
||||
banMember = await interaction.guild.members.fetch(user.id);
|
||||
} catch (e) {
|
||||
// Member not in server.
|
||||
}
|
||||
|
||||
const member = await interaction.guild.members.fetch(interaction.user.id);
|
||||
|
||||
if (banMember && member.roles.highest.comparePositionTo(banMember.roles.highest) <= 0) {
|
||||
return await interaction.editReply('You do not have permission to softban this user.');
|
||||
}
|
||||
|
||||
if (banMember && !banMember.bannable) {
|
||||
return await interaction.editReply('I do not have permission to softban this user.');
|
||||
}
|
||||
|
||||
try {
|
||||
await interaction.guild.bans.create(user, {
|
||||
reason: (reason + ` Softban by ${interaction.user.username} (${interaction.user.id})`).trim(),
|
||||
deleteMessageSeconds: seconds
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return await interaction.editReply("Error softbanning user (couldn't ban).");
|
||||
}
|
||||
|
||||
try {
|
||||
await interaction.guild.bans.remove(user);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return await interaction.editReply("Error softbanning user (couldn't remove ban).");
|
||||
}
|
||||
|
||||
await interaction.editReply('Softban successful');
|
||||
}
|
||||
};
|
||||
+29
-29
@@ -1,30 +1,30 @@
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, GuildBasedChannel, InteractionContextType, MessageMentions, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { channelIsInStaffCategory, handleWhoIsInteraction } from '../utils';
|
||||
|
||||
const mentionRegex = new RegExp(MessageMentions.UsersPattern);
|
||||
|
||||
export default {
|
||||
name: 'whois',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('whois')
|
||||
.setDescription("Find a user's e621 account from their discord account, or vice versa.")
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user mention, or ID, to find the e621 user of.')
|
||||
.setRequired(true)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
const input = interaction.options.getString('user', true);
|
||||
|
||||
const matches = mentionRegex.exec(input);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const valueToUse = matches ? matches.groups!.id : input;
|
||||
|
||||
handleWhoIsInteraction(interaction, valueToUse, !(await channelIsInStaffCategory(interaction.channel as GuildBasedChannel)));
|
||||
}
|
||||
import { ApplicationIntegrationType, ChatInputCommandInteraction, Client, GuildBasedChannel, InteractionContextType, MessageMentions, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js';
|
||||
import { channelIsInStaffCategory, handleWhoIsInteraction } from '../utils';
|
||||
|
||||
const mentionRegex = new RegExp(MessageMentions.UsersPattern);
|
||||
|
||||
export default {
|
||||
name: 'whois',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('whois')
|
||||
.setDescription("Find a user's e621 account from their discord account, or vice versa.")
|
||||
.setIntegrationTypes(ApplicationIntegrationType.GuildInstall)
|
||||
.setContexts(InteractionContextType.Guild)
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.addStringOption(option =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('The discord user mention, or ID, to find the e621 user of.')
|
||||
.setRequired(true)
|
||||
),
|
||||
handler: async function (client: Client, interaction: ChatInputCommandInteraction) {
|
||||
const input = interaction.options.getString('user', true);
|
||||
|
||||
const matches = mentionRegex.exec(input);
|
||||
mentionRegex.lastIndex = 0;
|
||||
|
||||
const valueToUse = matches ? matches.groups!.id : input;
|
||||
|
||||
handleWhoIsInteraction(interaction, valueToUse, !(await channelIsInStaffCategory(interaction.channel as GuildBasedChannel)));
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user