discord.js - Bot sending messages twice - discord.js

My discord bot keeps sending messages twice, as shown in this image.
Here's the simplified code for index.js:
const { prefix, token, giphyToken } = require('./config.json');
const fs = require('fs')
const Discord = require('discord.js');
const client = new Discord.Client();
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
var GphApiClient = require('giphy-js-sdk-core')
giphy = GphApiClient(giphyToken)
client.once('ready', () => {
console.log('Ready!');
});
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
client.commands.set(command.name, command);
}
client.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if (!client.commands.has(command)) return;
try {
client.commands.get(command).execute(message, args);
} catch (error) {
console.error(error);
message.reply('there was an error trying to execute that command!');
}
})
client.login(token);
I even tried changing the token multiple times and I killed the terminal to get rid of multiple instances, but nothing prevailed.
What can I do to fix this?

This has happened to me before. How I fixed it is to regenerate the discord token. There was 2 things happening in the background.

If this still happens after to regenerating the token, try using client.destroy() on the code, or killing the exiting process by using cmd+Z in your terminal.
If it is still happening after that, just restart your computer. The most likely issue is that your application has runs twice behind.

I actually figured out what was happening here, it was an issue with pm2.
Long story short, don't run pm2 and node . at the same time, that was what caused this issue.

The only thing I did was close and re-open the text editor.

Related

How can a bot read embed messages sent by another bot and post a message if it contains a specific content?

I'm trying to code a Discord bot that would read embed messages sent by another bot and ping a specific role if the embed contains '(FREE)' in the title, as displayed here:
https://i.stack.imgur.com/kPsR1.png
Unfortunately, my code produces nothing. I don't run into any error, the bot simply doesn't post a message when conditions are matched to do so — yet it is online and has the permissions to post messages in the channel.
Any help would be really appreciated. I went through all the questions related to this topic on SO, but I couldn't find a working solution to my issue. I'd like to mention that I'm a beginner in JS.
Thank you so much.
const Discord = require('discord.js');
const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES", "GUILD_WEBHOOKS"] })
client.on('ready', () => {
console.log(`Logged in...`);
});
client.on('messageCreate', (message) => {
if (message.embeds) {
const embed = message.embeds[0]
if (embed.title === '(FREE)') {
return message.channel.send('#Free mint')
}
}
})
Edit: I believe my question is different from the one suggested in the comment as I'm looking for specific content in the embed.
I managed to make the bot work with the following code, thanks #Gavin for suggesting it:
const Discord = require('discord.js');
const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES", "GUILD_WEBHOOKS"] })
client.on('ready', () => {
console.log(`Logged in...`);
});
client.on('messageCreate', message => {
for (let embed of message.embeds) {
if (embed.title.includes('FREE')) {
return message.channel.send("<#&" + roleId + ">")
}
}
});

"message.member.voice" returning undefined even when I'm in a voice channel - discord.js

I'm trying to make my discord bot play music for my discord server (in light of groovy shutting down).
But when I tried to get it to join using message.members.voice.join() it always returns undefined, even when I'm in a discord voice channel. I've left and rejoined the call, and restarted the bot, but nothing has worked.
const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');
module.exports = {
name: 'play',
description: 'Joins and plays a video from youtube',
async execute(message, args) {
const { voiceChannel } = message.member.voice;
if (!voiceChannel) return message.channel.send('Join a Voice-Channel to use this command');
const permissions = voiceChannel.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');
if (!args.length) return message.channel.send('You need to send the second argument!');
const connection = await voiceChannel.join();
const videoFinder = async (query) => {
const videoResult = await ytSearch(query);
return (videoResult.videos.length > 1) ? videoResult.videos[0] : null;
}
const video = await videoFinder(args.join(' '));
if (video) {
const stream = ytdl(video.url, { filter: 'audioonly' })
connection.play(stream, { seek: 0, volume: 1 });
}
}
}
You need to use #discordjs/voice package for discord.js v13.
const { joinVoiceChannel } = require('#discordjs/voice')
And join voice or stage channels with the joinVoiceChannel method
let connection = joinVoiceChannel({
...
})
You need to specify the options as shown in their documentation
Though I'm not sure about playing audio, there is a method joinVoiceChannel.subscribe() that takes AudioPlayer as parameter, which allows the player to play audio on the connection.
You could make an AudioPlayer by using createAudioPlayer(). But there is a method play in AudioPlayer, that takes AudioResource as parameter, which plays the resource in the player.
And to make AudioResource, use createAudioResource method, which takes input as parameter.
const {joinVoiceChannel, createAudioPlayer, createAudioResource} = require('#discordjs/voice')
let player = createAudioPlayer()
connection.subscribe(player)
let resource = createAudioResource('')
player.play(resource)
Though I'm still not sure about the value for the parameter, it could be URL or file paths, I haven't tested it out since I'm currently out
In discord.js version 12 you would need to get the GuildMember#voice state's VoiceChannel object they are connected to so you would have to use VoiceState#channel so you would to define your connection like so:
const connection = await message.member.voice.channel.join()

Why will messageReactionAdd event not work

this.on("messageReactionAdd", async (reaction, user) => {
if(reaction.emoji.name === "✔️") {
console.log("User reacted")
}
})
This is my code and at the moment it will not even run the event
this is defined as client.
My tips: Try if the ready or the message event works. If it doesn't, try removing the if statement in your code. If it still doesn't work try using the starter code from the discord.js guide which is something like this:
const Discord = require('discord.js');
const client = new Discord.Client();
client.on('messageReactionAdd', (reaction, user) => {
console.log('event works!');
});
client.login('your-token-here');
If it still doesn't work your bot is most likely not logging in to discord. In this case I'd suggest you to recheck if your bot's token is the right one.

Making discord.js send a message to channel on command

I am trying to make my bot send a message to a channel in all servers that it is in when updated. My idea is that I will trigger this manually whenever I update my bot. For example, I would like to have it send a message such as "Updated bot to version 2.03. Update log: (changes made in the update)". This is the code I currently have:
const Discord = require('discord.js');
const client = new Discord.Client();
var Long = require("long");
const getChannel = (guild) => {
// get "original" default channel
if(guild.channels.cache.has(guild.id))
return guild.channels.cache.get(guild.id)
const jimmyChannel = guild.channels.cache.find(channel => channel.name === "jimmybot");
if (jimmyChannel)
return jimmyChannel;
return guild.channels.cache
.filter(c => c.type === "text" &&
c.permissionsFor(guild.client.user).has("SEND_MESSAGES"))
.sort((a, b) => a.position - b.position ||
Long.fromString(a.id).sub(Long.fromString(b.id)).toNumber())
.first();
}
// I found this as an example but I'm not sure if it will work
client.on("guildMemberAdd", member => {
const channel = getChannel(member.guild);
channel.send(`text`);
});
client.login('token');
My question is how do I call this manually instead of it sending the message whenever a user joins the server?
If I'm understanding this properly...
Client is actually just a variation of a Node.js EventEmitter, as stated here.
This means that you can trigger the events of your own accord, and so here you could do your own 'custom' EventEmitter and trigger it of your own accord.
Ex code paired with message event emitter. I know that it's generally frowned upon to put an event emitter inside of another, but it was the only solution I could find.
const Discord = require('discord.js');
const client = new Discord.Client();
token = 'XXX'
client.once('ready', () => {
console.log('Fully functional and initialized!');
});
// Attach a listener function
client.on('test', console.log);
client.on('message', msg => {
if (msg.author.bot) return;
if (msg.content === 'emit event') {
// Emit the event
client.emit('test', 'This will be printed on the console');
}
})
client.login(token);

Ways to login to multiple bot accounts with one script?

The ways I've tried.
Loop through tokens, this is fine but not much room to customise what bot does what. Example having each bot type in a specific channel, with this I've realised the bots type in the same location right after each other.
const auth = require('./tokens.json')
const Discord = require('discord.js')
for (const token of auth.Tokens) {
const client = new Discord.Client()
client.on('ready', () => {
console.log('I am ready !')
console.log(client.user.id)
})
client.login(token)
}
Also by creating multiple instances of a discord.client
const Discord = require('discord.js');
const client1 = new Discord.Client();
const client2 = new Discord.Client();
ect...
client1.once('ready',() => {
})
client1.on('message', async(message) => {
})
client2.once('ready',() => {
})
client2.on('message', async(message) => {
})
client1.login(CONFIG.Token1);
client2.login(CONFIG.Token2);
I am just wondering if there is other ways of doing this, lets say I have 5-6 bots and I do the 2nd method the code will get quite long depending on what i want to add into it.
I did think about adding a loop something like this.
for(var i = 0; i < token.length; i++)
And having a channel id linked to a specific number as the i++ is increasing it. So each bot would get its own number and channel id, but I'm not sure if that's even a thing that would work or if it would be good enough to use.
Any suggestions would be greatly appreciated and thank you for reading.
I think your second method:
creating multiple instances of a discord.client
Would be the best way to do it.
The easiest way to give the bots specific channels is to change their discord permissions and physically assigning them the channels.
Another way could be something like:
client.channelID = <ID of channel you want the bot in>
client2.channelID = <ID of channel you want the bot in>
// ... code
client.on('message', message => {
if (message channel.id !== client.channelID) return;
// ...
I was able to run multiple bots from the same script using this code:
const auth = ['TOKEN1', 'TOKEN2']
const Discord = require('discord.js')
for (const token of auth) {
const client = new Discord.Client()
client.on('ready', () => {
console.log('I am ready !')
console.log(client.user.id)
});
client.on('message', (msg) => {
if (msg.content === '!ping') {msg.reply('pong!')}
});
client.login(token);
}

Resources