diff --git a/src/commands/link.ts b/src/commands/link.ts new file mode 100644 index 0000000..c2f9ec9 --- /dev/null +++ b/src/commands/link.ts @@ -0,0 +1,134 @@ +import { ApplicationIntegrationType, BitFieldResolvable, ChatInputCommandInteraction, Client, GuildBasedChannel, InteractionContextType, MessageFlags, MessageMentions, PermissionFlagsBits, SlashCommandBuilder } from 'discord.js'; +import { channelIsInStaffCategory, handleWhoIsInteraction, logCustomEvent } from '../utils'; +import { Database } from '../shared/Database'; +import { config } from '../config'; + +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 client.users.fetch(idToUse); + + if (!user) return interaction.editReply("Couldn't find user."); + + 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'); + } + } +}; \ No newline at end of file diff --git a/src/shared/Database.ts b/src/shared/Database.ts index d1989ca..c7e3e3a 100644 --- a/src/shared/Database.ts +++ b/src/shared/Database.ts @@ -136,10 +136,14 @@ export class Database { return ids.map(r => ({ userId: r.user_id.toString(), discordId: r.discord_id })); } - static async putUser(id: number, user: DiscordOAuth2.User) { + static async putUser(id: number, user: { id: string, username: string }) { await Database.db.run('INSERT INTO discord_names(user_id, discord_id, discord_username) VALUES (?, ?, ?)', id, user.id, user.username); } + static async removeUser(id: number, discordId: string) { + await Database.db.run('DELETE from tickets WHERE user_id = ? AND discord_id = ?', id, discordId); + } + // -- END WHOIS -- // -- START SETTINGS --