/ src / modules / commands / deleteActivityRole.ts
deleteActivityRole.ts
  1  import { DBActivityRole, getLang, prepare } from '../db';
  2  import { __h_dc, Locale, log, __ } from '../messages';
  3  import config from '../config';
  4  import { Command } from '../commandHandler';
  5  
  6  import {
  7    ActionRowBuilder,
  8    ButtonBuilder,
  9    ButtonInteraction,
 10    ButtonStyle,
 11    ChannelType,
 12    CommandInteraction,
 13    ComponentType,
 14    EmbedBuilder,
 15    PermissionsBitField,
 16    SlashCommandBuilder
 17  } from 'discord.js';
 18  
 19  
 20  export default {
 21    data: new SlashCommandBuilder()
 22      .setName('deleteactivityrole')
 23      .setDescription(
 24        'Deletes an activity role from your guild. Provide the activity or the role, or both.'
 25      )
 26      .setDescriptionLocalizations(
 27        __h_dc('Deletes an activity role from your guild. Provide the activity or the role, or both.')
 28      )
 29      .setDefaultMemberPermissions(PermissionsBitField.Flags.ManageRoles)
 30      .setDMPermission(true)
 31      .addStringOption(option =>
 32        option
 33          .setName('activity')
 34          .setDescription('the activity roles with this name will be deleted')
 35          .setDescriptionLocalizations(__h_dc('the activity roles with this name will be deleted'))
 36          .setRequired(false)
 37      )
 38      .addRoleOption(option =>
 39        option
 40          .setName('role')
 41          .setDescription('the activity roles of this role will be deleted')
 42          .setDescriptionLocalizations(__h_dc('the activity roles of this role will be deleted'))
 43          .setRequired(false)
 44      )
 45      .addBooleanOption(option =>
 46        option
 47          .setName('all')
 48          .setDescription('ATTENTION: DELETES ALL ACTIVITY ROLES')
 49          .setDescriptionLocalizations(__h_dc('ATTENTION: DELETES ALL ACTIVITY ROLES'))
 50          .setRequired(false)
 51      ),
 52  
 53    execute: async interaction => {
 54      const locale = getLang(interaction);
 55      if (!interaction.channel) return;
 56      if (interaction.channel.type !== ChannelType.GuildText) {
 57        await interaction.reply(__({ phrase: 'This command can only be used in text channels.', locale }));
 58        return;
 59      }
 60  
 61      const role = interaction.options.get('role')?.role;
 62      const activity = interaction.options.get('activity')?.value as string | undefined;
 63      const all = interaction.options.get('all')?.value as boolean | undefined;
 64  
 65      if (all) {
 66        interaction.reply({
 67          content: __({ phrase: 'Are you sure you want to delete all activity roles?', locale }),
 68          components: [
 69            new ActionRowBuilder<ButtonBuilder>().addComponents(
 70              new ButtonBuilder()
 71                .setCustomId('deleteactivityrole:confirm')
 72                .setLabel(__({ phrase: 'Yes', locale }))
 73                .setStyle(ButtonStyle.Danger),
 74              new ButtonBuilder()
 75                .setCustomId('deleteactivityrole:cancel')
 76                .setLabel(__({ phrase: 'No', locale }))
 77                .setStyle(ButtonStyle.Secondary)
 78            )
 79          ],
 80          ephemeral: true
 81        });
 82        interaction.channel
 83          .createMessageComponentCollector({
 84            componentType: ComponentType.StringSelect,
 85            filter: btnInt => interaction.user.id === btnInt.user.id,
 86            max: 1,
 87            time: 1000 * 60
 88          })
 89          .on('collect', async (int: ButtonInteraction) => {
 90            switch (int.customId) {
 91              case 'deleteactivityrole:confirm':
 92                process(
 93                  int,
 94                  prepare('SELECT * FROM activityRoles WHERE guildID = ?')
 95                    .all(interaction.guildId) as DBActivityRole[],
 96                  locale
 97                );
 98                prepare('DELETE FROM activityRoles WHERE guildID = ?').run(interaction.guildId);
 99                break;
100              case 'deleteactivityrole:cancel':
101                int.update({ content: __({ phrase: 'Cancelled', locale }), components: [] });
102                break;
103            }
104          });
105      } else if (!role && !activity) {
106        return interaction.reply({
107          content: __({
108            phrase:
109              'You need to provide a role or an activity. If you provide a role, all activity roles for that role will be deleted. If you provide an activity, all activity roles with that name will be deleted.\nIf you provide both, all activity roles with that name for that role will be deleted.',
110            locale
111          }),
112          ephemeral: true
113        });
114      } else if (role && !activity) {
115        process(
116          interaction,
117          prepare('SELECT * FROM activityRoles WHERE guildID = ? AND roleID = ?')
118            .all(interaction.guildId, role.id) as DBActivityRole[],
119          locale
120        );
121        prepare('DELETE FROM activityRoles WHERE guildID = ? AND roleID = ?').run(
122          interaction.guildId,
123          role.id
124        );
125      } else if (!role && activity) {
126        process(
127          interaction,
128          prepare('SELECT * FROM activityRoles WHERE guildID = ? AND activityName = ?')
129            .all(interaction.guildId, activity) as DBActivityRole[],
130          locale
131        );
132        prepare('DELETE FROM activityRoles WHERE guildID = ? AND activityName = ?').run(
133          interaction.guildId,
134          activity
135        );
136      } else if (role && activity) {
137        process(
138          interaction,
139          prepare(
140            'SELECT * FROM activityRoles WHERE guildID = ? AND roleID = ? AND activityName = ?'
141          )
142            .all(interaction.guildId, role.id, activity) as DBActivityRole[],
143          locale
144        );
145        prepare(
146          'DELETE FROM activityRoles WHERE guildID = ? AND roleID = ? AND activityName = ?'
147        ).run(interaction.guildId, role.id, activity);
148      }
149    }
150  } as Command;
151  
152  function process(
153    interaction: CommandInteraction | ButtonInteraction,
154    deleted: DBActivityRole[],
155    locale: Locale
156  ) {
157    if (deleted.length > 0) {
158      const embeds = [
159        // new EmbedBuilder().setTitle('Deleted Activity Roles:').setColor(config.COLOR)
160      ];
161      embeds.push(
162        ...deleted.map(activityRole => {
163          return new EmbedBuilder()
164            .addFields(
165              {
166                name: __({ phrase: 'Activity', locale }),
167                value: activityRole.activityName,
168                inline: true
169              },
170              {
171                name: __({ phrase: 'Role', locale }),
172                value: `<@&${activityRole.roleID}>`,
173                inline: true
174              },
175              {
176                name: __({ phrase: 'Exact Activity Name', locale }),
177                value: activityRole.exactActivityName
178                  ? __({ phrase: 'Yes', locale })
179                  : __({ phrase: 'No', locale }),
180                inline: true
181              },
182              {
183                name: __({ phrase: 'Live', locale }),
184                value: activityRole.live
185                  ? __({ phrase: 'Yes', locale })
186                  : __({ phrase: 'No', locale }),
187                inline: true
188              }
189            )
190            .setColor(config.COLOR);
191        })
192      );
193      if (interaction instanceof CommandInteraction)
194        interaction.reply({
195          content: __({ phrase: 'Deleted Activity Roles:', locale }),
196          embeds: embeds,
197          ephemeral: true
198        });
199      else
200        interaction.update({
201          content: __({ phrase: 'Deleted Activity Roles:', locale }),
202          embeds: embeds,
203          components: []
204        });
205      deleted.forEach(activityRole => {
206        log.info(
207          `Activity role removed: in guild ${interaction.guild?.name} (${interaction.guildId}) role: ${activityRole.roleID} activityName: ${activityRole.activityName}, exactActivityName: ${activityRole.exactActivityName}, live mode: ${activityRole.live}`
208        );
209      });
210    } else {
211      if (interaction instanceof CommandInteraction)
212        interaction.reply({
213          content: __({ phrase: 'No activity roles were deleted.', locale }),
214          ephemeral: true
215        });
216      else
217        interaction.update({
218          content: __({ phrase: 'No activity roles were deleted.', locale }),
219          components: []
220        });
221    }
222  }