I followed some tutorials and got some help, but no matter what I try it keeps showing an error with the playFile. The bot can also play music but the music (through a link) part works fine. So how would I play an audio file that's in the root folder and only when someone joins the voice channel?
bot.on('voiceStateUpdate', (oldMember, newMember) => {
// Here I'm storing the IDs of their voice channels, if available
let oldChannel = oldMember.voiceChannel ? oldMember.voiceChannel.id : null;
let newChannel = newMember.voiceChannel ? newMember.voiceChannel.id : null;
if (oldChannel === newChannel) return; // If there has been no change, exit
// Here I'm getting the bot's channel (bot.voiceChannel does not exist)
let botMember = oldMember.guild.member(bot.user),
botChannel = botMember ? botMember.voiceChannel.id : null;
var server = servers[botMember.guild.id];
// Here I'm getting the channel, just replace VVV this VVV with the channel's ID
let textChannel = oldMember.guild.channels.get('438025505615249408');
if (!textChannel) throw new Error("That channel does not exist.");
// Here I don't need to check if they're the same, since it would've exit before
if (newChannel === botChannel) {
// console.log("A user joined.");
server.dispatcher = botMember.voiceConnection.playFile('./audiofile.mp3');
textChannel.send(newMember.displayName + " joined.");
} else if (oldChannel === botChannel) {
// console.log("A user left.");
textChannel.send(newMember.displayName + " left.");
}
});
Side note: you're using GuildMember.voiceConnection, but that property does not exist. Look a the docs for GuildMember.
The docs for VoiceConnection.playFile() say that the file argument has to be an absolute path (like C:/yourfolder/audio.mp3). To convert a relative path (./audio.mp3) to an absolute one, you need to join the directory (stored in the global variable __dirname) and the relative:
let conn = bot.voiceConnections.get(newMember.guild.id);
if (!conn) throw new Error("The bot is not in a voiceChannel, fix your code.");
let path = __dirname + '/audiofile.mp3';
conn.playFile(path);
Alternatively, you can use the path module (docs).
let path = require('path').join(__dirname, './audiofile.mp3');
conn.playFile(path);
Related
So i need a bot that tracks another bot's status. like if its online it will say in a channel (with an embed) "The Bot Is Online" And The Same if it goes offline and whenever someone does !status {botname} it shows the uptime/downtime of the bot and 'last online' date
if someone can make it happen i will really appricate it!
also i found this github rebo but it dosen't work, it just says the bot is online and whenever i type !setup {channel} it turns off
The Link to the Repo: https://github.com/sujalgoel/discord-bot-status-checker
Also uh it can be any language, i don't really want to add anything else π
.
Again, Thanks!
First of all, you would need the privileged Presence intent, which you can enable in the Developer Portal.
Tracking the bot's status
In order to have this work, we have to listen to the presenceUpdate event in discord.js. This event emits whenever someone's presence (a.k.a. status) updates.
Add this in your index.js file, or an event handler file:
// put this with your other imports (and esm equivalent if necessary)
const { MessageEmbed } = require("discord.js");
client.on("presenceUpdate", async (oldPresence, newPresence) => {
// check if the member is the bot we're looking for, if not, return
if (newPresence.member !== "your other bot id here") return;
// check if the status (online, idle, dnd, offline) updated, if not, return
if (oldPresence?.status === newPresence.status) return;
// fetch the channel that we're sending a message in
const channel = await client.channels.fetch("your updating channel id here");
// create the embed
const embed = new MessageEmbed()
.setTitle(`${newPresence.member.displayName}'s status updated!`)
.addField("Old status", oldPresence?.status ?? "offline")
.addField("New status", newPresence.status ?? "offline");
channel.send({ embeds: [embed] });
});
Now, whenever we update the targeted bot's status (online, idle, dnd, offline), it should send the embed we created!
!status command
This one will be a bit harder. If you don't have or want to use a database, we will need to store it in a Collection. The important thing about a Collection is that it resets whenever your bot updates, meaning that even if your bot restarts, everything in that Collection is gone. Collections, rather than just a variable, allows you to store more than one bot's value if you need it in the future.
However, because I don't know what you want or what database you're using, we're going to use Collections.
In your index.js file from before:
// put this with your other imports (and esm equivalent if necessary)
const { Collection, MessageEmbed } = require("discord.js");
// create a collection to store our status data
const client.statusCollection = new Collection();
client.statusCollection.set("your other bot id here", Date.now());
client.on("presenceUpdate", async (oldPresence, newPresence) => {
// check if the member is the bot we're looking for, if not, return
if (newPresence.member !== "your other bot id here") return;
// check if the status (online, idle, dnd, offline) updated, if not, return
if (oldPresence?.status === newPresence.status) return;
// fetch the channel that we're sending a message in
const channel = await client.channels.fetch("your updating channel id here");
// create the embed
const embed = new MessageEmbed()
.setTitle(`${newPresence.member.displayName}'s status updated!`)
.addField("Old status", oldPresence?.status ?? "offline")
.addField("New status", newPresence.status ?? "offline");
channel.send({ embeds: [embed] });
// add the changes in our Collection if changed from/to offline
if ((oldPresence?.status === "offline" || !oldPresence) || (newPresence.status === "offline")) {
client.statusCollection.set("your other bot id here", Date.now());
}
});
Assuming that you already have a prefix command handler (not slash commands) and that the message, args (array of arguments separated by spaces), and client exists, put this in a command file, and make sure it's in an async/await context:
// put this at the top of the file
const { MessageEmbed } = require("discord.js");
const bot = await message.guild.members.fetch("your other bot id here");
const embed = new MessageEmbed()
.setTitle(`${bot.displayName}'s status`);
// if bot is currently offline
if ((bot.presence?.status === "offline") || (!bot.presence)) {
const lastOnline = client.statusCollection.get("your other bot id here");
embed.setDescription(`The bot is currently offline, it was last online at <t:${lastOnline / 1000}:F>`);
} else { // if bot is not currently offline
const uptime = client.statusCollection.get("your other bot id here");
embed.setDescription(`The bot is currently online, its uptime is ${uptime / 1000}`);
};
message.reply({ embeds: [embed] });
In no way is this the most perfect code, but, it does the trick and is a great starting point for you to add on. Some suggestions would be to add the tracker in an event handler rather than your index.js file, use a database rather than a local Collection, and of course, prettify the embed messages!
I'm working on semi-gacha bot command where you can pull characters and so on. I want to display the characters image after the user pulls and here is where I get stuck, it just doesn't display anything and I found what looked like the answer on here, but it didn't help, as I would get the same result and I don't get any errors, so I don't know what exactly is wrong. I have tried printing out the result of MessageAttachment first:
const attachment = new Discord.MessageAttachment('./chars/1.Jakku.png', '1.Jakku.png');
console.log(attachment);
and I get: undefined, anybody has any ideas of what am I doing wrong? And yes, I have discord.js library imported.
Relevant part of the code:
collector.on('collect', reaction => {
//new embd
const newEmbd = new Discord.MessageEmbed();
// gacha logic
if (reaction.emoji.name === 'β
') {
const values = Object.values(chars);
const randomChar = values[parseInt(Math.floor(Math.random()*values.length))];
const attachment = new Discord.MessageAttachment('./chars/1.Jakku.png', '1.Jakku.png');
const charData = randomChar.split('.');
newEmbd
.setTitle(`You pulled: ${charData[1]}!`)
.setColor('YELLOW')
.attachFiles(attachment)
.setImage(`attachment://1.Jakku.png`);
embdReact.edit(newEmbd);
pulled = true;
} else if (reaction.emoji.name === 'β') {
newEmbd
.setTitle('Time for gacha!')
.setColor('YELLOW')
.addFields(
{ name: 'Result:', value: 'You decided against pulling' }
);
embdReact.edit(newEmbd);
};
});
You need to use the correct syntax for attaching files as per this guide
const exampleEmbed = new Discord.MessageEmbed()
.setTitle('Some title')
.attachFiles(['./chars/1.Jakku.png'])
message.channel.send(exampleEmbed);
So, I need a way to forward a message sent in the bot's dm to a specific channel in my server.
this is the code that I got so far:
execute(message, args) {
if(message.channel.type == "dm"){
let cf = args.join(' ')
const cfAdm = message.guild.channels.cache.get('767082831205367809')
let embed = new discord.MessageEmbed()
.setTitle('**CONFISSΓO**')
.setDescription(cf)
.setColor('#000000')
const filter = (reaction, user) => ['π', 'π'].includes(reaction.emoji.name);
const reactOptions = {maxEmojis: 1};
cfAdm.send(embed)
.then(function (message) {
message.react('π')
.then(() => message.react('π'))
/**** start collecting reacts ****/
.then(() => message.awaitReactions(filter, reactOptions))
/**** collection finished! ****/
.then(collected => {
if (collected.first().emoji.name === 'π') {
const cfGnr = message.guild.channels.cache.get('766763882097672263')
cfGnr.send(embed)
}
})
});
}
else {
message.delete()
message.channel.send('Send me this in the dm so you can stay anon')
.then (message =>{
message.delete({timeout: 5000})
})
}
}
But for some reason that I can't seem to understand, it gives me this error:
TypeError: Cannot read property 'channels' of null
If anyone can help me, that would be greatly apreciated.
Thanks in advance and sorry for the bad english
The error here is that you are trying to call const cfAdm = message.guild.channels.cache.get('ID') on a message object from a Direct Message channel ( if(message.channel.type == "dm"){)
DMs don't have guilds, therefore message.guild is null and message.guild.channels does not exist.
You will need to first access the channel some other way. Luckily, Discord.js has a way to access all channels the bot can work with* (you don't need to muck around with guilds because all channels have unique IDs):
client.channels.fetch(ID) or client.channels.cache.get(ID)
(I have not tested this but it seems fairly straight forward)
*See the link for caveats that apply to bots in a large amount of servers.
Kind of new in the sphere of scripting bots, so looked up some tutorials and was trying to make a report command, when I write !report it says 'User not found', but when I write the full command ( !report #someone test) it doesn't send anything.
I have tried copying the code from GitHub but nothing helped, changed a lot of things around but still, no result.
//!report #ned this is the reason
let rUser = message.guild.member(message.mentions.users.first() || message.guild.members.get(args[1]));
if(!rUser) return message.channel.send("Couldn't find user.");
let rreason = args.join(" ").slice(22);
let reportEmbed = new Discord.RichEmbed()
.setDescription("Reports")
.setColor("#15f153")
.addField("Reported User", `${rUser} with ID: ${rUser.id}`)
.addField("Reported By", `${message.author} with ID: ${message.author.id}`)
.addField("Reported in", message.channel)
.addField("Reported at", message.createdAt)
.addField("Report reason", rreason);
let reportschannel = message.guild.channels.get("603857301392195585")
if(!reportschannel) return message.channel.send("Couldn't find reports channel.");
message.delete().catch(O_o=>{});
reportschannel.send(reportEmbed);
return;
}
There was no errors, nothing in the command prompt.
1. You forgot to set a title/author in your embed. I don't know if its needed but you should add something like this. Then you can remove .setDescription().
// [...]
let reportEmbed = new Discord.RichEmbed()
.setAuthor("Reports")
.setColor("#15f153")
// [...]
2. You can leave out the part after message.delete(), there is no .catch() needed.
3. Remove return; at the end. It's not needed either.
Also check if you are running this.
E.g. use debug messages. After almost every line a console.log("1"), console.log("2") etc. to check, where the code stops.
Example:
//!report #ned this is the reason
let rUser = message.guild.member(message.mentions.users.first() || message.guild.members.get(args[1]));
if(!rUser) return message.channel.send("Couldn't find user.");
console.log("1") // User exists
let rreason = args.join(" ").slice(22);
console.log("2") // No reason creating problems
let reportEmbed = new Discord.RichEmbed()
.setAuthor("Reports")
.setColor("#15f153")
.addField("Reported User", `${rUser} with ID: ${rUser.id}`)
.addField("Reported By", `${message.author} with ID: ${message.author.id}`)
.addField("Reported in", message.channel)
.addField("Reported at", message.createdAt)
.addField("Report reason", rreason);
let reportschannel = message.guild.channels.get("603857301392195585");
if(!reportschannel) return message.channel.send("Couldn't find reports channel.");
console.log("3") // Channel exists
message.delete();
console.log("4") // Message deleted
reportschannel.send(reportEmbed);
console.log("5") // Report message sent
Anyone knows what could be the issue that .kick() .setMute(true/false) or even setDeaf(true/false) in discord.js libary don't seem to work. Here is also a part of the code that doesn't do anything when it should but also doesn't throw any errors. Bot was invited with maximum privileges and also code block executes the command to steMute / setDeaf / kick. Any ideas of what might cause this or what should i try logging to find the issue? THANKS!
ar msgUserId = msg.author.id
var allUsers = []
var reset = true
bot.channels.forEach((channel, id) => {
if (reset){
channel.members.forEach((user, id) => {
allUsers.push(user)
if (id == msgUserId){
reset = false
}
})
if (reset){
allUsers = []
}
}
})
if (allUsers){
var number = Math.floor((Math.random() * allUsers.length))
allUsers[number].setDeaf(true)
allUsers[number].setMute(true)
} else {
var channel = msg.channel
channel.send("You must be in a voice channel with others for this to work!")
}
Channels in bot.channels are cached for the sole purpose of metadata which are instances of Channel, you need a guild context (aka. server ID) in order to acquire a TextChannel with which the operations you say can be done.