Get user to set role ID - discord

Im trying to setup a system where the user can change the role ID for staff but every time i restart my bot the ID resets back. Here is my code:
this is estaff.js
const roles = require("./roles");
module.exports = {
name: "estaff",
callback: ({ message, args }) => {
if (args.length === 0)
message.channel.send(`Current estaff role is <#&${roles.EstaffRole}>`);
else {
roles.EstaffRole = args[0];
message.channel.send("Successfully changed estaff role");
}
},
};
this is the roles.js file:
const roles = {
HstaffRole: "956109121550168114",
GstaffRole: "956112990116134953",
EstaffRole: "932558453203943434",
};
module.exports = roles;

I think you are misunderstanding how data is stored in this case.
This is not permanent storage, for a problem like this then you would require a database/storing system.
To help you understand, what you currently are doing is:
const roles = require("./roles");
This will get you a reference to the array in roles.js.
Assuming the call has the necessary arguments, you then
roles.EstaffRole = args[0];
This is going to change the array in roles, but not the files in roles.js.
Perhaps you could run this while looking at your roles.js and realise that you are not really changing anything, it will only work as long as your server/program is running.

Related

Discord.JS - How to get user ID from username?

can someone please help me to retrieve username from user ID and send a message to the chat with that ID?
if (message.content.startsWith(prefix)) {
const [CMD_NAME, ...args] = message.content
.trim()
.substring(prefix.length)
.split(/\s+/);
if (CMD_NAME === "getid") {
const getid1 = new MessageEmbed()
.setDescription("❗️ | Please tag the member to retrieve the ID!")
.setColor(10181046);
if (args.length === 0) return message.reply(getid1);
const username = client.guilds.cache.get('<GUILD ID>');
const userid = client.users.cache.find(username => username.tag === 'Someone#1234').id
message.channel.send(`${username} id is ${userid}`);
}
}
});
When I type the command "d!getid #Username", it shows me this error:
C:\Users\USER\Desktop\DiscordBotas\index.js:152 const userid = client.users.cache.find(username => username.tag === 'Someone#1234').id TypeError: Cannot read property 'id' of undefined at Client. (C:\Users\USER\Desktop\DiscordBotas\index.js:152:90)
You are creating a lambda of a variable that you just defined above the actual lambda, this could probably mess with your code.
The const username = client.guilds.cache.get('<GUILD ID>'); is wrong.
The fetching of the userId should probably work if you fix the line above it.
You are trying to get the user the wrong way. Firstly, why are you trying to match a user's tag with a guild? Maybe you think guild.cache has users? Well actually, this is client.guilds.cache, which only has guilds in it, and it returns a guild, not a user. Secondly, to get a user, you can try this method:
const user = client.users.cache.find(u => u.tag === 'SomeUser#0000')
console.log(user.id);
Below is code to get user by ID, but it probably won’t help with this, considering you would already have access to the ID
const user = client.users.cache.get("<UserID>");
console.log(user);
Also, you should add code to see if user isn’t found (client can’t find user with the condition). Here is some code to check that:
//... the find user code I put
if(!user) return message.reply('User could not be found');
message.channel.send(user.id);

Guild Members TImeout: Members didn't arrive in time

So I have this command that shows the riches users in a server this command worked yesterday however recently it has stopped working.
const { MessageEmbed } = require("discord.js");
const { stripIndents } = require("common-tags");
const { prefix } = require("../../botconfig.json");
const db = require('quick.db')
let bal = require('../../database/balance');
let rep = require('../../database/rep');
let work = require('../../database/works');
module.exports = {
config:{
name: "rich",
aliases: ["r"],
category: "currency",
description: "Tells who is rich",
usage: ""
},
run: async (client, message, args) => {
// Get all members of the server before doing anything
message.guild.members.fetch().then(guildMembers => {
let board = [];
for (let key of Object.keys(bal)) {
// Checks if the collection of GuildMembers contains the key.
if (guildMembers.has(key)) {
let value = Object.assign({user: guildMembers.get(key).user}, bal[key]);
board.push(value);
}
}
const emojis = [':first_place:', ':second_place:', ':third_place:', ':small_blue_diamond:', ':small_blue_diamond:']
board = board.sort((a,b) => b.balance-a.balance).splice(0, 5);
let top = board.map((x, i) => `${emojis[i]} **${x.balance.toLocaleString()}** - ${x.user.tag}`).join('\n');
let embed = new MessageEmbed()
.setColor("RANDOM")
.addField(`Richest users in **${message.guild.name}**`, `${top}`)
.setFooter('Switch Version 1.1');
return message.channel.send(embed);
}).catch(console.error)
}
}
The error code when the !rich command is used is as follows:
Guild_Members_Timeout: Members didn't arrive in time
I don't know if this is an issue within the bot or if it is an issue with discord.
Okay I have found the answer to my own problem it seems I needed to add intents to my discord bot to fetch the members.
All I did was add this line of code and it worked.
const intents = new Intents([
Intents.NON_PRIVILEGED, // include all non-privileged intents, would be better to specify which ones you actually need
"GUILD_MEMBERS", // lets you request guild members (i.e. fixes the issue)
]);
const client = new Client({ ws: { intents } });
None of my discord.js guildmember events are emitting, my user caches are basically empty, and my functions are timing out? . In this post it is explained in great detail and that helped me out a lot.TLDR:go to discord developer portal on your particular application ,go to bot , on bot permissions tick whatever is needed and copy the number.Then use this number as a constructor parameter for new Discord.Intents('insert the number here').This worked for me.

Firebase onDisconnect not deleting user name on disconnection

Perhaps I am mis-using onDisonnect(), but I looked at the example code on the firebase.blog and am doing my best.
When a user submits a user name, I call the code below, which adds the username to a firebase db. Then on disconnection, I want the username to be deleted from the db. This would mean that the db would only show users that are connected to the app at that moment in time.
I am doing it this way so I can then call the data and then map through the array to display currently logged-in users.
I have made two attempts in deleting the name, which you can see in the code below under con.onDisconnect().remove();, neither of which work the way I need. That said, if I log in once again from the same computer, the first user name replaces the second user name!
Here is my code
setName = e => {
e.preventDefault()
let name = this.state.name;
let connectedRef = firebase.database().ref('.info/connected');
connectedRef.on('value', function (snap) {
if (snap.val() === true) {
// Connected
let con = myConnectionsRef.push();
myConnectionsRef.set({
name
})
// On disconnect
con.onDisconnect().remove();
myConnectionsRef.orderByChild('name').equalTo(name).once('child_added', function (snapshot) {
snapshot.ref.remove();
// var nameRef = firebase.database().ref('users/'+name);
// nameRef.remove()
})
}
});
Where am I going wrong? Is there a better way to use onDisconnect? From the example on the fb forum, it isn't clear where I would put that block of code, hence why I am attempting to do it this way.
Thanks.
If I understand correctly what is your goal, you don't need to do
myConnectionsRef.orderByChild('name').equalTo(name).once('child_added', function (snapshot) {
snapshot.ref.remove();
// var nameRef = firebase.database().ref('users/'+name);
// nameRef.remove()
})
as the onDisconnect().remove() call will take care of that.
Also, as explained in the blog article you refer to (as well as shown in the doc):
The onDisconnect() call shall be before the call to set() itself. This is to
avoid a race condition where you set the user's presence to true and
the client disconnects before the onDisconnect() operation takes
effect, leaving a ghost user.
So the following code should do the trick:
setName = e => {
e.preventDefault()
let name = this.state.name;
const connectedRef = firebase.database().ref('.info/connected');
const usersRef = firebase.database().ref('users');
connectedRef.on('value', function (snap) {
if (snap.val() === true) {
// Connected
const con = usersRef.child(name); //Here we define a Reference
// When I disconnect, remove the data at the Database location corresponding to the Reference defined above
con.onDisconnect().remove();
// Add this name to the list of users
con.set(true); //Here we write data (true) to the Database location corresponding to the Reference defined above
}
});
The users node will display the list of connected users by name, as follows:
- users
- James: true
- Renaud: true

Saving roles from mentioned user

I am trying to make a tempmute command, I followed a tutorial online which worked... But my own server has users with multiple roles, and these roles allow them to talk even when they receive the "muted" role.
Is there any way to save all the roles from a mentioned user and then to remove and add those roles?
I already tried to make a new let variable
let roleHistory = tomute.member.roles;
and then adding and removing them with:
await(tomute.removerole(roleHistory));
tomute.addRole(roleHistory);
But that didn't work
module.exports.run = async (bot, message, args) => {
let tomute = message.guild.member(message.mentions.users.first() || message.guild.members.get(args[0]));
if(!tomute) return message.reply("Couldn't find user.");
if(tomute.hasPermission("MANAGE_MESSAGES")) return message.reply("Can't mute them!");
let muterole = message.guild.roles.find(`name`, "muted");
if(!muterole){
try{
muterole = await message.guild.createRole({
name: "muted",
color: "#000000",
permissions:[]
})
message.guild.channels.forEach(async (channel, id) => {
await channel.overwritePermissions(muterole, {
SEND_MESSAGES: false,
ADD_REACTIONS: false
});
});
}catch(e){
console.log(e.stack);
}
}
let mutetime = args[1];
if(!mutetime) return message.reply("You didn't specify a time!");
await(tomute.addRole(muterole.id));
message.reply(`<#${tomute.id}> has been muted for ${ms(ms(mutetime))}`);
setTimeout(function(){
tomute.removeRole(muterole.id);
message.channel.send(`<#${tomute.id}> has been unmuted!`);
}, ms(mutetime));
}
I want the bot to take the roles away, tempmute the user and giving the roles back after the Timeout.
Your attempt is on the right track, but you missed a small detail. A Guild Member has a method addRole and removeRole which you used. However, these methods are meant for adding/removing a single role.
When you first fetch the user roles with let roleHistory = tomute.member.roles;, it returns a Collection of roles. If you then attempt to use removeRole(roleHistory) it attempts to remove a single role equal to the complete collection (which doesn't exist obviously).
To make it work, you need the methods addRoles and removeRoles which adds/removes an entire collection. So your code would be:
let roleHistory = tomute.roles;
// Removing all the roles
await(tomute.removeRoles(roleHistory));
// Adding all the roles
tomute.addRoles(roleHistory);
P.s. Since your tomute variable is already a user you need to change your code to fetch the roles from let roleHistory = tomute.member.roles; to let roleHistory = tomute.roles;

Discord.js some GuildMemeber functions don't work or?

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.

Resources