Guest User

Untitled

a guest
Dec 21st, 2024
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.97 KB | None | 0 0
  1. const {
  2. Client,
  3. ChatInputCommandInteraction,
  4. SlashCommandBuilder,
  5. EmbedBuilder,
  6. ActionRowBuilder,
  7. ButtonBuilder,
  8. ButtonStyle,
  9. ComponentType,
  10. StringSelectMenuBuilder,
  11. TextInputBuilder,
  12. TextInputStyle,
  13. PermissionFlagsBits,
  14. ChannelType,
  15. } = require('discord.js');
  16. const gamesData = require('../../Templates/gameTMP.json'); // Adjust the path if necessary
  17. const { getLanguage } = require('../../Utils/getLanguage');
  18.  
  19. module.exports = {
  20. data: new SlashCommandBuilder()
  21. .setName('create_event')
  22. .setDescription('📅 Create a new event step by step.'),
  23.  
  24. /**
  25. * Executes the command logic.
  26. * @param {ChatInputCommandInteraction} interaction
  27. * @param {Client} client
  28. */
  29. async execute(interaction, client) {
  30. await interaction.deferReply({ ephemeral: true });
  31. const { user, guild } = interaction;
  32.  
  33. const translations = await getLanguage(interaction, true);
  34.  
  35. // Notify user to check DMs
  36. const notificationEmbed = new EmbedBuilder()
  37. .setTitle('Event Creation')
  38. .setDescription('Check your DMs to start creating your event! 📩')
  39. .setColor('Aqua');
  40.  
  41. await interaction.editReply({ embeds: [notificationEmbed] });
  42.  
  43. try {
  44. const dmChannel = await user.createDM();
  45. // Ask for event type
  46. const eventTypeEmbed = new EmbedBuilder()
  47. .setTitle('Choose Event Type')
  48. .setDescription(
  49. 'Please select the type of event you want to create from the options below:'
  50. )
  51. .addFields(
  52. {
  53. name: '🎮 Gaming',
  54. value: 'Events related to games like WoW, FFXIV, etc.',
  55. },
  56. { name: '📊 General Polls', value: 'Surveys or voting events.' },
  57. { name: '🛠 Custom Events', value: 'Create a fully custom event.' }
  58. )
  59. .setColor('Blue')
  60. .setFooter({
  61. text: 'Select an option to proceed.',
  62. iconURL: user.displayAvatarURL(),
  63. })
  64. .setTimestamp();
  65.  
  66. const eventTypeButtons = new ActionRowBuilder().addComponents(
  67. new ButtonBuilder()
  68. .setCustomId('gaming_event')
  69. .setLabel('🎮 Gaming')
  70. .setStyle(ButtonStyle.Primary),
  71. new ButtonBuilder()
  72. .setCustomId('general_poll')
  73. .setLabel('📊 General Poll')
  74. .setStyle(ButtonStyle.Secondary),
  75. new ButtonBuilder()
  76. .setCustomId('custom_event')
  77. .setLabel('🛠 Custom Event')
  78. .setStyle(ButtonStyle.Success)
  79. );
  80.  
  81. await dmChannel.send({
  82. embeds: [eventTypeEmbed],
  83. components: [eventTypeButtons],
  84. });
  85.  
  86. const collector = dmChannel.createMessageComponentCollector({
  87. filter: (interaction) =>
  88. interaction.customId === 'gaming_event' ||
  89. interaction.customId === 'general_poll' ||
  90. interaction.customId === 'custom_event',
  91. componentType: ComponentType.Button,
  92. idle: 60000,
  93. });
  94.  
  95. const variableData = {
  96. Type: '',
  97. templateID: '',
  98. Title: '',
  99. Description: '',
  100. Date: '',
  101. Time: '',
  102. Channel: '',
  103. };
  104.  
  105. collector.on('collect', async (buttonInteraction) => {
  106. await buttonInteraction.deferUpdate();
  107.  
  108. let responseEmbed;
  109.  
  110. if (buttonInteraction.customId === 'gaming_event') {
  111. // Prepare game list for dropdown
  112. variableData.Type = 'Gaming'; // Save type
  113. const gameOptions = gamesData.map((game) => ({
  114. emoji: `${game.templateEmoji}`,
  115. label: `${game.templateID} - ${game.templateName}`,
  116. value: `${game.templateID}`,
  117. }));
  118.  
  119. // Show game selection dropdown
  120. responseEmbed = new EmbedBuilder()
  121. .setTitle('Gaming Event Selected')
  122. .setDescription(
  123. 'You chose **Gaming**. Select a game from the list below:'
  124. )
  125. .setColor('Green');
  126.  
  127. // Add game list as fields in the embed
  128. gamesData.forEach((game) => {
  129. responseEmbed.addFields({
  130. name: `\u200B`,
  131. value: `**${game.templateID}** - ${game.templateEmoji} ${game.templateName}`, // Add other details if needed
  132. inline: true, // Optional: display fields inline
  133. });
  134. });
  135.  
  136. const selectMenu = new ActionRowBuilder().addComponents(
  137. new StringSelectMenuBuilder()
  138. .setCustomId('game_select')
  139. .setPlaceholder('Choose your game')
  140. .addOptions(gameOptions)
  141. );
  142.  
  143. await dmChannel.send({
  144. embeds: [responseEmbed],
  145. components: [selectMenu],
  146. });
  147. } else if (buttonInteraction.customId === 'general_poll') {
  148. responseEmbed = new EmbedBuilder()
  149. .setTitle('General Poll Selected')
  150. .setDescription(
  151. 'You chose **General Poll**. Let’s set up your poll questions and options.'
  152. )
  153. .setColor('Green');
  154. } else if (buttonInteraction.customId === 'custom_event') {
  155. responseEmbed = new EmbedBuilder()
  156. .setTitle('Custom Event Selected')
  157. .setDescription(
  158. 'You chose **Custom Event**. Let’s build your custom event step by step.'
  159. )
  160. .setColor('Green');
  161. }
  162.  
  163. collector.stop(); // Proceed to the next steps based on the selection
  164.  
  165. const templateCollector = dmChannel.createMessageComponentCollector({
  166. componentType: ComponentType.StringSelect,
  167. idle: 60000,
  168. });
  169.  
  170. templateCollector.on('collect', async (dropDownInteraction) => {
  171. await dropDownInteraction.deferReply();
  172. variableData.templateID = dropDownInteraction.values[0];
  173. templateCollector.stop();
  174.  
  175. const titleEmbed = new EmbedBuilder()
  176. .setTitle('Event Title')
  177. .setDescription(
  178. 'Please provide a title for your event. Respond with your desired title below.'
  179. )
  180. .setColor('Blue');
  181.  
  182. await dropDownInteraction.followUp({ embeds: [titleEmbed] });
  183.  
  184. const titleCollector = dmChannel.createMessageCollector({
  185. filter: (m) =>
  186. m.author.id === user.id && m.channel.id === dmChannel.id,
  187. idle: 60000,
  188. max: 1,
  189. });
  190.  
  191. titleCollector.on('collect', async (message) => {
  192. variableData.Title = message.content;
  193. titleCollector.stop();
  194.  
  195. const descriptionEmbed = new EmbedBuilder()
  196. .setTitle('Event Description')
  197. .setDescription(
  198. 'Please provide a description for your event. Respond with your desired description below.'
  199. )
  200. .setColor('Blue');
  201.  
  202. await dmChannel.send({ embeds: [descriptionEmbed] });
  203.  
  204. const descriptionCollector = dmChannel.createMessageCollector({
  205. filter: (m) =>
  206. m.author.id === user.id && m.channel.id === dmChannel.id,
  207. idle: 60000,
  208. max: 1,
  209. });
  210.  
  211. descriptionCollector.on('collect', async (message) => {
  212. variableData.Description = message.content;
  213. descriptionCollector.stop();
  214.  
  215. const dateEmbed = new EmbedBuilder()
  216. .setTitle('Event Date')
  217. .setDescription(
  218. 'Please provide a date for your event.\n\n' +
  219. '**Format:** `YYYY-MM-DD`\n' +
  220. '**Example:** `2024-12-31`\n\n' +
  221. 'Type your date below to proceed.'
  222. )
  223. .setColor('Blue')
  224. .setFooter({
  225. text: 'Ensure the format is correct to avoid errors.',
  226. })
  227. .setTimestamp();
  228.  
  229. await dmChannel.send({ embeds: [dateEmbed] });
  230.  
  231. const dateCollector = dmChannel.createMessageCollector({
  232. filter: (m) =>
  233. m.author.id === user.id && m.channel.id === dmChannel.id,
  234. idle: 60000,
  235. });
  236.  
  237. dateCollector.on('collect', async (message) => {
  238. const userInput = message.content;
  239. variableData.Date = userInput;
  240.  
  241. const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
  242.  
  243. if (!dateRegex.test(userInput)) {
  244. const errorEmbed = new EmbedBuilder()
  245. .setTitle('Invalid Date Format')
  246. .setDescription(
  247. 'The date you provided is not in the correct format.\n' +
  248. '**Expected Format:** `YYYY-MM-DD`\n' +
  249. '**Example:** `2024-12-31`\n\n' +
  250. 'Please try again.'
  251. )
  252. .setColor('Red');
  253.  
  254. await dmChannel.send({ embeds: [errorEmbed] });
  255. return;
  256. }
  257.  
  258. const [year, month, day] = userInput.split('-').map(Number);
  259.  
  260. const daysInMonth = new Date(year, month, 0).getDate();
  261. if (month < 1 || month > 12 || day < 1 || day > daysInMonth) {
  262. const errorEmbed = new EmbedBuilder()
  263. .setTitle('Invalid Date')
  264. .setDescription(
  265. `The date you provided is not valid.\n` +
  266. `**Month Range:** 1-12\n` +
  267. `**Day Range:** 1-${daysInMonth} (for ${month}/${year})\n\n` +
  268. `Please try again.`
  269. )
  270. .setColor('Red');
  271.  
  272. await dmChannel.send({ embeds: [errorEmbed] });
  273. return;
  274. }
  275.  
  276. dateCollector.stop();
  277.  
  278. const botTimeZone =
  279. Intl.DateTimeFormat().resolvedOptions().timeZone; // Bot's timezone
  280. const now = new Date();
  281. const botTime = now.toLocaleTimeString('en-US', {
  282. timeZone: botTimeZone,
  283. hour12: false,
  284. hour: '2-digit',
  285. minute: '2-digit',
  286. });
  287.  
  288. const timeEmbed = new EmbedBuilder()
  289. .setTitle('Event Time')
  290. .setDescription(
  291. `Please provide the time for your event in **24-hour format**.\n\n` +
  292. `**Example Format:** \`18:15\`\n\n` +
  293. `**Current Server Time:**\n` +
  294. `> 🕒 ${botTime} (${botTimeZone})\n\n` +
  295. `*Note: To change the servers's timezone, adjust your server settings.*`
  296. )
  297. .setColor('Blue');
  298.  
  299. await dmChannel.send({ embeds: [timeEmbed] });
  300.  
  301. const timeCollector = dmChannel.createMessageCollector({
  302. filter: (m) =>
  303. m.author.id === user.id && m.channel.id === dmChannel.id,
  304. idle: 60000,
  305. });
  306.  
  307. timeCollector.on('collect', async (message) => {
  308. const timeInput = message.content.trim();
  309.  
  310. const timeRegex = /^([01]?\d|2[0-3]):([0-5]\d)$/;
  311. if (!timeRegex.test(timeInput)) {
  312. const errorEmbed = new EmbedBuilder()
  313. .setTitle('Invalid Time Format')
  314. .setDescription(
  315. '❌ The time you entered is invalid. Please use the **24-hour format**, e.g., `18:15`.\n\n' +
  316. '**Example:**\n`18:15`'
  317. )
  318. .setColor('Red');
  319.  
  320. dmChannel.send({ embeds: [errorEmbed] });
  321. return;
  322. }
  323.  
  324. variableData.Time = timeInput;
  325. timeCollector.stop();
  326.  
  327. const channelEmbed = new EmbedBuilder()
  328. .setTitle('Select Event Channel')
  329. .setDescription(
  330. 'Please choose a channel for your event to take place in. Select from the options below:'
  331. )
  332. .setColor('Blue');
  333.  
  334. const textChannels = [];
  335. const forumChannels = [];
  336. const threadChannels = [];
  337.  
  338. const allChannels = await guild.channels.cache.filter(
  339. (channel) => {
  340. const userHasPermission =
  341. channel
  342. .permissionsFor(user)
  343. .has(PermissionFlagsBits.ViewChannel) &&
  344. channel
  345. .permissionsFor(user)
  346. .has(PermissionFlagsBits.SendMessages);
  347. const botHasPermission =
  348. channel
  349. .permissionsFor(guild.members.me)
  350. .has(PermissionFlagsBits.ViewChannel) &&
  351. channel
  352. .permissionsFor(guild.members.me)
  353. .has(PermissionFlagsBits.SendMessages);
  354. return userHasPermission && botHasPermission;
  355. }
  356. );
  357.  
  358. allChannels.forEach((channel) => {
  359. if (channel.type === ChannelType.GuildForum) {
  360. forumChannels.push(channel);
  361. } else if (channel.isThread()) {
  362. threadChannels.push(channel);
  363. } else if (channel.type === ChannelType.GuildText) {
  364. textChannels.push(channel);
  365. }
  366. });
  367.  
  368. const createChannelDropdown = (channels, placeholder) => {
  369. const options = channels.map((channel) => ({
  370. label: channel.name,
  371. value: channel.id,
  372. }));
  373.  
  374. const dropdowns = [];
  375. for (let i = 0; i < options.length; i += 25) {
  376. const chunk = options.slice(i, i + 25);
  377. const selectMenu = new StringSelectMenuBuilder()
  378. .setCustomId(placeholder.toLowerCase() + '_select')
  379. .setPlaceholder(`Choose a ${placeholder} channel`)
  380. .addOptions(chunk);
  381. dropdowns.push(
  382. new ActionRowBuilder().addComponents(selectMenu)
  383. );
  384. }
  385.  
  386. return dropdowns;
  387. };
  388.  
  389. const components = [];
  390.  
  391. if (forumChannels.length > 0) {
  392. channelEmbed.addFields({
  393. name: `Forum Channels (${forumChannels.length})`,
  394. value: 'Select a forum channel for your event',
  395. });
  396. components.push(
  397. ...createChannelDropdown(forumChannels, 'Forum')
  398. );
  399. }
  400.  
  401. if (textChannels.length > 0) {
  402. channelEmbed.addFields({
  403. name: `Text Channels (${textChannels.length})`,
  404. value: 'Select a text channel for your event',
  405. });
  406. components.push(
  407. ...createChannelDropdown(textChannels, 'Text')
  408. );
  409. }
  410.  
  411. if (threadChannels.length > 0) {
  412. channelEmbed.addFields({
  413. name: `Thread Channels (${threadChannels.length})`,
  414. value: 'Select a thread channel for your event',
  415. });
  416. components.push(
  417. ...createChannelDropdown(threadChannels, 'Thread')
  418. );
  419. }
  420.  
  421. await dmChannel.send({
  422. embeds: [channelEmbed],
  423. components: components.length ? components : [],
  424. });
  425.  
  426. const channelCollector =
  427. dmChannel.createMessageComponentCollector({
  428. filter: (interaction) =>
  429. interaction.customId.endsWith('_select'),
  430. componentType: ComponentType.StringSelect,
  431. idle: 60000,
  432. });
  433.  
  434. channelCollector.on('collect', async (interaction) => {
  435. await interaction.deferUpdate();
  436. variableData.Channel = interaction.values[0];
  437. const selectedChannelId = interaction.values[0];
  438. const selectedChannel = await guild.channels.fetch(
  439. selectedChannelId
  440. );
  441.  
  442. const confirmationEmbed = new EmbedBuilder()
  443. .setTitle('Channel Selected')
  444. .setDescription(
  445. `You selected the channel **${selectedChannel.name}** for your event.`
  446. )
  447. .setColor('Green');
  448.  
  449. await interaction.followUp({
  450. embeds: [confirmationEmbed],
  451. });
  452. channelCollector.stop();
  453.  
  454. await dmChannel.send({
  455. content:
  456. `Here are the details of your event:\n\n` +
  457. `**Event Type:** ${variableData.Type}\n` +
  458. `**Template ID:** ${variableData.templateID}\n` +
  459. `**Title:** ${variableData.Title}\n` +
  460. `**Description:** ${variableData.Description}\n` +
  461. `**Date:** ${variableData.Date}\n` +
  462. `**Channel:** ${selectedChannel.name}`,
  463. });
  464. });
  465.  
  466. channelCollector.on('end', (_, reason) => {
  467. if (reason === 'time') {
  468. const timeoutEmbed = new EmbedBuilder()
  469. .setTitle('Session Expired')
  470. .setDescription(
  471. 'You took too long to respond. Please try again.'
  472. )
  473. .setColor('Red');
  474.  
  475. dmChannel.send({ embeds: [timeoutEmbed] });
  476. }
  477. });
  478. });
  479.  
  480. timeCollector.on('end', (_, reason) => {
  481. if (reason === 'idle') {
  482. const timeoutEmbed = new EmbedBuilder()
  483. .setTitle('Session Expired')
  484. .setDescription(
  485. 'You took too long to respond. Please try again.'
  486. )
  487. .setColor('Red');
  488.  
  489. dmChannel.send({ embeds: [timeoutEmbed] });
  490. }
  491. });
  492. });
  493. });
  494.  
  495. descriptionCollector.on('end', (_, reason) => {
  496. if (reason === 'idle') {
  497. const timeoutEmbed = new EmbedBuilder()
  498. .setTitle('Session Expired')
  499. .setDescription(
  500. 'You took too long to respond. Please try again.'
  501. )
  502. .setColor('Red');
  503.  
  504. dmChannel.send({ embeds: [timeoutEmbed] });
  505. }
  506. });
  507. });
  508.  
  509. titleCollector.on('end', (_, reason) => {
  510. if (reason === 'idle') {
  511. const timeoutEmbed = new EmbedBuilder()
  512. .setTitle('Session Expired')
  513. .setDescription(
  514. 'You took too long to respond. Please try again.'
  515. )
  516. .setColor('Red');
  517.  
  518. dmChannel.send({ embeds: [timeoutEmbed] });
  519. }
  520. });
  521. });
  522.  
  523. templateCollector.on('end', (_, reason) => {
  524. if (reason === 'idle') {
  525. const timeoutEmbed = new EmbedBuilder()
  526. .setTitle('Session Expired')
  527. .setDescription('You took too long to respond. Please try again.')
  528. .setColor('Red');
  529.  
  530. dmChannel.send({ embeds: [timeoutEmbed] });
  531. }
  532. });
  533. });
  534.  
  535. collector.on('end', (_, reason) => {
  536. if (reason === 'idle') {
  537. const timeoutEmbed = new EmbedBuilder()
  538. .setTitle('Session Expired')
  539. .setDescription('You took too long to respond. Please try again.')
  540. .setColor('Red');
  541.  
  542. dmChannel.send({ embeds: [timeoutEmbed] });
  543. }
  544. });
  545. } catch (error) {
  546. const errorEmbed = new EmbedBuilder()
  547. .setTitle('Error')
  548. .setDescription(
  549. 'I was unable to send you a DM. Please check your settings and try again.'
  550. )
  551. .setColor('Red');
  552.  
  553. await interaction.editReply({ embeds: [errorEmbed] });
  554. }
  555. },
  556. };
  557.  
Advertisement
Add Comment
Please, Sign In to add comment