How to send a dm to a user using commands - bots

I'm scripting a bot to dm a certain user a message that I write for example I will do:
!dm #user Hi!
And the bot will send that user the dm saying only Hi!
It doesn't let me, can someone please check my code?
if(command === "dm") {
let member = message.mentions.members.first() || message.guild.members.get(args[0]);
if(!member)
return message.reply("Please mention a valid member of this server");
let reason = args.slice(1).join(' ');
mentionedUser.send(`${reason}`);
}
Updated code:
if(command === "dm") {
let member = message.mentions.members.first() || message.guild.members.get(args[0]);
if(!member)
return message.reply("Please mention a valid member of this server");
let reason = args.slice(1).join(' ');
if(!reason)
return message.reply("Please write a message.");
member.dmChannel.send(`${reason}`);
message.reply(`${member.user.tag} received a message( ${reason} ) sent by:${message.author.tag}`);
}
Now I get this error:
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'send' of undefined

You can DM the user by fetching the user's DM first,
let member = message.mentions.members.first() || message.guild.members.get(args[0]);
//...
member.dmChannel.send("")
Alternatively, you can use createDM() instead.

This answer pertains only to versions 11 and later.
There's no need to access the client's DM channel with the user (which needs to be instantiated first anyway). Simply use the User.send() or GuildMember.send() method.
member.send(reason)
.catch(console.error);

Related

Why does my Discord bot keep repeating when it runs this command?

This is the code used, there is nothing (I think) that's causing it to repeat, matter of fact I added something so it stops repeating but it didn't do anything at all.
client.on('message', e =>{
if(e.member.roles.cache.has('12345678901')){
if(!e.content.startsWith(p) || e.author.bot) return;
console.log('successfully unmuted')
var ar = e.content.slice(p.length).split(/ +/)
var cmd = ar.shift().toLowerCase();
if(cmd === 'b'){
console.log('succesfully banned')
var member = e.mentions.users.first();
if(member){
var membertarget = e.guild.members.cache.get(member.id)
membertarget.ban();
var sbbed = new discord.MessageEmbed()
.setColor('GREEN')
.setTitle('success!')
.setDescription(`<#${membertarget.user.id}> has been successfully banned!`)
}else {
var bbed = new discord.MessageEmbed()
.setColor('RED')
.setTitle('invalid user!')
.setDescription('ban failed because there was not a valid member mentioned :(')
e.channel.send({ embeds: [bbed] })
}
}
} else {
var rolefb = new discord.MessageEmbed()
.setColor('RED')
.setTitle('failed!')
.setDescription('sorry! you dont have a high enough role to use this command, but this can change!')
if (e.author.bot) return;
e.channel.send({embeds: [rolefb]})
}
})
This code is supposed to just ban somebody but it keeps repeating itself whenever it fails:
Code:
client.on('message', e =>{
if (e.author.bot) return
if(e.member.roles.cache.has('960191891473829929')){
I have edited the code, but it still doesn't work.
Your code in the message event listener runs whenever a message is posted in your server so the bot sending the message will also be counted. So all you have to do is add an if statement in the start to check whether the author of the message was a bot:
if (message.author.bot) return
Try to add this statement to your code before if(e.member.roles.cache.has('12345678901')){
if (e.author == client.user) return;
Also, change the if(e.member.roles.cache.has('12345678901')){ to else if (e.member.roles.cache.has('12345678901')){.
I would recommend restructuring the entire code and make it into a command handler, though.

Node.js Discord Bot TypeError: Cannot read property of 'voice' of undefined

Here is my whole code for the command, the problem is when I do -move everyone 123132123123(example channel id). The command works perfectly but gives me an error of (node:317) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'voice' of undefined. I have been trying to .catch() the error but it still gives me that error. Whenever I do return member.voice.setChannel(`${move}`);. The error stops but also only moves me for some reason...
if (command === 'move') {
if (!message.member.permissions.has("MOVE_MEMBERS")) return message.channel.send(':x: **You do not have the permission to use this command!**');
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
const mem = message.mentions.members.first()
let move = args[1]; // Remember arrays are 0-based!.
let move2 = args[2];
let idcheckchannel1 = client.channels.cache.get(move)
let idcheckchannel2 = client.channels.cache.get(move2)
if (!args[0]) return message.channel.send('Please mention user and voice channel ID/IDs')
if (!args[1]) return message.channel.send('Please mention voice channel ID/IDs')
if(args[0] === 'everyone' && !move2) {
if (!idcheckchannel1) return message.channel.send('Please use a valid voice channel ID')
let channel = message.guild.channels.cache.get(message.member.voice.channel.id);
for (const [memberID, member] of channel.members)
member.voice.setChannel(`${move}`);
}
if (!mem.voice.channel) return message.channel.send('User is not in voice channel')
if (!move2) {
if (!idcheckchannel1) return message.channel.send('Please use a valid voice channel ID')
mem.voice.setChannel(`${move}`)
} else {
if (!idcheckchannel1) return message.channel.send('Please use a valid voice channel ID')
if (!idcheckchannel2) return message.channel.send('Please use a valid voice channel ID')
mem.voice.setChannel(`${move}`)
mem.voice.setChannel(`${move2}`)
}
}
mem may be undefined if message.mentions.members is empty. You should check whether mem is undefined or not before using it.
Try this:
if (command === 'move') {
if (!message.member.permissions.has("MOVE_MEMBERS")) return message.channel.send(':x: **You do not have the permission to use this command!**');
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
const mem = message.mentions.members.first()
let move = args[1]; // Remember arrays are 0-based!.
let move2 = args[2];
let idcheckchannel1 = client.channels.cache.get(move)
let idcheckchannel2 = client.channels.cache.get(move2)
if (!args[0]) return message.channel.send('Please mention user and voice channel ID/IDs')
if (!args[1]) return message.channel.send('Please mention voice channel ID/IDs')
if(args[0] === 'everyone' && !move2) {
if (!idcheckchannel1) return message.channel.send('Please use a valid voice channel ID')
let channel = message.guild.channels.cache.get(message.member.voice.channel.id);
for (const [memberID, member] of channel.members)
member.voice.setChannel(`${move}`);
}
if (mem != null) { // << ensure that mem is not undefined
if (!mem.voice.channel) return message.channel.send('User is not in voice channel')
if (!move2) {
if (!idcheckchannel1) return message.channel.send('Please use a valid voice channel ID')
mem.voice.setChannel(`${move}`)
} else {
if (!idcheckchannel1) return message.channel.send('Please use a valid voice channel ID')
if (!idcheckchannel2) return message.channel.send('Please use a valid voice channel ID')
mem.voice.setChannel(`${move}`)
mem.voice.setChannel(`${move2}`)
}
}
}
channel.members returns a Collection, not an Array, so array destructuring will not work. Even if it did, the first properties of each element are not memberID and member.
Also, you made a new channel variable, even though you already had the channel object.
// let channel = message.guild.channels.cache.get(message.member.voice.channel.id);
// for (const [memberID, member] of channel.members)
// member.voice.setChannel(`${move}`);
// };
for (const member of message.member.voice.channel.members)
member.voice.setChannel(move);

How can i check if a person has went online, offline, etc. in discord.js?

const channel = client.channels.cache.get('<channelid>');
const person1 = client.users.cache.get('<userid>');
const person = client.users.cache.get('<userid>');
client.on('message', message =>{
client.on('presenceUpdate', () =>{
if(person1.user.presence.status === 'dnd' || person1.user.presence.status === 'online'){
channelforstatus.send('person1 is now online');
}
else if(peron1.user.presence.status === 'offline' || person1.user.presence.status === 'idle'){
channel.send('person1 is offline');
}
client.on('message', message => {
client.on('presenceUpdate', () =>{
if(person.user.presence.status === 'dnd' || person.user.presence.status === 'online'){
channel.send('person is now on');
}
else if(person.user.presence.status === 'offline' || person.user.presence.status === 'idle'){
channel.send('person is now off');
}
});
});
});
});
This is what I've tried and the .send() the function is not working. I've looked everywhere and found nothing that could help me with this problem. I just need it so it checks every time if a specific person has went online, offline, etc. And sends a message to a specific channel.
First of all, one rule to abide with is that event listeners should always be in top level of your code and never nested. (Else you are subject to memory leaks and other issues like duplicated and unintended code execution).
client.on("message", (message) => {
...
});
client.on('presenceUpdate', (oldPresence, newPresence) => {
...
});
Now when looking at presenceUpdate event and Presence object documentation you can manage to see if a status evolved like that :
client.on('presenceUpdate', (oldPresence, newPresence) => {
let member = newPresence.member;
// User id of the user you're tracking status.
if (member.id === '<userId>') {
if (oldPresence.status !== newPresence.status) {
// Your specific channel to send a message in.
let channel = member.guild.channels.cache.get('<channelId>');
// You can also use member.guild.channels.resolve('<channelId>');
let text = "";
if (newPresence.status === "online") {
text = "Our special member is online!";
} else if (newPresence.status === "offline") {
text = "Oh no! Our special member is offline.";
}
// etc...
channel.send(text);
}
}
});
Be aware that presenceUpdate event is fire by EACH guild the user and bot share, meaning that if user status change and share two guilds with your bot, this code will be executed twice.
In case you use presence but get offline instead of the user being online I spent like.. 2 whole days looking for the answer so ill share it anywayz
Common mistakes on presence.status is forgetting to check these stuff at the the developer applications. which i have no idea what means
A screenshot
now on your message (command handler) function.. if you have one
message.guild.members.cache.get('userId').presence.status
or
${message.author.username} is now ${message.author.presence.status};
Ill update this if I found out how to presence all the users instead of just one
my first post... I SHALL REMEMBER THIS xD
To get the presence, you can use user.presence, which will get all kinds of info about the user, but you only need user.presence.clientStatus.desktop
so your code would, for example, be
bot.on('presenceUpdate', () =>{
let person1 = bot.users.cache.get('USERID')
console.log(person1.presence.clientStatus.desktop)
if(person1.presence.clientStatus.desktop === 'dnd' || person1.presence.clientStatus.desktop === 'online'){
channel.send('person1 is now online');
}
else if(person1.presence.clientStatus.desktop === 'offline' || person1.presence.clientStatus.desktop === 'idle'){
channel.send('person1 is offline');
}
})

I want to send a message to a specific user after someone joined into a specific channel

So, I want my Discord bot to send a message to a specific user whenever someone joins into a specific channel. But my code doesn't seem to work.
Does someone know how to fix it?
client.on('voiceStateUpdate', (oldMember, newMember) => {
let newUserChannel = newMember.voiceChannel
let oldUserChannel = oldMember.voiceChannel
if(oldUserChannel === undefined && newUserChannel !== undefined) {
if(voiceChannel.id === "530501827389685762"){
client.users.get("188984116618854400").send("Ein neuer Spieler ist im Aufnahmebereich!")
}
else {
return;
}
}
})
On line 6, you write:
if (voiceChannel.id ...
voiceChannel is not defined.
For future reference, include the error. Some style remarks:
1. the else and return statement are unnecessary if that's the end of your function
2. research truthy and falsy values in javascript, they can save you some time checking if channels are undefined.

Send message to specific channel with typescript

I want to send a greeting message to an "welcome" text channel, whenever a new user joins the server (guild).
The problem I'm facing is that, when I find the wanted channel, I will receive the channel with the type GuildChannel.
Since GuildChannel has no send() function, I'm not able to send the message. But I can't find a way to find the TextChannel, so I'm stuck here.
How can I get to the TextChannel so that I'm able to use the send() message? Below the code I'm using by now:
// Get the log channel (change to your liking)
const logChannel = guild.channels.find(123456);
if (!logChannel) return;
// A real basic message with the information we need.
logChannel.send('Hello there!'); // Property 'send' does not exist on type 'GuildChannel'
I'm using version 11.3.0 of discord.js
Thanks to this GitHub issue I've found the solution to my problem.
I need to use a Type Guard to narrow down the correct type.
My code now is this:
// Get the log channel
const logChannel = member.guild.channels.find(channel => channel.id == 123456);
if (!logChannel) return;
// Using a type guard to narrow down the correct type
if (!((logChannel): logChannel is TextChannel => logChannel.type === 'text')(logChannel)) return;
logChannel.send(`Hello there! ${member} joined the server.`);
Maybe for latecomers who are still looking for an answer this worked for me
let channel = client.channels.get("channelid") as Discord.TextChannel;
channel.send("what you want to send to that channel");
You can use the GuildChannel#isText() method to type guard before invoking send.
Example:
if (channel.isText()) {
await channel.send('...');
}
Or:
if (!channel.isText()) return;
await channel.send('...');
Discord v14
const channel: TextChannel = client.channels.cache.get(channelId) as TextChannel;
channel.send('test')
If you have problems with cache, you can use
const channel: TextChannel = await client.channels.fetch(channel.channelId) as TextChannel;
I do this:
let channel = client.guilds.get('your-guild-id').channels.get('your-channel-id');
channel.send("it worked");
(client is the discord client). your code should work if you change find to get and put the channel id in some single quotes. Well, it works for me.
Maybe this can help you?
Code:
client.on('guildMemberAdd', member => {
let channel = member.guild.channels.find('name', 'welcome');
let memberavatar = member.user.avatarURL
if (!channel) return;
let embed = new Discord.RichEmbed()
.setColor('RANDOM')
.setThumbnail(memberavatar)
.addField(':bust_in_silhouette: | name : ', `${member}`)
.addField(':microphone2: | Welcome!', `Welcome to the server, ${member}`)
.addField(':id: | User :', "**[" + `${member.id}` + "]**")
.addField(':family_mwgb: | Your are the member', `${member.guild.memberCount}`)
.addField("Name", `<#` + `${member.id}` + `>`, true)
.addField('Server', `${member.guild.name}`, true )
.setFooter(`**${member.guild.name}**`)
.setTimestamp()
channel.sendEmbed(embed);
});

Resources