// Discord.js commando requirements
const PermissionCommand = require('../../classes/permission-command');
const { checkForRole, sendMessageToMember, } = require('../../discord-services');
const { MessageEmbed, Collection, Message, } = require('discord.js');
const BotGuildModel = require('../../classes/bot-guild');
/**
* The ask command tries to imitate a thread like functionality from slack. Users can ask questions, and then other
* users can respond to the question, the responses are added on the same message embed, to keep the conversation on
* the same message.
* @category Commands
* @subcategory Hacker-Utility
* @extends PermissionCommand
*/
class AskQuestion extends PermissionCommand {
constructor(client) {
super(client, {
name: 'ask',
group: 'hacker_utility',
memberName: 'ask anonymous question with thread',
description: 'Will send the question to the same channel, and add emoji collector for thread like support.',
guildOnly: true,
args: [
{
key: 'question',
prompt: 'Question to ask',
type: 'string',
default: '',
}
],
});
}
/**
* @param {BotGuildModel} botGuild
* @param {Message} message
* @param {Object} args
* @param {String} args.question
*/
async runCommand(botGuild, message, {question}) {
// if question is blank let user know via DM and exit
if (question === '') {
sendMessageToMember(message.member, 'When using the !ask command, add your question on the same message!\n' +
'Like this: !ask This is a question');
return;
}
// get current channel
var curChannel = message.channel;
// message embed to be used for question
const qEmbed = new MessageEmbed()
.setColor(botGuild.colors.questionEmbedColor)
.setTitle('Question from ' + message.author.username)
.setDescription(question);
// send message and add emoji collector
curChannel.send(qEmbed).then(async (msg) => {
// list of users currently responding
var onResponse = new Collection();
msg.react('🇷'); // respond emoji
msg.react('✅'); // answered emoji!
msg.react('⏫'); // up vote emoji
msg.react('⛔'); // delete emoji
// filter and collector
const emojiFilter = (reaction, user) => !user.bot && (reaction.emoji.name === '🇷' || reaction.emoji.name === '✅' || reaction.emoji.name === '⛔');
const collector = msg.createReactionCollector(emojiFilter);
collector.on('collect', async (reaction, user) => {
// delete the reaction
reaction.users.remove(user.id);
// add response to question
if (reaction.emoji.name === '🇷') {
// make sure user is not already responding
if (onResponse.has(user.id)) {
return;
} else {
onResponse.set(user.id, user.username);
}
// prompt the response
curChannel.send('<@' + user.id + '> Please send your response within 15 seconds! If you want to cancel write cancel.').then(prompt => {
// filter and message await only one
// only user who reacted this message will be able to add a reply to it
curChannel.awaitMessages(m => m.author.id === user.id, {max: 1, time: 15000, errors: ['time']}).then((msgs) => {
var response = msgs.first();
// if cancel then do nothing
if (response.content.toLowerCase() != 'cancel') {
// if user has a mentor role, they get a special title
if (checkForRole(response.member, botGuild.roleIDs.staffRole)) {
msg.edit(msg.embeds[0].addField('🤓 ' + user.username + ' Responded:', response.content));
} else {
// add a field to the message embed with the response
msg.edit(msg.embeds[0].addField(user.username + ' Responded:', response.content));
}
}
// delete messages
prompt.delete();
response.delete();
// remove user from on response list
onResponse.delete(user.id);
}).catch((msgs) => {
prompt.delete();
curChannel.send('<@' + user.id + '> Time is up! When you are ready to respond, emoji again!').then(msg => msg.delete({timeout: 2000}));
// remove user from on response list
onResponse.delete(user.id);
});
});
}
// check for check-mark emoji and only user who asked the question
else if (reaction.emoji.name === '✅' && user.id === message.author.id) {
// change color
msg.embeds[0].setColor('#80c904');
// change title and edit embed
msg.edit(msg.embeds[0].setTitle('✅ ANSWERED ' + msg.embeds[0].title));
}
// remove emoji will remove the message
else if (reaction.emoji.name === '⛔') {
// check that user is staff
if (checkForRole(msg.guild.member(user), botGuild.roleIDs.staffRole)) {
msg.delete();
} else {
sendMessageToMember(user, 'Deleting a question is only available to staff!', true);
}
}
});
});
}
}
module.exports = AskQuestion;
Source