Source

commands/a_boothing/e-room-directory.js

  1. const PermissionCommand = require('../../classes/permission-command');
  2. const { Message, MessageEmbed, Role, Collection} = require('discord.js');
  3. const { deleteMessage } = require('../../discord-services');
  4. const BotGuildModel = require('../../classes/bot-guild');
  5. const winston = require('winston');
  6. const { StringPrompt, RolePrompt, SpecialPrompt } = require('advanced-discord.js-prompts');
  7. /**
  8. * Shows an embed with a link used for activities happening outside discord. Initial intent was to be used for
  9. * sponsor booths. A specified role can open and close the rooms as they want. When rooms open, a specified role is notified.
  10. * @category Commands
  11. * @subcategory Boothing
  12. * @extends PermissionCommand
  13. * @guildonly
  14. */
  15. class ERoomDirectory extends PermissionCommand {
  16. constructor(client) {
  17. super(client, {
  18. name: 'e-room-directory',
  19. group: 'a_boothing',
  20. memberName: 'keep track of booths',
  21. description: 'Sends embeds to booth directory to notify hackers of booth statuses',
  22. guildOnly: true,
  23. },
  24. {
  25. role: PermissionCommand.FLAGS.STAFF_ROLE,
  26. roleMessage: 'This command can only be ran by staff!',
  27. });
  28. }
  29. /**
  30. * Sends an embed same channel with the sponsor's name and link to their Zoom boothing room. The embed has 2 states: Open and Closed.
  31. * In the Closed state the embed will be red and say the booth is closed, which is the default, and the bot will react to the embed with
  32. * a door emoji at the beginning. In the Open state the embed will be green and say the booth is open. Any time a staff or sponsor clicks
  33. * on that emoji, the embed changes to the other state. When a booth goes from Closed to Open, it will also notify a role (specified by
  34. * the user) that it is open.
  35. *
  36. * @param {Message} message - messaged that called this command
  37. * @param {BotGuildModel} botGuild
  38. */
  39. async runCommand(botGuild, message) {
  40. // helpful vars
  41. let channel = message.channel;
  42. let userId = message.author.id;
  43. try {
  44. var sponsorName = await StringPrompt.single({prompt: 'What is the room name?', channel, userId, cancelable: true});
  45. sponsorName = sponsorName.content;
  46. var link = await StringPrompt.single({prompt: 'What is the room link? We will add no words to it! (ex. <Room Name> is Currently Open).', channel, userId, cancelable: true});
  47. link = link.content;
  48. //ask user for role and save its id in the role variable
  49. var role = (await RolePrompt.single({prompt: 'What role will get pinged when the rooms open?', channel, userId})).id;
  50. } catch (error) {
  51. channel.send('<@' + userId + '> Command was canceled due to prompt being canceled.').then(msg => msg.delete({timeout: 5000}));
  52. return;
  53. }
  54. /**
  55. * prompt for roles that can open/close the room
  56. * @type {Collection<String, Role>}
  57. */
  58. var roomRoles;
  59. try {
  60. roomRoles = await RolePrompt.multi({ prompt: 'What other roles can open/close the room? (Apart form staff).', channel, userId, cancelable: true });
  61. } catch (error) {
  62. // do nothing as this is fine
  63. winston.loggers.get(message.guild.id).warning(`Got an error: ${error} but I let it go since we expected it from the prompt.`, { event: 'E-Room-Directory Command' });
  64. }
  65. // add staff role
  66. roomRoles.set(botGuild.roleIDs.staffRole, message.guild.roles.resolve(botGuild.roleIDs.staffRole));
  67. // prompt user for emoji to use
  68. let emoji = await SpecialPrompt.singleEmoji({prompt: 'What emoji do you want to use to open/close the room?', channel, userId});
  69. //variable to keep track of state (Open vs Closed)
  70. var closed = true;
  71. //embed for closed state
  72. const embed = new MessageEmbed()
  73. .setColor('#FF0000')
  74. .setTitle(sponsorName + ' is Currently Closed')
  75. .setDescription('Room link: ' + link);
  76. //send closed embed at beginning (default is Closed)
  77. channel.send(embed).then((msg) => {
  78. msg.pin();
  79. msg.react(emoji);
  80. //only listen for the door react from users that have one of the roles in the room roles collection
  81. const emojiFilter = (reaction, user) => {
  82. let member = message.guild.member(user);
  83. return !user.bot && reaction.emoji.name === emoji.name && roomRoles.some(role => member.roles.cache.has(role.id));
  84. };
  85. const emojiCollector = msg.createReactionCollector(emojiFilter);
  86. var announcementMsg;
  87. emojiCollector.on('collect', async (reaction, user) => {
  88. reaction.users.remove(user);
  89. if (closed) {
  90. //embed for open state
  91. const openEmbed = new MessageEmbed()
  92. .setColor('#008000')
  93. .setTitle(sponsorName + ' \'s Booth is Currently Open')
  94. .setDescription('Please visit this Zoom link to join: ' + link);
  95. //change to open state embed if closed is true
  96. msg.edit(openEmbed);
  97. closed = false;
  98. //notify people of the given role that booth is open and delete notification after 5 mins
  99. announcementMsg = await channel.send('<@&' + role + '> ' + sponsorName + ' \'s booth has just opened!');
  100. announcementMsg.delete({timeout: 300 * 1000});
  101. } else {
  102. //change to closed state embed if closed is false
  103. msg.edit(embed);
  104. closed = true;
  105. deleteMessage(announcementMsg);
  106. }
  107. });
  108. });
  109. }
  110. }
  111. module.exports = ERoomDirectory;