Discord.js forms - javascript

I'm trying to make a forms but it doesn't work well for me. The timeout does not work and I need to type the command twice for it to work I don't know why
const Discord = require('discord.js');
module.exports = {
name: 'forms',
category: "Info",
description: 'forms',
run: async(client, message, args) => {
const questions = [
"What's your IGN?",
"How old are you?",
"What time zone do you reside in?",
"Do you have Schematica?"
];
const applying = [];
bot.on("messageCreate", async message => {
if (message.author.bot) return;
if (message.content.toLowerCase() === "!forms") {
if (applying.includes(message.author.id)) return;
try {
console.log(`${message.author.tag} began applying.`);
applying.push(message.author.id);
await message.author.send(":pencil: **Application started!** Type `#cancel` to exit.");
for (let i = 0, cancel = false; i < questions.length && cancel === false; i++) {
await message.author.send(questions[i]);
await message.author.send(m => m.author.id === message.author.id, { max: 1, time: 300000, errors: ["time"] })
.then(async collected => {
if (collected.first().content.toLowerCase() === "#cancel") {
await message.channel.send(":x: **Application cancelled.**");
applying.splice(applying.indexOf(message.author.id), 1);
cancel = true;
console.log(`${message.author.tag} cancelled their application.`);
}
}).catch(async ()=> {
await message.author.send(":hourglass: **Application timed out.**");
applying.splice(applying.indexOf(message.author.id), 1);
cancel = true;
console.log(`${message.author.tag} let their application time out.`);
});
}
await message.author.send(":thumbsup: **You're all done!**");
console.log(`${message.author.tag} finished applying.`);
} catch(err) {
console.error(err);
}
}
});
},
};

Remove the messageCreate event from there:
const questions = [
"What's your IGN?",
"How old are you?",
"What time zone do you reside in?",
"Do you have Schematica?"
];
const applying = [];
if (message.author.bot) return;
if (message.content.toLowerCase() === "!forms") {
if (applying.includes(message.author.id)) return;
try {
console.log(`${message.author.tag} began applying.`);
applying.push(message.author.id);
await message.author.send(":pencil: **Application started!** Type `#cancel` to exit.");
for (let i = 0, cancel = false; i < questions.length && cancel === false; i++) {
await message.author.send(questions[i]);
await message.author.send(m => m.author.id === message.author.id, { max: 1, time: 300000, errors: ["time"] })
.then(async collected => {
if (collected.first().content.toLowerCase() === "#cancel") {
await message.channel.send(":x: **Application cancelled.**");
applying.splice(applying.indexOf(message.author.id), 1);
cancel = true;
console.log(`${message.author.tag} cancelled their application.`);
}
}).catch(async ()=> {
await message.author.send(":hourglass: **Application timed out.**");
applying.splice(applying.indexOf(message.author.id), 1);
cancel = true;
console.log(`${message.author.tag} let their application time out.`);
});
}
await message.author.send(":thumbsup: **You're all done!**");
console.log(`${message.author.tag} finished applying.`);
} catch(err) {
console.error(err);
}
}
Note: You may need to do some formatting
In the future, never listen to events within an event

Related

Why is my discord bot taking so long to research videos

Basically my bot is taking too long to send me the results for the video research he made on youtube. I do believe that the problem is in this for loop, but I'm not sure about it
for(var i = 0; i <= 4; i++){
//Search for video
const videoFinder = async (query) => {
const videoResult = await ytSearch(query);
return (videoResult.videos.length > (i + 1)) ? videoResult.videos[i] : null;
}
const video = await videoFinder(args.join(' '));
if(video){
searchResults.push(video)
} else {
searchResults.push('No video results found');
}
}
This is the entire code to the play command:
const ytdl = require('ytdl-core')
const ytSearch = require('yt-search');
const { User } = require('discord.js');
const { accessSync } = require('fs');
module.exports = {
name: 'play',
description: "Plays video from youtube on a earrape mode",
async execute(client, message, args){
const voiceChannel = message.member.voice.channel;
//Check if person is in voice chat
if(!voiceChannel) return message.channel.send('You need to be in a voice chat to execute this command');
//Check person permissions
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT' || 'SPEAK')) return message.channel.send('You dont have the permission to execute this command');
//Check if message has arguments
if(!args.length) return message.channel.send('You need to send some keywords')
var searchResults = [];
//Bot join VC
const connection = await voiceChannel.join();
for(var i = 0; i <= 4; i++){
//Search for video
const videoFinder = async (query) => {
const videoResult = await ytSearch(query);
return (videoResult.videos.length > (i + 1)) ? videoResult.videos[i] : null;
}
const video = await videoFinder(args.join(' '));
if(video){
searchResults.push(video)
} else {
searchResults.push('No video results found');
}
}
let filter = m => m.author.id === message.author.id
var whichVideo = null;
await message.channel.send({embed: {
color: 3447003,
title: "Select your music:",
fields: [
{
name: `1.`,
value: `***[${searchResults[0].title}](${searchResults[0].url})***`
},
{
name: `2.`,
value: `***[${searchResults[1].title}](${searchResults[1].url})***`
},
{
name: `3.`,
value: `***[${searchResults[2].title}](${searchResults[2].url})***`
},
{
name: `4.`,
value: `***[${searchResults[3].title}](${searchResults[3].url})***`
},
{
name: `5.`,
value: `***[${searchResults[4].title}](${searchResults[4].url})***`
}
],
footer: {
icon_url: client.user.avatarURL,
text: "Timeout in 30 seconds"
}
}
})
.then(() => {
message.channel.awaitMessages(filter, {
max: 1,
time: 30000,
errors: ['time']
})
.then(message => {
message = message.first();
if (message.content == '1' || message.content == '2' || message.content == '3' || message.content == '4' || message.content == '5'){
whichVideo = parseInt(message.content) - 1;
message.channel.send(`:musical_note: added ~ ***${searchResults[whichVideo].title}*** ~ to the queue`);
try{
message.channel.send(`:loud_sound: :notes: Now Playing: ~ ***${searchResults[whichVideo].title}*** ~`);
//Get only the audio of the video
const stream = ytdl(searchResults[whichVideo].url, {filter: 'audioonly'});
//Bot joins plays music
connection.play(stream, {seek: 0, volume: 1})
//Leave when music ends
.on('finish', () =>{
voiceChannel.leave();
});
} catch (e){
console.log(e);
voiceChannel.leave();
}
} else {
message.channel.send('');
}
})
.catch(collected => {
message.channel.send('');
});
})
}
}
I am not 100% sure, but I think the issue is in this part:
for(var i = 0; i <= 4; i++){
//Search for video
const videoFinder = async (query) => {
const videoResult = await ytSearch(query);
return (videoResult.videos.length > (i + 1)) ? videoResult.videos[i] : null;
}
const video = await videoFinder(args.join(' '));
if(video){
searchResults.push(video)
} else {
searchResults.push('No video results found');
}
}
You are launching 4 searches (?)
Try using this library instead:
var search = require('youtube-search');
var opts = {
maxResults: 4,
key: 'Your YouTube API V3 key'
};
search('video title', opts, function(err, results) {
if(err) return console.log(err);
console.dir(results);
});
This way you can search for 4 results at the same time, this should speed up your process.

How to detect more than one reaction to a message in discord.js?

I'm trying to create a dynamic help command, in the sense that the users can decide what "page" they would like to go to simply by reacting to the message. I have tried doing this, however, with my code it only detects the first reaction. I have tried setting the max for the awaitReactions method to more than 1, however once I do that it doesn't detect any reaction. Here is my code:
const Discord = require('discord.js');
const fs = require('fs');
module.exports = {
name: 'help',
aliases: ('cmds'),
description: 'Shows you the list of commands.',
usage: 'help',
example: 'help',
async execute(client, message, args, prefix, footer, color, invite, dev, devID, successEmbed, errorEmbed, usageEmbed) {
const helpEmbed = new Discord.MessageEmbed()
.setColor(color)
.setAuthor(`${client.user.username} Discord Bot\n`)
.setDescription('• 📍 Prefix: ``' + prefix + '``\n' +
`• 🔧 Developer: ${dev}\n\n⚙️ - **Panel**\n👮 - **Moderation**\n❔ - **Other**`);
const moderationEmbed = new Discord.MessageEmbed()
.setColor(color)
.setAuthor(`Config\n`)
.setDescription('To get more information about a certain command, use ``' + prefix +
'help [command]``.\n\n•``test``, ``test2``, ``test3``.');
try {
const filter = (reaction, user) => {
return (reaction.emoji.name === '⚙️' || '👮' || '❔') && user.id === message.author.id;
};
message.delete();
message.channel.send(helpEmbed).then(embedMsg => {
embedMsg.react("⚙️")
.then(embedMsg.react("👮"))
.then(embedMsg.react("❔"))
embedMsg.awaitReactions(filter, { max: 1, time: 60000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
if (reaction.emoji.name === '⚙️') {
embedMsg.edit(helpEmbed);
} else if (reaction.emoji.name === '👮') {
embedMsg.edit(moderationEmbed);
} else if (reaction.emoji.name === '❔') {
message.reply('test.');
}
})
.catch(collected => {
message.reply('didnt work.');
});
});
} catch (e) {
console.log(e.stack);
}
}
}
Used a collector.
const collector = embedMsg.createReactionCollector(filter);
collector.on('collect', (reaction, user) => {
reaction.users.remove(user.id); // remove the reaction
if (reaction.emoji.name === '⚙️') {
embedMsg.edit(helpEmbed);
} else if (reaction.emoji.name === '🛠️') {
embedMsg.edit(utilityEmbed);
} else if (reaction.emoji.name === '👮') {
embedMsg.edit(moderationEmbed);
}
});

How to successfully update a MongoDB schema in Discord.js?

I have been trying to make a function where I tell the bot what channel to deploy the points system in. I am also using MongoDB so that when my bot restarts, it remembers what channel the points system was set in. However, I am getting errors such as 404: Not Found and it does not even update the schema, so as a result, I am looking for available solutions. Here's my code:
const {
prefix,
} = require('./config.json')
const Discord = require('discord.js')
var date = new Date().toLocaleString();
module.exports = (client) => {
const Mongo = require('mongoose')
const LeaderboardSequence = require('./leaderboard.js')
const SLSchema = require('./setLeaderboard.js')
const mongoose = require('mongoose')
mongoose.connect('insert URL here', {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false
});
client.on('message', async message => {
if (message.content === `${prefix}setLeaderboardChannel`) {
// Destructure the guild and channel properties from the message object
const { guild, channel } = message
// Use find one and update to either update or insert the
// data depending on if it exists already
await SLSchema.findOneAndUpdate(
{
_id: guild.id,
},
{
_id: guild.id,
channelId: channel.id,
},
{
upsert: true,
}
)
message.reply(`The points channel has been set to <#${channel.id}>!`)
}
});
client.on('message', async message => {
const { guild, channel } = message
const channelId = await SLSchema.find({channelId: channel.id})
if (message.channel.id = channelId) {
if (message.attachments.size > 0) {
message.react('🔼')
message.react('🔽')
} else {
message.delete()
}
}
})
client.on('messageReactionAdd', async (reaction, user) => {
const { guild, channel } = message
const channelId = await SLSchema.find({channelId: channel.id})
if (reaction.partial) await reaction.fetch()
if (reaction.message.partial) await reaction.message.fetch()
if (reaction.message.channel.id !== channelId) return;
if (user.id === client.user.id) return;
if (reaction.message.author.id === user.id) return reaction.users.remove(user)
if (reaction.emoji.name === "🔼") {
await LeaderboardSequence.findOneAndUpdate({ userid: reaction.message.author.id, guildID: reaction.message.guild.id }, { $inc: { points: 1 } }, { upsert: true , new: true , setDefaultsOnInsert: true })
} else if (reaction.emoji.name === "🔽") {
await LeaderboardSequence.findOneAndUpdate({ userid: reaction.message.author.id, guildID: reaction.message.guild.id }, { $inc: { points: -1 } }, { upsert: true , new: true , setDefaultsOnInsert: true})
}
});
client.on('messageReactionRemove', async (reaction, user) => {
const { guild, channel } = message
const channelId = await SLSchema.find({channelId: channel.id})
if (reaction.partial) await reaction.fetch()
if (reaction.message.partial) await reaction.message.fetch()
if (reaction.message.channel.id !== channelId) return;
if (reaction.message.author.id === user.id) return reaction.users.remove(user)
if (user.id === client.user.id) return;
if (reaction.emoji.name === "🔼") {
await LeaderboardSequence.findOneAndUpdate({ userid: reaction.message.author.id, guildID: reaction.message.guild.id }, { $inc: { points: -1 } }, { upsert: true , new: true , setDefaultsOnInsert: true })
} else if (reaction.emoji.name === "🔽") {
await LeaderboardSequence.findOneAndUpdate({ userid: reaction.message.author.id, guildID: reaction.message.guild.id }, { $inc: { points: 1 } }, { upsert: true , new: true , setDefaultsOnInsert: true})
}
});
client.on('message', async message => {
if (message.content === `${prefix}leaderboard`) {
const Users = await LeaderboardSequence.find({guildID: message.guild.id}).sort({ points: -1 })
const embedArray = []
for (var i = 0; i < Users.length % 10 + 1; i++) {
const leaderboard = new Discord.MessageEmbed()
.setTitle(`Here is ${message.guild}'s points leaderboard!`)
.setColor("RANDOM")
.setThumbnail("https://pbs.twimg.com/media/D7ShRPYXoAA-XXB.jpg")
let text = ""
for (var j = 0; j < 10; j++) {
if (!Users[ i * 10 + j ]) break;
text += `${i * 10 + j + 1}. <#${Users[ i * 10 + j ].userid}>: ${Users[ i * 10 + j ].points}\n`
}
leaderboard.setDescription(text)
.setFooter("By (username) and (username), for everyone with the magic of discord.js.")
.setTimestamp()
embedArray.push(leaderboard)
}
paginate(message, embedArray)
}
});
const reactions = ['◀️', '⏸️', '▶️']
async function paginate(message, embeds, options) {
const pageMsg = await message.channel.send({ embed: embeds[0] })
await pageMsg.react(reactions[0])
await pageMsg.react(reactions[1])
await pageMsg.react(reactions[2])
let pageIndex = 0;
let time = 30000;
const filter = (reaction, user) => {
return reactions.includes(reaction.emoji.name) && user.id === message.author.id;
};
if (options) {
if (options.time) time = options.time
}
const collector = pageMsg.createReactionCollector(filter, { time: time });
collector.on('collect', (reaction, user) => {
reaction.users.remove(user)
if (reaction.emoji.name === '▶️') {
if (pageIndex < embeds.length-1) {
pageIndex++
pageMsg.edit({ embed: embeds[pageIndex] })
} else {
pageIndex = 0
pageMsg.edit({ embed: embeds[pageIndex] })
}
} else if (reaction.emoji.name === '⏸️') {
collector.stop()
} else if (reaction.emoji.name === '◀️') {
if (pageIndex > 0) {
pageIndex--
pageMsg.edit({ embed: embeds[pageIndex] })
} else {
pageIndex = embeds.length-1
pageMsg.edit({ embed: embeds[pageIndex]})
}
}
});
collector.on('end', () => pageMsg.reactions.removeAll().catch(err => console.log(err)));
}``
}
In the question, I did not mention that I was also checking for the points channel through an if statement:
(const { guild, channel } = message
const channelId = await SLSchema.find({channelId: channel.id}))
But this does not work as well.
Here is the schema:
const { Schema, model } = require('mongoose')
// We are using this multiple times so define
// it in an object to clean up our code
const reqString = {
type: String,
required: true,
}
const SLSchema = Schema({
_id: reqString, // Guild ID
channelId: reqString,
})
module.exports = model('setLeaderboard', SLSchema)
In the first piece of code, I have pasted the entire script so you guys have an understanding of the thing I am trying to pull off here.

Bot doesn't edit role permissions for each channel

I'm trying to make an anti-spam and when the bot is supposed to edit the muted role's permission for each channel nothing happens.
So first I create the role
const mute_role = message.guild.roles.cache.find(r => r.name == "Muted");
if (!mute_role) {
try {
mute_role = await message.guild.roles.create({
data: {
name: "Muted",
color: "#000000",
permissions: []
}
})
Then i edit the role's permissions on all guild's channels
message.guild.channels.cache.forEach(async (channel, id) => {
await channel.updateOverwrite(mute_role,
{
SEND_MESSAGES: false,
ADD_REACTIONS: false,
}
);
});
} catch (e) {
console.log(e.stack);
}
}
And after doing this it should continue to the rest of the code but it seems to skip that part because it continues to the anti-spam and adds the role if spam is triggered
Here is the full code for the anti-spam
bot.on('message', async message => {
if (message.author.bot) return;
const mute_role = message.guild.roles.cache.find(r => r.name == "Muted");
if (!mute_role) {
try {
mute_role = await message.guild.roles.create({
data: {
name: "Muted",
color: "#000000",
permissions: []
}
})
message.guild.channels.cache.forEach(async (channel, id) => {
await channel.updateOverwrite(mute_role,
{
SEND_MESSAGES: false,
ADD_REACTIONS: false,
}
);
});
} catch (e) {
console.log(e.stack);
}
}
if (usersMap.has(message.author.id)) {
const userData = usersMap.get(message.author.id);
const { lastMessage, timer } = userData;
const difference = message.createdTimestamp - lastMessage.createdTimestamp;
let msgCount = userData.msgCount;
console.log(difference);
if (difference > DIFF) {
clearTimeout(timer);
console.log('Cleared timeout');
userData.msgCount = 1;
userData.lastMessage = message;
userData.timer = setTimeout(() => {
usersMap.delete(message.author.id);
console.log('Removed from RESET');
}, TIME);
usersMap.set(message.author.id, userData);
}
else {
msgCount++;
console.log(msgCount)
if (parseInt(msgCount) === LIMIT) {
message.member.roles.add(mute_role);
message.channel.send(`${message.author} has been muted for spamming`);
setTimeout(() => {
message.member.roles.remove(mute_role);
message.channel.send(`${message.author} has been unmuted`);
}, TIME);
}
else {
userData.msgCount = msgCount;
usersMap.set(message.author.id, userData);
}
}
}
else {
let fn = setTimeout(() => {
usersMap.delete(message.author.id);
console.log('Removed from map');
}, TIME);
usersMap.set(message.author.id, {
msgCount: 1,
lastMessage: message,
timer: fn
})
}
})
Okay so I just found out why it was not working
Instead of using
const mute_role = message.guild.roles.cache.find(r => r.name == "Muted");
I just had to use
let mute_role = message.guild.roles.cache.find(r => r.name == "Muted");
Now it works and overwrites the channels permissions

Discord.js YouTube Search and Play

I am trying to make discord bot that will play some music but I can't manage to make search command correctly ( Now I need to type command .f press enter and then put that what I want to search and I want it to just .f [what i want to search]) but doesn't know how to. I tried many guides but still nothing, also I would like to have that after searching and choosin what to I meant to play bot automatically join and play it (I made it buut in weird way and I know there is easier way but I am dumb for it.
TL;DR: Search command that will search and play with ".f [what to search]".
Whole code if it wil help:
const { Client } = require("discord.js");
const config = require('./config.json')
const Discord = require("discord.js");
const ytdl = require('ytdl-core');
const search = require("youtube-search")
const opts = {
maxResults: 25,
key: config.YOUTUBE_API,
type: 'video'
}
const queue = new Map();
const client = new Client({
disableEveryone: true
});
client.on("ready", () => {
console.log(`ŻYJE I JAM JEST ${client.user.username} `);
});
client.on("message", async message => {
console.log(`${message.author.username} mówi: ${message.content}`)
});
client.on("message", async message => {
if (!message.content.startsWith('.')) return;
const serverQueue = queue.get(message.guild.id);
if (message.content.startsWith(`.p`, '.play', '.pla', '.pl')) {
execute(message, serverQueue);
return;
} else if (message.content.startsWith(`.s`, '.skip', '.sk', '.ski')) {
skip(message, serverQueue);
return;
} else if (message.content.startsWith(`.l`, '.leave', '.le', '.lea', '.leav')) {
stop(message, serverQueue);
return;
};
if (message.content.toLowerCase() === '.f') {
let embed = new Discord.MessageEmbed()
.setColor("#00FE0C")
.setDescription("Czego szukasz? Opowiedz mi dokładniej.")
.setTitle("Wyszukiwarka")
.setThumbnail('https://i.imgur.com/vs6ulWc.gif')
let embedMsg = await message.channel.send(embed);
let filter = m => m.author.id === message.author.id;
let query = await message.channel.awaitMessages(filter, { max: 1});
let results = await search(query.first().content, opts).catch(err => console.log(err))
if(results) {
let youtubeResults = results.results;
let i =0;
let titles = youtubeResults.map(result => {
i++;
return i + ") " + result.title;
});
console.log(titles);
message.channel.send({
embed : {
title: "Wybieraj mordo",
description: titles.join("\n")
}
}).catch(err => console.log(err));
filter = m => (m.author.id === message.author.id) && m.content >= 1 && m.content <= youtubeResults.length;
let collected = await message.channel.awaitMessages(filter, { max: 1 });
let selected = youtubeResults[collected.first().content - 1];
embed = new Discord.MessageEmbed()
.setColor("#00FE0C")
.setTitle(`${selected.title}`)
.setURL(`${selected.link}`)
.setDescription(`${selected.description}`)
.setThumbnail(`${selected.thumbnails.default.url}`);
message.channel.send(embed)
if (message.member.voice.channel) {
const connection = await message.member.voice.channel.join();
await message.channel.send(`.p ${selected.link}`).then(d_msg => { d_msg.delete({ timeout: 1500 })})
}
};
};
});
async function execute(message, serverQueue) {
const args = message.content.split(" ");
const voiceChannel = message.member.voice.channel;
if (!voiceChannel)
return message.channel.send(
"No wbij Mordunio na kanał najpierw!"
);
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has("CONNECT") || !permissions.has("SPEAK")) {
return message.channel.send(
"Dawaj klucze do kantorka to wbije!"
);
}
const songInfo = await ytdl.getInfo(args[1]);
const song = {
title: songInfo.title,
url: songInfo.video_url
};
if (!serverQueue) {
const queueContruct = {
textChannel: message.channel,
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: 5,
playing: true
};
queue.set(message.guild.id, queueContruct);
queueContruct.songs.push(song);
try {
var connection = await voiceChannel.join();
queueContruct.connection = connection;
play(message.guild, queueContruct.songs[0]);
} catch (err) {
console.log(err);
queue.delete(message.guild.id);
return message.channel.send(err);
}
} else {
serverQueue.songs.push(song);
return message.channel.send(`**${song.title}** został do kolejeczki dodany Byku!`);
}
}
function skip(message, serverQueue) {
if (!message.member.voice.channel)
return message.channel.send(
"Nie zatrzymasz mnie! Ciebie tu nie ma!"
);
if (!serverQueue)
return message.channel.send("A co miałabym pominąć");
serverQueue.connection.dispatcher.end();
}
function stop(message, serverQueue) {
if (!message.member.voice.channel)
return message.channel.send(
"Musisz tu byyyyć byyyyyku!!"
);
serverQueue.songs = [];
serverQueue.connection.dispatcher.end();
}
function play(guild, song, message) {
const serverQueue = queue.get(guild.id);
if (!song) {
serverQueue.voiceChannel.leave();
queue.delete(guild.id)
return;
}
const dispatcher = serverQueue.connection
.play(ytdl(song.url))
.on("finish", () => {
serverQueue.songs.shift();
play(guild, serverQueue.songs[0]);
})
.on("error", error => console.error(error));
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
serverQueue.textChannel.send(`Gram: **${song.title}**`);
};
client.login(config.TOKEN);

Categories