I'm making a bot that chats when user enters a voice channels.
I can get how to use #username like below,
//CODE1
bot.on('voiceStateUpdate', (oldMember, newMember) => {
let newUserChannel = newMember.voiceChannel
if (oldUserChannel === undefined && newUserChannel !== undefined) {
bot.channels.get('text channel ID').send('Hello here!'+ newMember);
}
returs like this.
Hello here! #toko
However, I want to use specific message for each user like "heyyy" to userA, "ciao" to userB so I want my code be like this.
//CODE2
if (newMembers ID = A) {
bot.channels.get('text channel ID').send('heyyy');
}else if(newMembers ID = B){
bot.channels.get('text channel ID').send('ciao');
}
I'm new to programming so I don't know how to write this in correct way and where to put CODE2. Please help...
If by newMembers ID you mean '#toko' as in the above code, then this:
bot.on('voiceStateUpdate', (oldMember, newMember) => {
let newUserChannel = newMember.voiceChannel
if (oldUserChannel === undefined && newUserChannel !== undefined) {
if (newMember == '#toko') {
bot.channels.get('text channel ID').send('heyyy');
}else if(newMember == '#samuel'){
bot.channels.get('text channel ID').send('ciao');
}
}
})
Of course the problem with this approach is knowing every new user's id and writing an if statement for each one.
Related
I've been getting an error along the lines of "Cannot read property 'name' of undefined" and the error traces back to this code
const roleName = message.guild.roles.cache.find(r => (r.name === args[1].toString()) || (r.id === args[1].toString().replace(/[^\w\s]/gi, '')));
What's going wrong here?
slightly larger peice of code
if (!message.member.hasPermission('MANAGE_ROLES')) return message.channel.send(`You do not have MANAGE_ROLES permission`)
try {
const user = message.mentions.users.first();
const member = message.guild.member(user);
const roleName = message.guild.roles.cache.find(r => (r.name === args[1].toString()) || (r.id === args[1].toString().replace(/[^\w\s]/gi, '')));
//after this i create a discord embed, give the member the role specified then send the embed.
} catch (err) {
console.log(err)
}
Add an Elvis operator:
const roleName = message.guild.roles.cache.find(r =>
(r?.name === args[1].toString())
|| (r?.id === args[1].toString().replace(/[^\w\s]/gi, ''))
);
Or do it the old way:
const roleName = message.guild.roles.cache.find(r =>
r
&& (r.name === args[1].toString())
|| (r.id === args[1].toString().replace(/[^\w\s]/gi, ''))
);
So you're getting this error because you're trying to access 'r.name' in your Array.find() method and some of the entries in the array appear to be 'undefined' or 'null'. I would first run an Array.filter(r => !!r) and then chain on the .find() method afterwards to make sure all your entries are not undefined/null.
how to fix this error
music.on('voiceStateUpdate',(lama, baru) => {
var state = null;
let Role = baru.roles.find((r) => ["IRON", "BRONZE"].includes(r.name));
const kategorikanal = '700743802574602260'
const channelid = '700743824346972231'
if(!lama.voiceChannel && !baru.voiceChannel) return;
if(!lama.voiceChannel && baru.voiceChannel) {state = "join"}
else if(lama.voiceChannel && !baru.voiceChannel) {state = "leave"}
else if(lama.voiceChannel.id !== baru.voiceChannel.id) {state = "move"}
else if(lama.voiceChannel.id == baru.voiceChannel.id) return;
console.log(state);
//!baru.member.roles.has(allowedRole)
if(baru.voiceChannelID === channelid || !baru.voiceChannelID === Role || Role !== null && Role !== '') {
console.log(baru.displayName + ' gabisabgo hrus ada rank ranked ');
// const Role = baru.guild.roles.get("724997095236304987");
baru.guild
.createChannel(`${Role.name} | ${baru.user.username}`,"voice")
.then(tempChannel => {
tempChannel.overwritePermissions(baru.guild.defaultRole.id, {
CONNECT: false,
})
tempChannel.overwritePermissions(Role.id, {
CONNECT: true
})
tempChannel.setParent(kategorikanal);
baru.setVoiceChannel(tempChannel.id);
tempChannel.setUserLimit("5");
})
.catch(console.error)
}
if(lama.voiceChannelID || !lama.voiceChannelID === Role || Role !== null && Role !== '') {
console.log(lama.displayName + ' gabisabgo hrus ada rank ranked ');
const voicelama = lama.guild.channels.get(lama.voiceChannelID);
let Role = baru.roles.find((r) => ["IRON", "BRONZE"].includes(r.name));
if(voicelama.name.startsWith(`${Role.name} | ${baru.user.username}`)){
let sawadikap = `**${baru.user.username}'s**` + " **Team**"
var koko = new Discord.RichEmbed()
.setColor("#FF4654")
.setThumbnail(`${baru.user.avatarURL}`)
.addField('**Good Game Well Played**',`${sawadikap}`)
.setFooter("#Valorant Indonesia Community." , 'https://i.imgur.com/yPWqxxu.png')
voicelama.delete()
.then(function() {
music.channels.get('725080861392896101').send(koko)
})
.catch(console.error);
}
}
})
ERROR VIEW
.createChannel(${Role.name} | ${baru.user.username},"voice")
^ TypeError: Cannot read property 'name' of null
Have you stepped through the code in debug mode? I recommend setting breakpoints, creating watches, and checking the value of the variables as you step through. If you don't feel comfortable doing so, can you please put in the following, and tell me what the console logs? :
console.log(Role)
console.log(Role.name)
Although Role is not null, The value of Role.name is null, meaning that it has no value assigned to it. That issue occurs here:
let Role = baru.roles.find((r) => ["IRON", "BRONZE"].includes(r.name));
So I see two possibilities:
No roles contain those names.
I thought that find should only result one result, but I can't seem to find good documentation of that method. Is it possible that both roles are found and a collection is returned? This would mean that there would be a collection of multiple roles, meaning that Role would not contain the data members that a Role object type would. This means that you would have to index one of the roles before using the name.
//
//if there isn't a matching role, then terminate the method.
if (Role == null)
{
return;
}
//if there are multiple roles that match the criterion, just use the first one.
//The alternative is that we could make it into a loop that handles it for all of them.
else if (Role instanceof Array)
{
if (Role.length == 0)
{
return;
}
Role = Role[0]
}
Add the above lines before calling baru.guild.createChannel.
So, i've been coding a discord bot, and i'm getting this error when trying to check if "mrole" has the property "app". I have no idea why this is not working.
I want it to read the team's id so i can sort out the json file like this:
let barney = message.guild.roles.find(r => r.name === "Barney")
let deadpool = message.guild.roles.find(r => r.name === "Deadpool")
let hulk = message.guild.roles.find(r => r.name === "Hulk")
let mario = message.guild.roles.find(r => r.name === "Mario")
let spiderman = message.guild.roles.find(r => r.name === "Spider-Man")
let umbreon = message.guild.roles.find(r => r.name === "Umbreon")
let app = message.guild.member(message.mentions.users.first());
let app2 = message.mentions.users.first().username
var mrole
if (app.roles.has(barney.id)){
mrole = barney.id
}
else if (app.roles.has(deadpool.id)){
mrole = deadpool.id
}
else if (app.roles.has(hulk.id)){
mrole = hulk.id
}
else if (app.roles.has(mario.id)){
mrole = mario.id
}
else if (app.roles.has(spiderman.id)){
mrole = spiderman.id
}
else if (app.roles.has(umbreon.id)){
mrole = umbreon.id
}
if(mrole = barney.id || deadpool.id || hulk.id || mario.id || spiderman.id || umbreon.id){
if (client.memberspoints.mrole[app.id].name != app2){
client.memberspoints [mrole] = {
[app2.id]: {
name: `${app2}`,
mpoints: `${+args[1]}`
}
}
message.channel.send(`${app} agora tem ${+args[1]} pontos`);
}
else{
let _mpoints = client.memberspoints.mrole[app.id].mpoints
var smpoints = +_mpoints + +args[1]
client.memberspoints [mrole] = {
[app.id]:{
name: `${app2}`,
mpoints: `${smpoints}`
}
}
message.channel.send(`${app} agora tem ${smpoints} pontos`);
}
fs.writeFile ('./memberspoints.json', JSON.stringify (client.memberspoints, null, 2), err => {
if (err) throw err;
console.log('Salvo');
});
Here is the error i'm geting:
if (client.memberspoints.mrole[app.id].name != app2){
^
TypeError: Cannot read property 'app.id' of undefined
I basically want it to check if the "mrole" already has the name of the person on it, so i an sort it out by team and by name. Any ideas?
To check if an object has a certain property, you should use the object.hasOwnProperty method:
The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it).
so, it would go like this:
if(mrole.hasOwnProperty('app')) { // do stuff }
I recently learned that in this could potentially be a security problem, so its better to use it like this: if( Object.prototype.hasOwnProperty.call(mrole, 'app'). ( you can read more here ).
now, the probelm might be something else entirely- I noticed that in the line
if(mrole = barney.id || deadpool.id || hulk.id || mario.id || spiderman.id || umbreon.id), you ASSIGN to the mrole, and not comparing! should be if(mrole == ...
I am currently making a discord bot using discord.js and i am trying to make a menu command so when a user types [prefix]menu it sends a picture of the menu
i can do that easily but i am trying to make it multipaged, i know i could just make a menu1, menu2 and menu3 command but id like to have a command saying nextpage and previouspage this is what i have so far but it doesn't work and there is no errors
if (command === "menu") {
output()
message.channel.send({file: './images/menu1.png'});
curPage = 1;
}
if (command === "next page") {
output()
curPage++;
if(curPage >= 3) {
output()
curPage = 3; message.channel.send("You're on the last page!");
}
} else if (command === "previous page") {
output()
curPage--;
if(curPage <= 0) {
output()
curPage = 1; message.channel.send("You're on the first page!");
}
message.channel.send({file: `./images/menu${curPage}.png`});
}
Use a ReactionCollector instead.
A collect event would be emitted when a user reacts to the targeted message.
Example:
const collector = message.createReactionCollector((reaction, user) =>
user.id === message.author.id &&
reaction.emoji.name === "◀" ||
reaction.emoji.name === "▶" ||
reaction.emoji.name === "❌"
).once("collect", reaction => {
const chosen = reaction.emoji.name;
if(chosen === "◀"){
// Prev page
}else if(chosen === "▶"){
// Next page
}else{
// Stop navigating pages
}
collector.stop();
});
Docs: Message, ReactionCollector, Reaction, User
I think the best way to achieve this, would be with .awaitMessages?
https://discord.js.org/#/docs/main/stable/class/TextChannel?scrollTo=awaitMessages
It might be worth trying something along these lines, however I'm not 100% sure about how to await multiple times for paging back and forth... I'd be interested in seeing someone elses solution for this.
For example:
if (command === "menu") {
message.channel.send({file: './images/menu1.png'});
.then(() => {
message.channel.awaitMessages(response => response.content === 'next', {
max: 1,
time: 30000,
errors: ['time'],
})
.then((collected) => {
message.channel.send({file: './images/menu2.png'});
})
.catch(() => {
// Do something with error
});
});
}
I'm making a discord bot and there's a command where I want only admins to be able to use, but when I try to check if the user has a role, it says that it can't read the property 'roles' of undefined. Here's the code I'm using
if(command === '!cmd') {
if(message.author.id != ownerid || !message.member.roles.has(370565560972476437)) {
messagesend("YOU ARE NOT ALLOWED TO USE THIS COMMAND\nTHIS IS YOUR ONLY WARNING")
console.log(message.author);
} else if(message.author.id === ownerid || message.member.roles.has("370565560972476437") || message.member.roles.some(r=>["admin"].includes(r.name))) {
var messageArrray = messageArray.slice(1,messageArray.length)
let evalStr = ""
for(let element of messageArrray){
evalStr += element + " "
}
console.log(evalStr);
eval(evalStr)
message.delete()
}
}
if (message.guild.members.get(message.author.id).roles.exists('name','ROLENAME'){
///Code here
}
Thats all.