I use MongoDB as a storage adapter for keyv, After setting the prefix to ;, it again resets to !. according to me there is a error in the logic. Here is the cmd used in discord
https://cdn.discordapp.com/attachments/713041505719287818/902605670086508585/IMG_8303.png
const { Client, Intents, MessageEmbed, Collection } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS,Intents.FLAGS.GUILD_MESSAGES] });
const dotenv = require('dotenv');
const Keyv = require('keyv');
const keyv = new Keyv('mongodb://user:password#cluster0-shard-00-00.auifa.mongodb.net:27017,cluster0-shard-00-01.auifa.mongodb.net:27017,cluster0-shard-00-02.auifa.mongodb.net:27017/Discord?ssl=true&replicaSet=atlas-bs4dwb-shard-0&authSource=admin&retryWrites=true&w=majority', { collection: 'Discord' });
keyv.on('error', err => console.error('Keyv connection error:', err));
dotenv.config();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('messageCreate', async (msg) => {
if (msg.author.bot) return;
let number = msg.content.split(' ')[1];
if (msg.content === '!ping') {
msg.channel.send('ping!')
}
const prefixMap = await keyv.get('prefix');
const getGuildPrefix = async () => {
return prefixMap ?. [msg.guild.id] || "!"
}
// Sets the prefix to the current guild.
const setGuildPrefix = async (prefix) => {
prefixMap[msg.guild.id] = prefix;
await keyv.set('prefix', prefixMap);
}
let commandprefix = await getGuildPrefix();
// Get prefix command.
if ((msg.content === `${process.env.prefix}prefix`) || (msg.content === `${commandprefix}prefix`)) {
msg.channel.send(`Your server prefix is ${commandprefix}`)
}
// Change prefix command
if ((msg.content.startsWith(`${process.env.prefix}setprefix`)) || (msg.content.startsWith(`${commandPrefix}setprefix`))) {
const newPrefix = number;
if (newPrefix.length === 0) {
msg.channel.send(`Please enter a valid prefix`);
return;
}
await setGuildPrefix(newPrefix)
msg.channel.send(`Your server prefix is now '${newPrefix}'`);
}
})
client.login(process.env.token);
How this code is supposed to run is: If the code is run for the first time in the server, then the prefix is supposed to be ! as default, we can also change it to another prefix. The thing here is it shows that it changed the prefix but it didn't update the value in the database
Related
so this code below works fine but the problem is I can't run it in all servers that have my bot I used quick.db but It seem to work only in one sever since it takes the last variable or I might did a mistake. Is there any way to change from quick.db to mongoDB so it work for all servers.
I hope I explain the issue successfully.
Code: what I am trying to do in this code is the bot will send a random messages from json file to a specific text channel specified by user which works fine, but I think I have a problem with the database.
discord.js v12
hosting the bot throw Heroku
index.js file
require('events').EventEmitter.prototype._maxListeners = 30;
const Discord = require('discord.js')
const client = new Discord.Client()
const ytdl = require('ytdl-core');
const config = require('./config.json')
const mongo = require('./mongo')
const command = require('./command')
const loadCommands = require('./commands/load-commands')
const commandBase = require('./commands/command-base')
const { permission, permissionError } = require('./commands/command-base')
const cron = require('node-cron')
const zkrList = require('./zkr.json')
const logo =
'URL HERE'
const db = require(`quick.db`)
const prefix = "!"
let cid;
client.on('ready', async () => {
await mongo().then((mongoose) => {
try {
console.log('Connected to mongo!')
} finally {
mongoose.connection.close()
}
})
console.log(`${client.user.tag} is online`);
console.log(`${client.guilds.cache.size} Servers`);
console.log(`Server Names:\n[ ${client.guilds.cache.map(g => g.name).join(", \n ")} ]`);
loadCommands(client)
cid = client.guilds.cache.map(guild => { db.get(`${guild.id}_channel_`) });
cron.schedule('*/10 * * * * *', () => {
const zkrRandom = zkrList[Math.floor(Math.random() * zkrList.length)]
const zkrEmbed = new Discord.MessageEmbed()
.setDescription(zkrRandom)
.setAuthor('XX', logo)
.setColor('#447a88')
client.channels.cache.get(cid).send(zkrEmbed);
})
client.on("message", async message => {
if (message.author.bot) {
return
}
console.log(client.guilds.cache.map(guild => { db.get(`${guild.id}_channel_`) }))
if (!message.member.hasPermission('ADMINISTRATOR') && message.content.startsWith('XX')) return message.reply('YOU DONT HAVE A PERMISSION TO RUN THIS COMMAND.')
if (!message.content.startsWith(prefix)) return;
const args = message.content.slice(prefix.length).trim().split(/ +/g)
const cmd = args[0]
if (cmd === "s") {
let c_id = args[1]
if (!c_id) return message.reply("YOU NEED TO MENTION A TEXT CHANNEL/ID")
c_id = c_id.replace(/[<#>]/g, '')
const channelObject = message.guild.channels.cache.get(c_id);
try { if (channelObject.type === 'voice') return message.reply('YOU CANNOT SEND MESSAGES TO VOICE CHANNEL') } catch (err) { return message.reply('AN ERROR OCCURRED') }
if (client.channels.cache.get(c_id)) {
client.guilds.cache.map(guild => { db.set(`${guild.id}_channel_`, c_id) })
message.reply(`SENDING TO THIS CHANNEL ${message.guild.channels.cache.get(c_id)}`);
cid = db.get(client.guilds.cache.map(guild => { db.get(`${guild.id}_channel_`) }))
const zkrRandom = zkrList[Math.floor(Math.random() * zkrList.length)]
const zkrEmbed = new Discord.MessageEmbed()
.setDescription(zkrRandom)
.setAuthor('XX', logo)
.setColor('#447a88')
client.channels.cache.get(cid).send(zkrEmbed);
} else {
return message.reply("NOT A VALID CHANNEL")
}
}
})
})
client.login(config.token)
zkr.json file
[
"MESSAGE 1",
"MESSAGE 2",
"MESSAGE 3"
]
I am trying to make a system that makes a user enter a code(like a verification code sent to the dms) before doing the action. I am trying to understand how my code can wait for the code to be entered, and I came across the awaitMessages tag. I am trying to understand how I can use it properly in my code. Here is my code.
const Discord = require("discord.js");
const config = require("./config.json");
const { MessageAttachment, MessageEmbed } = require('discord.js');
const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES", "DIRECT_MESSAGES", "DIRECT_MESSAGE_REACTIONS", "DIRECT_MESSAGE_TYPING"], partials: ['CHANNEL',] })
const RichEmbed = require("discord.js");
const prefix = "!";
client.on("messageCreate", function(message) {
if (message.author.bot) return;
if (!message.content.startsWith(prefix)) return;
const commandBody = message.content.slice(prefix.length);
const args = commandBody.split(' ');
const command = args.shift().toLowerCase();
if (command === "news") {
if (message.channel.type == "DM") {
message.author.send(" ");
}
}
if (command === "help") {
message.author.send("The help desk is avaliable at this website: https://example.com/");
}
});
client.on("messageCreate", function(message) {
if (message.author.bot) return;
if (!message.content.startsWith(prefix)) return;
const commandBody = message.content.slice(prefix.length);
const args = commandBody.split(' ');
const command = args.shift().toLowerCase();
if (command === "ping") {
const timeTaken = Date.now() - message.createdTimestamp;
message.channel.send(`Pong! This message had a latency of ${timeTaken}ms.`);
}
if (command === "delete all messages") {
const timeTaken = Date.now() - message.createdTimestamp;
const code = Math.random(1,1000)
message.channel.send(`Executing command. Verification Required.`);
message.author.send(`Your code is the number ${code}.`)
message.channel.send(`Please confirm your code. The code has been sent to your dms. Confirm it in here.`)
message.channel.awaitMessage(code) {
message.channel.send('confirmed. Doing the action.')
}
}
});
client.login(config.BOT_TOKEN)
To wait for a response from the user, you can use a collector.
You can create a filter to see if the user sending the code is the same as the one who executed the command and if the code sent is correct
const filter = (msg) => msg.author.id === message.author.id && msg.content === code;
const collector = message.channel.createMessageCollector({
filter,
time: 60000,
});
collector.on('collect', (collectedMessage) => {
collector.stop('success');
message.channel.send('confirmed. Doing the action.')
});
collector.on('end', (collected, reason) => {
if (reason === 'success') return;
else message.channel.send('Timeout or error');
});
My Index.js is having a error. I can't understand why.
const { Client, Collection } = require("discord.js");
const { readdirSync } = require("fs");
const { join } = require("path");
const { TOKEN, PREFIX } = require("./util/Util");
const i18n = require("./util/i18n");
const { Intents, client } = require('discord.js');
client.login(TOKEN);
client.commands = new Collection();
client.prefix = PREFIX;
client.queue = new Map();
const cooldowns = new Collection();
const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
client.on("ready", () => {
console.log(`${client.user.username} ready!`);
client.user.setActivity(`with ${client.guilds.cache.size} servers`);
});
client.on("warn", (info) => console.log(info));
client.on("error", console.error);
const commandFiles = readdirSync(join(__dirname, "commands")).filter((file) => file.endsWith(".js"));
for (const file of commandFiles) {
const command = require(join(__dirname, "commands", `${file}`));
client.commands.set(command.name, command);
}
client.on("message", async (message) => {
if (message.author.bot) return;
if (!message.guild) return;
const prefixRegex = new RegExp(`^(<#!?${client.user.id}>|${escapeRegex(PREFIX)})\\s*`);
if (!prefixRegex.test(message.content)) return;
const [, matchedPrefix] = message.content.match(prefixRegex);
const args = message.content.slice(matchedPrefix.length).trim().split(/ +/);
const commandName = args.shift().toLowerCase();
const command =
client.commands.get(commandName) ||
client.commands.find((cmd) => cmd.aliases && cmd.aliases.includes(commandName));
if (!command) return;
if (!cooldowns.has(command.name)) {
cooldowns.set(command.name, new Collection());
}
const now = Date.now();
const timestamps = cooldowns.get(command.name);
const cooldownAmount = (command.cooldown || 1) * 1000;
if (timestamps.has(message.author.id)) {
const expirationTime = timestamps.get(message.author.id) + cooldownAmount;
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return message.reply(
i18n.__mf("common.cooldownMessage", { time: timeLeft.toFixed(1), name: command.name })
);
}
}
timestamps.set(message.author.id, now);
setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
try {
command.execute(message, args);
} catch (error) {
console.error(error);
message.reply(i18n.__("common.errorCommand")).catch(console.error);
}
});
client.login(TOKEN);
The import is called Client instead of client. So change your import and instantiate the client like so:
const { Intents, Client } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
You will have to set the intents according to your own use case, as per this answer.
You are calling client.login(TOKEN); two times, in the beginning and in the final of the code.
I started making a music bot for my discord server when i input command for playing song it returns that execute is not defined i tried to fix but i had no success. That's why I am asking here.
Note: I made event and command handler but that is not the problem since it was also not working before implementing it.
Here is my code from event that happens on message aka starting command:
module.exports = (client, Discord, message)=>{
const prefix = '-';
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split('/ +/');
const cmd = args.shift().toLowerCase();
const command = client.commands.get(cmd) || client.commands.find(a => a.aliases && a.aliases.includes(cmd));
//const ChannelName = message.channel.name;
try{
command.execute(args, cmd, client, Discord, message);
} catch(err){
message.reply("There was an error trying to execute this command!");
console.log(err);
}
}
And here is my code for play command:
const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');
const queue = new Map();
module.exports = {
name: 'play',
aliases: ['skip', 'stop'],
cooldown: 0,
description: 'Advanced music bot',
async execute(args, cmd, client, Discord, message){
const voice_channel = message.member.voice.channel;
if (!voice_channel) return message.channel.send('You need to be in a channel to execute this command!');
const permissions = voice_channel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT')) return message.channel.send('You dont have the correct permissins');
if (!permissions.has('SPEAK')) return message.channel.send('You dont have the correct permissins');
const server_queue = queue.get(message.guild.id);
if (cmd === 'play'){
if (!args.length) return message.channel.send('You need to send the second argument!');
let song = {};
if (ytdl.validateURL(args[0])) {
const song_info = await ytdl.getInfo(args[0]);
song = { title: song_info.videoDetails.title, url: song_info.videoDetails.video_url }
} else {
const video_finder = async (query) =>{
const video_result = await ytSearch(query);
return (video_result.videos.length > 1) ? video_result.videos[0] : null;
}
const video = await video_finder(args.join(' '));
if (video){
song = { title: video.title, url: video.url }
} else {
message.channel.send('Error finding video.');
}
}
if (!server_queue){
const queue_constructor = {
voice_channel: voice_channel,
text_channel: message.channel,
connection: null,
songs: []
}
queue.set(message.guild.id, queue_constructor);
queue_constructor.songs.push(song);
try {
const connection = await voice_channel.join();
queue_constructor.connection = connection;
video_player(message.guild, queue_constructor.songs[0]);
} catch (err) {
queue.delete(message.guild.id);
message.channel.send('There was an error connecting!');
throw err;
}
} else{
server_queue.songs.push(song);
return message.channel.send(`👍 **${song.title}** added to queue!`);
}
}
else if(cmd === 'skip') skip_song(message, server_queue);
else if(cmd === 'stop') stop_song(message, server_queue);
}
}
const video_player = async (guild, song) => {
const song_queue = queue.get(guild.id);
if (!song) {
song_queue.voice_channel.leave();
queue.delete(guild.id);
return;
}
const stream = ytdl(song.url, { filter: 'audioonly' });
song_queue.connection.play(stream, { seek: 0, volume: 0.5 })
.on('finish', () => {
song_queue.songs.shift();
video_player(guild, song_queue.songs[0]);
});
await song_queue.text_channel.send(`🎶 Now playing **${song.title}**`)
}
const skip_song = (message, server_queue) => {
if (!message.member.voice.channel) return message.channel.send('You need to be in a channel to execute this command!');
if(!server_queue){
return message.channel.send(`There are no songs in queue 😔`);
}
server_queue.connection.dispatcher.end();
}
const stop_song = (message, server_queue) => {
if (!message.member.voice.channel) return message.channel.send('You need to be in a channel to execute this command!');
server_queue.songs = [];
server_queue.connection.dispatcher.end();
}
I think that problem is in main part of code but I cant seem to find problem.
Here is code for command handling
const fs = require('fs');
module.exports = (client, Discord) =>{
const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js'));
for (const file of commandFiles){
const command = require(`../commands/${file}`);
if(command.name){
client.commands.set(command.name, command);
} else{
continue;
}
}
}
And here is my main file of the bot with commands collection
const Discord = require('discord.js');
const client = new Discord.Client();
client.once('ready', () => {
client.user.setStatus('online')
console.log('Bot is online!');
client.user.setActivity('Youtube',{
type:"LISTENING"
})
console.log('Servers:')
client.guilds.cache.forEach((guild) => {
console.log('-' + guild.name)
})
});
const fs = require('fs');
const message = require('./events/guild/message');
client.commands = new Discord.Collection();
client.events = new Discord.Collection();
['command_handler', 'event_handler'].forEach(handler =>{
require(`./handlers/${handler}`)(client, Discord);
})
Ok so I finally figured out how to code my fs events handler to use the events folder. now I just need to know the basic method for coding the evtns in their own files.
Here is what I have for now [starting with the ready.js file]. Is this correct and if not how do I code the event files properly?
module.exports = {
name: 'avatar',
description: 'Get the avatar URL of the tagged user(s), or your own avatar.',
execute(message) {
client.on("ready", () => {
client.user.setActivity(`on ${client.guilds.size} servers`);
console.log(`Ready to serve on ${client.guilds.size} servers, for ${client.users.size} users.`);
}
}};
This is my index.js file for reference:
const fs = require('fs');
const Discord = require('discord.js');
const client = new Discord.Client();
const { prefix, token } = require('./config.json');
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
client.commands.set(command.name, command);
}
fs.readdir('./events/', (err, files) => {
if (err) return console.error(err);
files.forEach(file => {
const eventFunction = require(`./events/${file}`);
if (eventFunction.disabled) return; //
const event = eventFunction.event || file.split('.')[0];
const emitter = (typeof eventFunction.emitter === 'string' ? client[eventFunction.emitter] : eventFunction.emitter) || client; /
const once = eventFunction.once;
try {
emitter[once ? 'once' : 'on'](event, (...args) => eventFunction.run(...args));
} catch (error) {
console.error(error.stack);
}
});
});
client.login(token);
The upper code block is not ready.js its avatar.js i think.