From e74a1bbecb35792be3254b2ecc3b4aaeea6e1b9a Mon Sep 17 00:00:00 2001 From: Yuzu Date: Tue, 7 Jun 2022 17:32:32 +0700 Subject: [PATCH] Localized settings and code clean up --- src/discord/Settings.ts | 453 -------------------- src/discord/Settings/Prefix.ts | 112 +++++ src/discord/Settings/ServiceAnnouncement.ts | 250 +++++++++++ src/discord/Settings/index.ts | 107 +++++ 4 files changed, 469 insertions(+), 453 deletions(-) delete mode 100644 src/discord/Settings.ts create mode 100644 src/discord/Settings/Prefix.ts create mode 100644 src/discord/Settings/ServiceAnnouncement.ts create mode 100644 src/discord/Settings/index.ts diff --git a/src/discord/Settings.ts b/src/discord/Settings.ts deleted file mode 100644 index 8d90b5a..0000000 --- a/src/discord/Settings.ts +++ /dev/null @@ -1,453 +0,0 @@ -import { - Message, - Interaction, - CommandInteraction, - Permissions, - ThreadChannel, - GuildChannel -} from 'discord.js'; - -import DiscordProvider from '../providers/Discord'; -import Prisma from '../providers/Prisma'; -import Cache from '../providers/Cache'; - -import DiscordModule, { HybridInteractionMessage } from '../utils/DiscordModule'; -import { - makeInfoEmbed, - makeErrorEmbed, - makeSuccessEmbed, - makeProcessingEmbed, - sendHybridInteractionMessageResponse -} from '../utils/DiscordMessage'; - -const EMBEDS = { - SETTINGS_INFO: (data: Message | Interaction) => { - return makeInfoEmbed({ - title: 'Settings', - description: `Change how ${DiscordProvider.client.user?.username} behave on **${data.guild?.name}**`, - fields: [ - { - name: 'Available arguments', - value: '``setPrefix`` ``setEnableServiceAnnouncement`` ``setServiceAnnouncementChannel``' - } - ], - user: data instanceof Interaction ? data.user : data.author - }); - }, - PROCESSING: (data: HybridInteractionMessage) => { - return makeProcessingEmbed({ - icon: data.isMessage() ? undefined : '⌛', - title: `Performing actions`, - user: data.getUser() - }); - }, - NO_PERMISSION: (data: Message | Interaction) => { - return makeErrorEmbed({ - title: 'You need ``ADMINISTRATOR`` permission on this guild!', - user: data instanceof Interaction ? data.user : data.author - }); - }, - NO_PREFIX_PROVIDED: (data: Message | Interaction) => { - return makeErrorEmbed({ - title: 'No prefix provided', - user: data instanceof Interaction ? data.user : data.author - }); - }, - SERVICE_ANNOUNCEMENT_INVALID_STATUS: (data: Message | Interaction) => { - return makeErrorEmbed({ - title: 'Invalid status, Use ``true`` or ``false``', - user: data instanceof Interaction ? data.user : data.author - }); - }, - NO_SERVICE_ANNOUNCEMENT_STATUS_PROVIDED: async (data: Message | Interaction) => { - let GuildCache = await Cache.getCachedGuild(data.guild!.id); - - // TODO: Better error handling - if (typeof GuildCache === 'undefined') throw new Error('Guild not found'); - - return makeInfoEmbed({ - title: 'Service Announcement', - description: `Service Announcement is ${ - GuildCache.ServiceAnnouncement_Enabled ? '**enabled**' : '**disabled**' - } on this server`, - user: data instanceof Interaction ? data.user : data.author - }); - }, - PREFIX_TOO_LONG: (data: Message | Interaction) => { - return makeErrorEmbed({ - title: 'Prefix too long', - description: `I bet you can't even remember that`, - user: data instanceof Interaction ? data.user : data.author - }); - }, - PREFIX_IS_MENTION: (data: Message | Interaction) => { - return makeErrorEmbed({ - title: 'Prefix cannot be mention of me', - description: `You can already call me by mentioning me. I got that covered, don't worry`, - user: data instanceof Interaction ? data.user : data.author - }); - }, - PREFIX_UPDATED: (data: Message | Interaction, newPrefix: string) => { - return makeSuccessEmbed({ - title: 'Prefix Updated', - description: `From now onwards, I shall be called by using \`\`${newPrefix}\`\``, - user: data instanceof Interaction ? data.user : data.author - }); - }, - SERVICE_ANNOUNCEMENT_STATUS_UPDATED: (data: Message | Interaction, newStatus: boolean) => { - return makeSuccessEmbed({ - title: `Service Announcement is now ${newStatus ? 'enabled' : 'disabled'}`, - user: data instanceof Interaction ? data.user : data.author - }); - }, - SERVICE_ANNOUNCEMENT_STATUS_ALREADY_SET: (data: Message | Interaction, status: boolean) => { - return makeInfoEmbed({ - title: `Service Announcement is already ${status ? 'enabled' : 'disabled'}`, - user: data instanceof Interaction ? data.user : data.author - }); - }, - SERVICE_ANNOUNCEMENT_NO_PARAMETER: (data: Message | Interaction) => { - return makeErrorEmbed({ - title: 'Missing parameter', - description: `You must define service announcement channel to enable this feature`, - user: data instanceof Interaction ? data.user : data.author - }); - }, - NO_CHANNEL_MENTIONED: (data: Message | Interaction) => { - return makeErrorEmbed({ - title: 'No channel mentioned', - user: data instanceof Interaction ? data.user : data.author - }); - }, - NO_CHANNEL_FOUND: (data: Message | Interaction) => { - return makeErrorEmbed({ - title: 'Cannot find that channel', - user: data instanceof Interaction ? data.user : data.author - }); - }, - INVALID_CHANNEL: (data: Message | Interaction, channel: GuildChannel) => { - return makeErrorEmbed({ - title: 'Invalid channel type, only TextChannel is supported', - description: '``' + channel.name + '``' + ' is not a text channel', - user: data instanceof Interaction ? data.user : data.author - }); - }, - INVALID_CHANNEL_THREAD: ( - data: Message | Interaction, - channel: GuildChannel | ThreadChannel - ) => { - return makeErrorEmbed({ - title: 'Thread channel is not supported', - description: - '``' + - channel.name + - '``' + - ' is a thread channel. Please use a regular text channel', - user: data instanceof Interaction ? data.user : data.author - }); - }, - BOT_NO_PERMISSION: (data: Message | Interaction, channel: GuildChannel) => { - return makeErrorEmbed({ - title: `I don't have permission`, - description: 'I cannot access/send message in ' + '``' + channel.name + '``', - user: data instanceof Interaction ? data.user : data.author - }); - }, - SERVICE_ANNOUNCEMENT_CONFIGURED_CHANNEL: ( - data: Message | Interaction, - channel: GuildChannel - ) => { - return makeSuccessEmbed({ - title: 'Configured Service Announcement Channel', - user: data instanceof Interaction ? data.user : data.author - }); - } -}; - -export default class Settings extends DiscordModule { - public id = 'Discord_Settings'; - public commands = ['settings']; - public commandInteractionName = 'settings'; - - async GuildOnModuleCommand(args: any, message: Message) { - await this.run(new HybridInteractionMessage(message), args); - } - - async GuildModuleCommandInteractionCreate(interaction: CommandInteraction) { - await this.run(new HybridInteractionMessage(interaction), interaction.options); - } - - async run(data: HybridInteractionMessage, args: any) { - const Guild = await Prisma.client.guild.findFirst({ where: { id: data.getGuild()!.id } }); - if (!Guild) return; - - const funct = { - setPrefix: async (data: HybridInteractionMessage) => { - let member = data.getMember(); - if (!member) return; - - if (!member.permissions.has([Permissions.FLAGS.ADMINISTRATOR])) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.NO_PERMISSION(data.getRaw())] - }); - - let newPrefix: string | null | undefined; - if (data.isMessage()) { - let _name: string; - if (typeof args[1] === 'undefined') - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.NO_PREFIX_PROVIDED(data.getRaw())] - }); - - let __name = args; - __name.shift(); - _name = __name.join(' '); - newPrefix = _name; - } else if (data.isSlashCommand()) - newPrefix = data.getSlashCommand().options.getString('prefix'); - - if (!newPrefix) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.NO_PREFIX_PROVIDED(data.getRaw())] - }); - - if (newPrefix.length > 200) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.PREFIX_TOO_LONG(data.getRaw())] - }); - - if (newPrefix.startsWith(`<@!${DiscordProvider.client.user?.id}>`)) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.PREFIX_IS_MENTION(data.getRaw())] - }); - - let placeholder: HybridInteractionMessage | undefined; - - let _placeholder = await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.PROCESSING(data)] - }); - if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder); - - await Prisma.client.guild.update({ - where: { id: data.getGuild()!.id }, - data: { prefix: newPrefix } - }); - Cache.updateGuildCache(data.getGuild()!.id); - - if (data && data.isMessage() && placeholder && placeholder.isMessage()) - return placeholder - .getMessage() - .edit({ embeds: [EMBEDS.PREFIX_UPDATED(data.getRaw(), newPrefix)] }); - else if (data.isSlashCommand()) - return await sendHybridInteractionMessageResponse( - data, - { embeds: [EMBEDS.PREFIX_UPDATED(data.getRaw(), newPrefix)] }, - true - ); - }, - setEnableServiceAnnouncement: async (data: HybridInteractionMessage) => { - let member = data.getMember(); - if (!member) return; - - if (!member.permissions.has([Permissions.FLAGS.ADMINISTRATOR])) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.NO_PERMISSION(data.getRaw())] - }); - - let newStatus: string | null | undefined; - if (data.isMessage()) { - let _name: string; - if (typeof args[1] === 'undefined') - return await sendHybridInteractionMessageResponse(data, { - embeds: [ - await EMBEDS.NO_SERVICE_ANNOUNCEMENT_STATUS_PROVIDED(data.getRaw()) - ] - }); - - let __name = args; - __name.shift(); - _name = __name.join(' '); - newStatus = _name; - } else if (data.isSlashCommand()) - newStatus = data.getSlashCommand().options.getString('status')!; - - if (!newStatus) - return await sendHybridInteractionMessageResponse(data, { - embeds: [ - await EMBEDS.NO_SERVICE_ANNOUNCEMENT_STATUS_PROVIDED(data.getRaw()) - ] - }); - - if ( - !['true', 'false', 'yes', 'no', 'y', 'n', 'enable', 'disable'].includes( - newStatus.toLowerCase() - ) - ) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_INVALID_STATUS(data.getRaw())] - }); - - await Cache.updateGuildCache(data.getGuild()!.id); - let GuildCache = await Cache.getCachedGuild(data.getGuild()!.id); - - const newStatusBool = ['true', 'yes', 'y', 'enable'].includes( - newStatus.toLowerCase() - ) - ? true - : false; - - if (GuildCache?.ServiceAnnouncement_Enabled === newStatusBool) - return await sendHybridInteractionMessageResponse(data, { - embeds: [ - EMBEDS.SERVICE_ANNOUNCEMENT_STATUS_ALREADY_SET( - data.getRaw(), - newStatusBool - ) - ] - }); - - if (GuildCache?.ServiceAnnouncement_Channel === null) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_NO_PARAMETER(data.getRaw())] - }); - - let placeholder = await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.PROCESSING(data)] - }); - - await Prisma.client.guild.update({ - where: { id: data.getGuild()!.id }, - data: { - ServiceAnnouncement_Enabled: newStatusBool - } - }); - Cache.updateGuildCache(data.getGuild()!.id); - - if (data.isMessage()) - return await (placeholder as Message).edit({ - embeds: [ - EMBEDS.SERVICE_ANNOUNCEMENT_STATUS_UPDATED(data.getRaw(), newStatusBool) - ] - }); - else if (data.isSlashCommand()) - return await sendHybridInteractionMessageResponse( - data, - { - embeds: [ - EMBEDS.SERVICE_ANNOUNCEMENT_STATUS_UPDATED( - data.getRaw(), - newStatusBool - ) - ] - }, - true - ); - }, - setServiceAnnouncementChannel: async (data: HybridInteractionMessage) => { - let member = data.getMember(); - if (!member) return; - - if (!member.permissions.has([Permissions.FLAGS.ADMINISTRATOR])) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.NO_PERMISSION(data.getRaw())] - }); - - let channel; - if (data.isMessage()) { - if (typeof args[1] === 'undefined') - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.NO_CHANNEL_MENTIONED(data.getRaw())] - }); - channel = data.getMessage().mentions.channels.first(); - } else if (data.isSlashCommand()) - channel = data.getSlashCommand().options.getChannel('channel'); - - if (!channel) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.NO_CHANNEL_FOUND(data.getRaw())] - }); - - let TargetChannel = data.getGuild()!.channels.cache.get(channel.id); - if (typeof TargetChannel === 'undefined') return; - - if (TargetChannel instanceof ThreadChannel || TargetChannel.isThread()) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.INVALID_CHANNEL_THREAD(data.getRaw(), TargetChannel)] - }); - - if (!TargetChannel.isText()) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.INVALID_CHANNEL(data.getRaw(), TargetChannel)] - }); - - if ( - !data - .getGuild()! - .me?.permissionsIn(TargetChannel) - .has([Permissions.FLAGS.SEND_MESSAGES, Permissions.FLAGS.VIEW_CHANNEL]) - ) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.BOT_NO_PERMISSION(data.getRaw(), TargetChannel)] - }); - - let placeholder = await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.PROCESSING(data)] - }); - - await Prisma.client.guild.update({ - where: { id: data.getGuild()!.id }, - data: { ServiceAnnouncement_Channel: channel.id } - }); - - if (data.isMessage()) - return await (placeholder as Message).edit({ - embeds: [ - EMBEDS.SERVICE_ANNOUNCEMENT_CONFIGURED_CHANNEL( - data.getRaw(), - TargetChannel - ) - ] - }); - else if (data.isSlashCommand()) - return await sendHybridInteractionMessageResponse( - data, - { - embeds: [ - EMBEDS.SERVICE_ANNOUNCEMENT_CONFIGURED_CHANNEL( - data.getRaw(), - TargetChannel - ) - ] - }, - true - ); - } - }; - - let query; - - if (data.isMessage()) { - if (args.length === 0) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.SETTINGS_INFO(data.getRaw())] - }); - - query = args[0].toLowerCase(); - } else if (data.isSlashCommand()) { - query = args.getSubcommand(); - } - - switch (query) { - case 'info': - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.SETTINGS_INFO(data.getRaw())] - }); - case 'setprefix': - return await funct.setPrefix(data); - case 'setenableserviceannouncement': - return await funct.setEnableServiceAnnouncement(data); - case 'setserviceannouncementchannel': - return await funct.setServiceAnnouncementChannel(data); - } - } -} diff --git a/src/discord/Settings/Prefix.ts b/src/discord/Settings/Prefix.ts new file mode 100644 index 0000000..4387064 --- /dev/null +++ b/src/discord/Settings/Prefix.ts @@ -0,0 +1,112 @@ +import { Permissions, Guild } from 'discord.js'; +import { I18n } from 'i18n'; + +import DiscordProvider from '../../providers/Discord'; +import Prisma from '../../providers/Prisma'; +import Cache from '../../providers/Cache'; + +import { HybridInteractionMessage } from '../../utils/DiscordModule'; +import { + makeInfoEmbed, + makeErrorEmbed, + makeSuccessEmbed, + sendHybridInteractionMessageResponse +} from '../../utils/DiscordMessage'; + +import { COMMON_EMBEDS } from '.'; + +const EMBEDS = { + PREFIX_INFO: (data: HybridInteractionMessage, locale: I18n, currentPrefix: string) => { + return makeInfoEmbed({ + title: locale.__('settings_prefix.info', currentPrefix), + description: locale.__('settings_prefix.info_description'), + user: data.getUser() + }); + }, + PREFIX_TOO_LONG: (data: HybridInteractionMessage, locale: I18n) => { + return makeErrorEmbed({ + title: locale.__('settings_prefix.prefix_too_long'), + description: locale.__('settings_prefix.prefix_too_long_description'), + user: data.getUser() + }); + }, + PREFIX_IS_MENTION: (data: HybridInteractionMessage, locale: I18n) => { + return makeErrorEmbed({ + title: locale.__('settings_prefix.prefix_is_mention'), + description: locale.__('settings_prefix.prefix_is_mention_description'), + user: data.getUser() + }); + }, + PREFIX_UPDATED: (data: HybridInteractionMessage, locale: I18n, newPrefix: string) => { + return makeSuccessEmbed({ + title: locale.__('settings_prefix.prefix_updated'), + description: locale.__('settings_prefix.prefix_updated_description', newPrefix), + user: data.getUser() + }); + } +}; + +export default async (data: HybridInteractionMessage, args: any, guild: Guild, locale: I18n) => { + let member = data.getMember(); + if (!member) return; + + const GuildCache = await Cache.getCachedGuild(guild.id); + if (!GuildCache) return; + const prefix = GuildCache.prefix; + + if (!member.permissions.has([Permissions.FLAGS.ADMINISTRATOR])) + return await sendHybridInteractionMessageResponse(data, { + embeds: [COMMON_EMBEDS.NO_PERMISSION(data, locale)] + }); + + let newPrefix: string | null | undefined; + if (data.isMessage()) { + let _name: string; + if (typeof args[1] === 'undefined') + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.PREFIX_INFO(data, locale, prefix)] + }); + + let __name = args; + __name.shift(); + _name = __name.join(' '); + newPrefix = _name; + } else if (data.isSlashCommand()) newPrefix = data.getSlashCommand().options.getString('prefix'); + + if (!newPrefix) + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.PREFIX_INFO(data, locale, prefix)] + }); + + if (newPrefix.length > 200) + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.PREFIX_TOO_LONG(data, locale)] + }); + + if (newPrefix.startsWith(`<@!${DiscordProvider.client.user?.id}>`) || newPrefix.startsWith(`<@${DiscordProvider.client.user?.id}>`)) + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.PREFIX_IS_MENTION(data, locale)] + }); + + let placeholder: HybridInteractionMessage | undefined; + + let _placeholder = await sendHybridInteractionMessageResponse(data, { + embeds: [COMMON_EMBEDS.PROCESSING(data, locale)] + }); + if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder); + + await Prisma.client.guild.update({ + where: { id: guild.id }, + data: { prefix: newPrefix } + }); + Cache.updateGuildCache(guild.id); + + if (data && data.isMessage() && placeholder && placeholder.isMessage()) + return placeholder.getMessage().edit({ embeds: [EMBEDS.PREFIX_UPDATED(data, locale, newPrefix)] }); + else if (data.isSlashCommand()) + return await sendHybridInteractionMessageResponse( + data, + { embeds: [EMBEDS.PREFIX_UPDATED(data, locale, newPrefix)] }, + true + ); +}; diff --git a/src/discord/Settings/ServiceAnnouncement.ts b/src/discord/Settings/ServiceAnnouncement.ts new file mode 100644 index 0000000..21d4a0c --- /dev/null +++ b/src/discord/Settings/ServiceAnnouncement.ts @@ -0,0 +1,250 @@ +import { Permissions, Guild, GuildChannel, ThreadChannel, Message } from 'discord.js'; +import { I18n } from 'i18n'; + +import DiscordProvider from '../../providers/Discord'; +import Prisma from '../../providers/Prisma'; +import Cache from '../../providers/Cache'; + +import { HybridInteractionMessage } from '../../utils/DiscordModule'; +import { + makeInfoEmbed, + makeErrorEmbed, + makeSuccessEmbed, + sendHybridInteractionMessageResponse +} from '../../utils/DiscordMessage'; + +import { COMMON_EMBEDS } from '.'; + +const EMBEDS = { + SERVICE_ANNOUNCEMENT_INVALID_STATUS: (data: HybridInteractionMessage, locale: I18n) => { + return makeErrorEmbed({ + title: 'Invalid status, Use ``true`` or ``false``', + user: data.getUser() + }); + }, + NO_SERVICE_ANNOUNCEMENT_STATUS_PROVIDED: async ( + data: HybridInteractionMessage, + locale: I18n, + isServiceAnnouncementEnabled: boolean + ) => { + return makeInfoEmbed({ + title: 'Service Announcement', + description: `Service Announcement is ${ + isServiceAnnouncementEnabled ? '**enabled**' : '**disabled**' + } on this server`, + user: data.getUser() + }); + }, + SERVICE_ANNOUNCEMENT_STATUS_UPDATED: (data: HybridInteractionMessage, locale: I18n, newStatus: boolean) => { + return makeSuccessEmbed({ + title: `Service Announcement is now ${newStatus ? 'enabled' : 'disabled'}`, + user: data.getUser() + }); + }, + SERVICE_ANNOUNCEMENT_STATUS_ALREADY_SET: (data: HybridInteractionMessage, locale: I18n, status: boolean) => { + return makeInfoEmbed({ + title: `Service Announcement is already ${status ? 'enabled' : 'disabled'}`, + user: data.getUser() + }); + }, + SERVICE_ANNOUNCEMENT_NO_PARAMETER: (data: HybridInteractionMessage, locale: I18n) => { + return makeErrorEmbed({ + title: 'Missing parameter', + description: `You must define service announcement channel to enable this feature`, + user: data.getUser() + }); + }, + NO_CHANNEL_MENTIONED: (data: HybridInteractionMessage, locale: I18n) => { + return makeErrorEmbed({ + title: 'No channel mentioned', + user: data.getUser() + }); + }, + NO_CHANNEL_FOUND: (data: HybridInteractionMessage, locale: I18n) => { + return makeErrorEmbed({ + title: 'Cannot find that channel', + user: data.getUser() + }); + }, + INVALID_CHANNEL: (data: HybridInteractionMessage, locale: I18n, channel: GuildChannel) => { + return makeErrorEmbed({ + title: 'Invalid channel type, only TextChannel is supported', + description: '``' + channel.name + '``' + ' is not a text channel', + user: data.getUser() + }); + }, + INVALID_CHANNEL_THREAD: (data: HybridInteractionMessage, locale: I18n, channel: GuildChannel | ThreadChannel) => { + return makeErrorEmbed({ + title: 'Thread channel is not supported', + description: '``' + channel.name + '``' + ' is a thread channel. Please use a regular text channel', + user: data.getUser() + }); + }, + BOT_NO_PERMISSION: (data: HybridInteractionMessage, locale: I18n, channel: GuildChannel) => { + return makeErrorEmbed({ + title: `I don't have permission`, + description: 'I cannot access/send message in ' + '``' + channel.name + '``', + user: data.getUser() + }); + }, + SERVICE_ANNOUNCEMENT_CONFIGURED_CHANNEL: (data: HybridInteractionMessage, locale: I18n, channel: GuildChannel) => { + return makeSuccessEmbed({ + title: 'Configured Service Announcement Channel', + user: data.getUser() + }); + } +}; + +export const setEnableServiceAnnouncement = async ( + data: HybridInteractionMessage, + args: any, + guild: Guild, + locale: I18n +) => { + let member = data.getMember(); + if (!member) return; + + if (!member.permissions.has([Permissions.FLAGS.ADMINISTRATOR])) + return await sendHybridInteractionMessageResponse(data, { + embeds: [COMMON_EMBEDS.NO_PERMISSION(data, locale)] + }); + + let GuildCache = await Cache.getCachedGuild(guild.id); + if(!GuildCache) return; + + let newStatus: string | null | undefined; + if (data.isMessage()) { + let _name: string; + if (typeof args[1] === 'undefined') + return await sendHybridInteractionMessageResponse(data, { + embeds: [await EMBEDS.NO_SERVICE_ANNOUNCEMENT_STATUS_PROVIDED(data, locale, GuildCache.ServiceAnnouncement_Enabled)] + }); + + let __name = args; + __name.shift(); + _name = __name.join(' '); + newStatus = _name; + } else if (data.isSlashCommand()) newStatus = data.getSlashCommand().options.getString('status')!; + + if (!newStatus) + return await sendHybridInteractionMessageResponse(data, { + embeds: [await EMBEDS.NO_SERVICE_ANNOUNCEMENT_STATUS_PROVIDED(data, locale, GuildCache.ServiceAnnouncement_Enabled)] + }); + + if (!['true', 'false', 'yes', 'no', 'y', 'n', 'enable', 'disable'].includes(newStatus.toLowerCase())) + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_INVALID_STATUS(data, locale)] + }); + + const newStatusBool = ['true', 'yes', 'y', 'enable'].includes(newStatus.toLowerCase()) ? true : false; + + if (GuildCache?.ServiceAnnouncement_Enabled === newStatusBool) + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_STATUS_ALREADY_SET(data, locale, newStatusBool)] + }); + + if (GuildCache?.ServiceAnnouncement_Channel === null) + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_NO_PARAMETER(data, locale)] + }); + + let placeholder = await sendHybridInteractionMessageResponse(data, { + embeds: [COMMON_EMBEDS.PROCESSING(data, locale)] + }); + + await Prisma.client.guild.update({ + where: { id: guild.id }, + data: { + ServiceAnnouncement_Enabled: newStatusBool + } + }); + + await Cache.updateGuildCache(guild.id); + + if (data.isMessage()) + return await (placeholder as Message).edit({ + embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_STATUS_UPDATED(data, locale, newStatusBool)] + }); + else if (data.isSlashCommand()) + return await sendHybridInteractionMessageResponse( + data, + { + embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_STATUS_UPDATED(data, locale, newStatusBool)] + }, + true + ); +}; + +export const setServiceAnnouncementChannel = async ( + data: HybridInteractionMessage, + args: any, + guild: Guild, + locale: I18n +) => { + let member = data.getMember(); + if (!member) return; + + if (!member.permissions.has([Permissions.FLAGS.ADMINISTRATOR])) + return await sendHybridInteractionMessageResponse(data, { + embeds: [COMMON_EMBEDS.NO_PERMISSION(data, locale)] + }); + + let channel; + if (data.isMessage()) { + if (typeof args[1] === 'undefined') + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.NO_CHANNEL_MENTIONED(data, locale)] + }); + channel = data.getMessage().mentions.channels.first(); + } else if (data.isSlashCommand()) channel = data.getSlashCommand().options.getChannel('channel'); + + if (!channel) + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.NO_CHANNEL_FOUND(data, locale)] + }); + + let TargetChannel = guild.channels.cache.get(channel.id); + if (typeof TargetChannel === 'undefined') return; + + if (TargetChannel instanceof ThreadChannel || TargetChannel.isThread()) + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.INVALID_CHANNEL_THREAD(data, locale, TargetChannel)] + }); + + if (!TargetChannel.isText()) + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.INVALID_CHANNEL(data, locale, TargetChannel)] + }); + + if ( + !data + .getGuild()! + .me?.permissionsIn(TargetChannel) + .has([Permissions.FLAGS.SEND_MESSAGES, Permissions.FLAGS.VIEW_CHANNEL]) + ) + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.BOT_NO_PERMISSION(data, locale, TargetChannel)] + }); + + let placeholder = await sendHybridInteractionMessageResponse(data, { + embeds: [COMMON_EMBEDS.PROCESSING(data, locale)] + }); + + await Prisma.client.guild.update({ + where: { id: guild.id }, + data: { ServiceAnnouncement_Channel: channel.id } + }); + + if (data.isMessage()) + return await (placeholder as Message).edit({ + embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_CONFIGURED_CHANNEL(data, locale, TargetChannel)] + }); + else if (data.isSlashCommand()) + return await sendHybridInteractionMessageResponse( + data, + { + embeds: [EMBEDS.SERVICE_ANNOUNCEMENT_CONFIGURED_CHANNEL(data, locale, TargetChannel)] + }, + true + ); +}; diff --git a/src/discord/Settings/index.ts b/src/discord/Settings/index.ts new file mode 100644 index 0000000..754d340 --- /dev/null +++ b/src/discord/Settings/index.ts @@ -0,0 +1,107 @@ +import { + Message, + Interaction, + CommandInteraction, + Permissions, + ThreadChannel, + GuildChannel, + Guild +} from 'discord.js'; +import { I18n } from 'i18n'; + +import DiscordProvider from '../../providers/Discord'; +import Prisma from '../../providers/Prisma'; +import Cache from '../../providers/Cache'; +import Locale from '../../services/Locale'; + +import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule'; +import { + makeInfoEmbed, + makeErrorEmbed, + makeSuccessEmbed, + makeProcessingEmbed, + sendHybridInteractionMessageResponse +} from '../../utils/DiscordMessage'; + +import * as PrefixModule from './Prefix'; +import * as ServiceAnnouncementModule from './ServiceAnnouncement'; + +export const COMMON_EMBEDS = { + NO_PERMISSION: (data: HybridInteractionMessage, locale: I18n) => { + return makeErrorEmbed({ + title: locale.__('common.no_permissions'), + description: locale.__('common.no_permissions_description','ADMINISTRATOR'), + user: data.getUser() + }); + }, + PROCESSING: (data: HybridInteractionMessage, locale: I18n) => { + return makeProcessingEmbed({ + icon: data.isMessage() ? undefined : '⌛', + title: locale.__('common.processing'), + user: data.getUser() + }); + } +} + +const EMBEDS = { + SETTINGS_INFO: (data: HybridInteractionMessage, locale: I18n, guild: Guild) => { + return makeInfoEmbed({ + title: locale.__('settings.title'), + description: locale.__('settings.description', DiscordProvider.client.user!.username, guild.name), + fields: [ + { + name: locale.__('common.available_args'), + value: locale.__('settings.valid_args'), + } + ], + user: data.getUser() + }); + } +}; + +export default class Settings extends DiscordModule { + public id = 'Discord_Settings'; + public commands = ['settings']; + public commandInteractionName = 'settings'; + + async GuildOnModuleCommand(args: any, message: Message) { + await this.run(new HybridInteractionMessage(message), args); + } + + async GuildModuleCommandInteractionCreate(interaction: CommandInteraction) { + await this.run(new HybridInteractionMessage(interaction), interaction.options); + } + + async run(data: HybridInteractionMessage, args: any) { + const guild = data.getGuild(); + if (!guild) return; + + const locale = await Locale.getGuildLocale(guild.id); + + let query; + + if (data.isMessage()) { + if (args.length === 0) + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.SETTINGS_INFO(data, locale, guild)] + }); + + query = args[0].toLowerCase(); + } else if (data.isSlashCommand()) { + query = args.getSubcommand(); + } + + switch (query) { + case 'info': + return await sendHybridInteractionMessageResponse(data, { + embeds: [EMBEDS.SETTINGS_INFO(data, locale, guild)] + }); + case 'prefix': + return await PrefixModule.default(data, args, guild, locale); + case 'enableserviceannouncement': + return await ServiceAnnouncementModule.setEnableServiceAnnouncement(data, args, guild, locale); + case 'serviceannouncementchannel': + return await ServiceAnnouncementModule.setServiceAnnouncementChannel(data, args, guild, locale); + } + } +}