Sudo command (discord.js) - javascript

Im trying to make a sudo command but the user i mention in args 0's Profile picture wont show.
async execute(client, message, args) {
if (!message.member.hasPermission("MANAGE_WEBHOOKS")) {
return message.channel.send(`You don't have permission to execute this command.`)}
message.delete();
let user =
message.mentions.members.first() ||
message.guild.members.cache.get(args[0]) ||
message.member.id();
if (!user) return message.channel.send("Please provide a user!");
const webhook = await message.channel.createWebhook(user.displayName, {
avatar: user.user.displayAvatarURL(),
channel: message.channel.id
});
await webhook.send(args.slice(1).join(" ")).then(() => {
webhook.delete();
});
}

A couple of things:
Your declaration of user (let user =) is a bit misleading when you are fetching a member object from the cache. I would recommend changing it to member instead for coherency.
Smallketchup82 is correct. Because you are getting a member object you would need to use the .user attribute to get anything pertaining to the user portion (username, tag, discriminator, and avatar).
If you were to follow the above advice you could do something like:
avatar: member.user.avatarURL()
I'm not entirely sure of which method gets the user's avatar as I have only worked with discordjs v13. However, its most likely one of the two:
member.user.displayAvatarURL()
member.user.avatarURL()

Related

Delete Button/Component of a specifc message (discord.js)

I am now trying in vain to remove buttons from a bot message. I have created a command for this purpose. When executing it, it should at best remove a specific, the last or at least all buttons that are on a specific message.
I have tried various things, but in all attempts the buttons are not removed.
module.exports = {
category: 'Utilities',
description: 'Delete Buttons',
permissions: ['ADMINISTRATOR'],
callback: async ({ client, message }) => {
const channel = client.channels.cache.get('the channel id')
channel.messages.fetch('the message id').then(msg => msg.edit({components: []}));
console.log(msg)
}
}
When I try to do this, I get the following console error:
TypeError: Cannot read properties of undefined (reading 'messages')
When I try this, I neither get a console log, nor does the bot do anything ...
const { Client, Message } = require("discord.js");
module.exports = {
category: 'Utilities',
description: 'Delete Buttons',
permissions: ['ADMINISTRATOR'],
callback: async ({ client, message }) => {
client.on('ready', async () => {
const channel = client.channels.cache.get('the channel id')
channel.messages.fetch('the message id').then(msg => {
msg.edit({ components: [] })
});
},
)}
}
Maybe one of you knows a solution or an idea. :)
Thanks a lot!
When I try this, I neither get a console log, nor does the bot do anything
The second example does not do anything because you are creating a ready event handler on running your command. Meaning, it's waiting for the bot to once again be "ready", i.e. the state of having logged in to the API as it does on startup. But your bot is already ready, and will not become ready again until the next time it restarts, so nothing will happen.
As for the first example, the error you are getting suggests channel is undefined, meaning either:
A) You have the incorrect channel ID
- OR -
B) The specified channel is no longer in the channel cache
If you are 100% sure the ID is correct, we can assume the issue you are having is the latter (the channel not being in the cache). There are many ways to solve this, but one simple way is to simply fetch the channel similar to how you are trying to fetch the message. Here's an example:
const channel = await client.channels.fetch('the channel id');
const msg = await channel.messages.fetch('the message id');
msg.edit({components: []});
That should fix the issue. If it doesn't, then the issue is much more complicated and not enough information has been provided. Also note that in the above example, I swapped Promise syntax for async/await since you are using an async function anyways; I did this just to make this answer more readable, you can choose whichever format you prefer.

kick command is not working and getting an error when try kicking an admin, how do i fix it?

im adding moderation commands into my bot, but I dont want people to be able to kick admins, so i added some code, but it did not work well, when i do ,kick it tell me Please specify a member to kick, perfect, when i do ,kick #[user] it kicks the user, but when i try kicking an admin it gives me an error message saying Cannot read property 'has' of undefined here is the code
module.exports = {
name: 'kick',
description: '[DESCRIPTION]',
async execute(Client, message, args, Discord) {
const member = message.mentions.users.first();
if(message.member.permissions.has("ADMINISTRATOR") || message.member.permissions.has("KICK_MEMBERS") || Client.users.cache.find(u => u.tag === 'Mr Tophat#3864').id){
if(!member){
message.channel.send("Please specify a member to kick");
}
else if(member.permissions.has("ADMINISTRATOR")){
message.channel.send("You can't an admin");
}
else{
if(member){
const memberTarget = message.guild.members.cache.get(member.id);
memberTarget.kick();
message.channel.send("User has been kicked!");
}
}
}
}
}
You are getting this error because you are trying to access permissions of a user instead of a guildMember. Declare your member like this:
const member = message.mentions.members.first();
The difference is, that a user is the global discord user and a guildMember is the user on a specific server
Reference
What is the difference between a User and a GuildMember in discord.js?

Discord.js Ban Error when trying to use a variable

Im trying to make a bot and have it have a ban command. without a reason, the ban command works great. But once I give it a reason, it just stops working and gives me this error:
{"title":"Go Vote for the Server!","description":"I've just finished posting the server to top.gg, one of the largest server listing sites. Please go vote for the server [here](https://top.gg/servers/754062115123232938/vote) so that more people can learn about it. It would really help the server grow. ","color":10426392,"footer":{"text":"© The Red Door, 2020"}}
If you have any idea how to fix this it would be greatly appreciated. Here is my current code for banning users:
if (message.member.roles.cache.some(role => role.name === config.modRole)) {
// Looks for the mentioned user
const user = message.mentions.users.first();
if(user){
// Checks if the user mentioned is in the server
const member = message.guild.member(user);
if(member){
// Bans the user
member.ban(config.banMessage).then(() =>{
message.reply(`sucessfuly banned ${user.tag}.`);
console.log(`Sucsessfuly banned ${user.tag} in ${message.guild}`)
}).catch(error =>{
// Catches any errors
message.reply(`I encountered an error when trying to ban ${user.tag}`);
console.log(`Error banning ${user.tag} in ${message.guild}`);
console.error(error);
})
} else {
message.reply(`That user isn\'t in the server.`)
}
} else {
message.reply(`you need to specify a valid user to ban!`)
}
} else {
message.reply('you do not have permission to use this command!')
console.log(`${message.author} tried to use the ban command in ${message.guild} but did not have sufficient permissions`)
}
},
Found my problem. The ban command has a different method of using a reason compared to the kick command. For the kick command, you can simply use message.author.kick("reason") as said here. But for the ban command you use message.author.ban({reason: "reason"}) as said here.

Discord.js open DM stream with certain user by ID

Is there any option to open a DM stream or something like that with certain user by ID.
What do I mean?
It's like ssh terminal function, when I enter command to bot like:
me: DM#{user.id}
bot: {connection established message}
/**--------------------------------------------
# and for now, every message from me, bot will deliver to {user.id} until I
# don't send `{message_stop}` command, for example:
----------------------------------------------*/
me: "Hi, how are you?" -> client.fetchUser('user_id')
me: "Are you ok?"
me: -stop command
Without using -prefix every time in the beginning of each message?
Or probably implement this function like that:
Creating a channel on server(guild) and every message that I write there, will be delivered to a certain user?
The actual question is, if it's possible then how should I manipulate with client.on('trigger') state to achieve such result?
As for now, I have written the command, which DMs message to user, based on prefix in the begging of each message like:
me: dm#user_id: Hello!
me: dm#user_id: How are you?
Probably I should store session data (user.id) somewhere, to help bot understood that I want to communicate only with specific user?
I receive this answer in Discord.js discord. So it's possible with MessageCollector. I'm using this guide for building my bot with dynamic commands. So here is my code:
module.exports = {
name: 'direct',
description: 'Ping!',
args: true,
execute(message, args, client) {
const u = message.content.split(/(?<=^\S+)#/)[1];
console.log(message.content);
message.channel.send(`Connection established: ${message.author.id}`);
const filter = m => m.content.includes('discord');
const collector = message.channel.createMessageCollector(filter, {
maxMatches: 10,
time: 30000,
errors: ['time']
});
collector.on('collect', m => {
console.log(`${Date.now()} Collected ${m.content}`);
client.fetchUser('user_id').then((user) => {
return user.send(`${m.content}`);
});
});
collector.on('end', collected => {
message.channel.send(`Connection cancelled with ${message.author.id}. You send ${collected.size} messages`);
console.log(`${Date.now()} Collected ${collected.size} items`);
if (collected.size === 0) {
console.log('here');
}
});
}
};
You just enter command name (direct) in this case, and then every message that incudes discord DMs to user_id 10 times or for 30 seconds. You could use arguments, if you want to change it. Hope it helps anyone.
Also, I'm very thankful to Monbrey#4502 from Discord.js community for providing this information.

Await reply in private message discord.js

So, this works ALMOST as intended. I have the bot private messaging the user who uses the correct command in the correct channel of the server. Instead of clogging up the server with profile creation messages, I have the bot do profile creation privately. I know/think the problem is with the message.channel.awaitMessages, because it only sees the replies in the original channel on the server where the command was put into place.
I am not sure what I should replace the message.channel.awaitMessages with in order for it to pick up on the reply in the private message conversation rather than the original profile creation channel on the server.
I have not tested the sql message yet. I haven't tested what I have but I am pretty sure it won't work. I want the reply that is given by the user in the private message to be inserted (updated maybe?) into a mysql database I have already set up and properly got working. The users ID and username has been put into this table with the rest of the profile related questions being null at this moment. As they reply to these questions, those fields can be filled out/updated. Any ideas/suggestions are welcome!
module.exports.run = async (bot, message, args) => {
if(message.channel.id === '460633878244229120') return message.author.send(`Greetings, ${message.author.username}! FIRST QUESTION, **What is the name of your Brawler or Character?**`)
.then(function(){
message.channel.awaitMessages(response => message.content, {
max: 1,
time: 5000,
errors: ['time'],
})
.then((collected) => {
message.author.send(`Your Name is: ${collected.first().content}`);
var sql = (`UPDATE profile SET name = '${message.content}' WHERE id = ${message.author.id}`);
})
.catch(function(){
message.author.send('Please submit a name for your character. To restart Profile creation, please type "!profilecreate" command in Profile Creation channel on the server.');
});
});
}
Thanks in advance for your time!
I don't use SQL so, since the question is not specifically on that, don't ask me.
When you're using message.channel.awaitMessages, message is still the first one that you passed in the module.exports.run function, not the one that comes from send(). When send is resolved, it passes a new message, that you have to include in the arguments of the function you put inside then: so, instead of .then(function() {}) you'll need something like .then(function(new_message_sent_in_private) {})
This should fix the problem:
module.exports.run = async (bot, message, args) => {
if(message.channel.id === '460633878244229120') return message.author.send(`Greetings, ${message.author.username}! FIRST QUESTION, **What is the name of your Brawler or Character?**`)
.then((newmsg) => { //Now newmsg is the message you sent
newmsg.channel.awaitMessages(response => response.content, {
max: 1,
time: 5000,
errors: ['time'],
}).then((collected) => {
newmsg.channel.send(`Your Name is: ${collected.first().content}`);
var sql = (`UPDATE profile SET name = '${message.content}' WHERE id = ${message.author.id}`);
}).catch(() => {
newmsg.channel.send('Please submit a name for your character. To restart Profile creation, please type "!profilecreate" command in Profile Creation channel on the server.');
});
});
}
Let me now if that worked :)

Categories

Resources