Discord Bot Posting a Channel Link - bots

This is what I have so far and it works. I am trying to add a #channel-name-link at the end of the message.
bot.on('guildMemberAdd', member => {
const welcome = member.guild.channels.cache.find(channel => channel.name === "on-the-leash");
if (!welcome) return;
welcome.send("Welcome " + member.toString() + "more message here!!" + message.guild.channels.cache.get('channelID').toString());
});
Now I am getting an error say that message is not defined. I am new to node.js. I am use to PowerShell and Bash. I have programmed in Java and C++ but it has been a year or two since I really did anything with them. I appreciate all the help.
Any help would be appreciated

Are you using discord.js v11 or v12?
Do you want to get the channel by using it's ID or would you rather find it using its name?
Edit:
Add .cache after message.guild.channels, that should fix your issue
Your solution would be:
welcome.send("Welcome " + member.toString() + "more message here" + message.guild.channels.cache.find(channel => channel.name === "rules" ).toString());
OR
welcome.send("Welcome " + member.toString() + "more message here" + message.guild.channels.cache.get("channelID").toString());

Thank you for the help #Syntle you got me where I needed to be
bot.on('guildMemberAdd', member => {
const welcome = member.guild.channels.cache.find(channel => channel.name === "on-the-leash");
const channel = member.guild.channels.cache.get('#ChannelID#').toString();
if (!welcome) return;
welcome.send("Welcome " + member.toString() + "More Message Here" + channel);
});

Related

Discord.js | Mentioning someone in an embed

Hey im trying to make a bot which has hug commands and its meant to say you hugged a user that you mentioned, inside an embed with a random hug image...Code:
if (message.content === '+hug'){
let user = message.mentions.users.first();
let maxImageNumber = 5;
let imageNumber = Math.floor (Math.random() * (maxImageNumber - 1 + 1)) + 1;
let imageName = `${imageNumber}.gif`
let imagePath = `./hug/${imageName}`
let file = new Discord.MessageAttachment(imagePath);
let embed = new Discord.MessageEmbed();
embed.setDescription(message.author.username + ' *just hugged* '+ user.username);
embed.setImage(`attachment://${imageName}`)
embed.setColor(0xffe6f7)
message.channel.send({ files: [file], embed: embed });
}
The Error is every time I do the command nothing shows up
How would I solve this issue?
I already made a question like this but it wasn't clear enough, I hope this is clear
Your current doesn't work, because you check if the content of the message is equal to +hug. So when you send +hug #some-user, the content of the message is not equal to +huganymore. The following code will work:
if (message.content.startsWith('+hug')){
let user = message.mentions.users.first();
let maxImageNumber = 5;
let imageNumber = Math.floor (Math.random() * (maxImageNumber - 1 + 1)) + 1;
let imageName = `${imageNumber}.gif`
let imagePath = `./hug/${imageName}`
let file = new Discord.MessageAttachment(imagePath);
let embed = new Discord.MessageEmbed();
embed.setDescription(message.author.username + ' *just hugged* '+ user.username);
embed.setImage(`attachment://${imageName}`)
embed.setColor(0xffe6f7)
message.channel.send({ files: [file], embed: embed });
}
It doesn't check if the content of the message is equal to something but if it starts with something.
Try this
embed.setDescription(`${message.author.username} *just hugged* ${user.username}`);
If you want to mention the second person you just type user instead of user.username
Hope this helped

Having different welcome channels

I need my discord bot to remember which channel to send a greeting to in different guilds.
For now, I have the channel name as a prefix and I use that to recall where to send it:
//greeting new users script
bot.on('guildMemberAdd', member => {
// Send the message to a designated channel on a server:
const WelcomeChannel = member.guild.channels.cache.find(ch => ch.name === config.WelcomeChannelVar);
// Do nothing if the channel wasn't found on this server
if (!WelcomeChannel) return;
const welcomeEmbed = new Discord.MessageEmbed()
.setAuthor(member.displayName.toString() + '#' + member.user.discriminator, member.user.displayAvatarURL())
.setTitle('someone joined!')
.setDescription('welcome to **' + member.guild.name + '**, <#' + member.id + '> !')
.setColor(0x348a58)
.setThumbnail(member.user.avatarURL())
.setFooter('you\'re member #' + member.guild.memberCount + '!')
setTimeout(() => {
WelcomeChannel.send(welcomeEmbed)
}, 200);
member.send("welcome to " + member.guild.name + "! please **read the rules**, and *follow them* :) if you need any help, please **ping a staff member**.");
});
How do I set a command that owners can use when the bot joins their guild that sets a unique welcome channel for each guild (and obviously only send welcome messages to people who join in their guild).
Oh, and how do I set a command that eventually lets people change the welcome message for their guild?
Thanks! :)
You need to have a file where you store the welcome channel IDs for every guild, so that you can later check them. You can just use a JSON file:
// Define it one time
const welcomeChannels = require('./path/to/your/file.json')
// When you want to set the channel for a guild
welcomeChannels[guild.id] = channel.id
fs.writeFileSync('./path/to/your/file.json', JSON.stringify(welcomeChannels))
// When you need to read a property
let welcomeChannelID = welcomeChannels[guild.id]
You can use a variable to store the object, which is saved to a file that you can update with fs.writeFileSync.
Inside the guildMemberAdd handler, you can get the guild id from the new member and then use it to get the channel id:
bot.on('guildMemberAdd', member => {
let id = welcomeChannels[member.guild.id]
let welcomeChannel = member.guild.channels.cache.get(id)
// The rest is the same as in your code
})
Example
In the main file you just need to require it for the first time and use it in your guildMemberAdd handler.
// main file
const welcomeChannels = require('./path/to/your/file.json')
bot.on('guildMemberAdd', member => {
let id = welcomeChannels[member.guild.id]
let welcomeChannel = member.guild.channels.cache.get(id)
// The rest is the same as in your code
})
For the command it really depends on your command system: you need to find a way of sharing the welcomeChannels variable across the files, which is typically done though import/export Here's a mock function on how to set a new value.
// command file
function setId(guildID, channelID) {
welcomeChannels[guild.id] = channel.id
fs.writeFileSync('./path/to/your/file.json', JSON.stringify(welcomeChannels))
}

Discord.js mentioning

client.on('message', message => {
if (message.content === `L!hug`) {
if (!message.mentions.users.size) {
return message.reply('you need to tag a user in order to hug them!!');
const taggeduser = message.mentions.users.first();
}
// message goes below!
message.channel.send(userID + ` you just got a hug https://tenor.com/view/anime-cuddle-cute-gif-12668750`);
}
});
I have tried a few ideas and I am very new to this library of language (discord.js)
You can use message.mentions.members.first()
client.on('message', message => {
if (message.content.startsWith('L!hug')) {
let targetMember = message.mentions.members.first();
if(!targetMember) return message.reply('you need to tag a user in order to hug them!!');
// message goes below!
message.channel.send(`<#${targetMember.user.id}> you just got a hug https://tenor.com/view/anime-cuddle-cute-gif-12668750`);
}
});
Discord.js uses many custom toString() and an User return his mention.
So if you want to mention an user in a message you can do
This :
`<#${user.id}>`
But a faster way is this :
`${user}`
And you can simply put user without any String it works also if the function runs a .toString() on your string.
like this :
message.channel.send(user + " has made something");
Will mention the user.
Note :
It won't work anymore in v13.
If you use a command handler like this one
this is how you would make it work
module.exports = {
name: "hug",
description: "# someone to hug them through the bot command.",
nsfw: false,
execute(message, args){
const targetmember = message.mentions.members.first()
if (!targetmember) return message.reply("you need to tag a user in order to hug them.");
var huggifs = [`${targetmember} Recieved a hug https://imgur.com/r9aU2xv`, `${targetmember} Recieved a hug https://tenor.com/LUqw.gif`, `${targetmember} Recieved a hug https://media.giphy.com/media/3ZnBrkqoaI2hq/giphy.gif`, `${targetmember} Recieved a hug https://tenor.com/1jRF.gif`, `${targetmember} Recieved a hug https://media.giphy.com/media/lrr9rHuoJOE0w/giphy.gif`]
var hugrandomform = huggifs[Math.floor(Math.random()*huggifs.length)];
message.channel.send(hugrandomform).then().catch(console.error);
}
}
Here, you can use message.mentions.users.first():
let user = message.mentions.users.first(); // As a shortcut to it
// Check if there is actually a mention
if(!user) {
return message.reply("You need to tag a user in order to hug them!");
}
// If there is a user, do this code
message.channel.send(`${user.toString()}, you just got a hug https://tenor.com/view/anime-cuddle-cute-gif-12668750`);
// user.toString() will convert the user object to a mention
Hope this helped!
Here is a simple version of the code. userID isn't defined, meaning you'd need to use the targetmember. Here, this is how it should be.
client.on('message', message => {
if (message.content === "L!hug") {
const targetmember = message.mentions.members.first()
if (!targetmember) return message.reply("you need to tag a user in order to hug them!!");
message.channel.send(`${targetmember} you just got a hug https://tenor.com/view/anime-cuddle-cute-gif-12668750`);
}
})
You can use this to create a mention (note that it will not work in pre, as no mention works in it)
'<#&' + user_id + '>'
Note the # and &.

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);
});

Using Promise in afterSave

I am trying to do the following code in cloud code:
//Code for sending push notifications after an update is created
Parse.Cloud.afterSave('AssignmentMod', function(request){
//Only send if the mod is new
console.log("MOD SAVED. NOTIFICATIONS CHECK.")
if(!request.object.existed()) {
console.log("NEW MOD ADDED. NOTIFICATIONS START.")
var mod = request.object
//Get the users who have these classes
var userType = Parse.Object.extend('User')
var usersQuery = new Parse.Query(userType)
usersQuery.equalTo('currentClasses', mod.get("parentClass"))
//Get the users who removed the assignment
var modsType = Parse.Object.extend('AssignmentMod')
//If if was an assignment and removed at some point
var mods1Query = new Parse.Query(modsType)
mods1Query.notEqualTo("assignment", null)
mods1Query.equalTo("assignment", mod.get("assignment"))
mods1Query.equalTo("type", "remove")
//If it was an assignment mod and was removed at some point
var mods2Query = new Parse.Query(modsType)
mods2Query.notEqualTo("assignmentMod", null)
mods2Query.equalTo("assignmentMod", mod.id)
mods2Query.equalTo("type", "remove")
//Get the remove mods for this particular update
var modsQuery = new Parse.Query.or(mods1Query,mods2Query)
//Run the user and mods queries
Parse.Promise.when(
usersQuery.find(),
modsQuery.find()
).then( function(users, removeMods) {
console.log("QUERY 1 COMPLETE.")
//Get all users that copied this remove mod
var copyType = Parse.Object.extend('ModCopy')
var copyQuery = new Parse.Query(copyType)
copyQuery.containedIn("assignmentMod", removeMods)
copyQuery.find().then(function(copies){
console.log("QUERY 2 COMPLETE.")
var copyUsers = copies.map(function(copy){
return copy.get("user")
})
//Get the devices of users that belong to the class, did not remove the assignment, and have an ios devices
var deviceQuery = new Parse.Query(Parse.Installation)
deviceQuery.equalTo("deviceType", "ios")
deviceQuery.containedIn("user", users)
deviceQuery.notContainedIn("user", copyUsers)
//Send the push notification
console.log("PUSHING NOTIFICATIONS")
Parse.Push.send(
{
where: deviceQuery,
data: {
alert: "You have new updates."
}
},
{userMasterKey: true}
).then(
function(){
console.log("SUCCESSFULLY SEND NOTIFICATIONS.")
},
function(error){
throw "Error sending push notifications:" + error.code + " : " + error.message
console.log("FAILED TO SEND NOTIFICATIONS")
}
)
},
function(reason){
throw "Error: " + reason
print("ERROR: " + reason)
})
},
function(reason){
throw "Error: " + reason
print("ERROR: " + reason)
})
}
})
I can see in my logs that "MOD SAVED. NOTIFICATIONS CHECK." and "NEW MOD ADDED> NOTIFICATIONS START." are both logged out. However, I get no other logs after that and no push notifications are sent. I should at leas see the logs, and see none. Is there an issue with parse server using promises inside an afterSave or something? Why am is my code seemingly halting execution when it hits the first promise?
Your afterSave() cloud code must be ended by a response.success() or response.error(error)
You should wait for all your Promises complete end then finish your code with something like:
promise.then( function(){
console.log("END of afterSave() " ;
response.success();
}, function(error){
console.error("error in afterSave() " + " : " + error.message);
response.error(JSON.stringify({code: error.code, message: error.message}));
});
This turned out to be an issue with Heroku hosting. I have not tracked down passed that. If the same code is hosted on AWS or another hosting platform, these issues do not occur. There is likely some server settings Heroku uses in it's default setup that need changed. If you encounter this issue and have more of a solution beyond "Switch off Heroku hosting" then submit an answer and I will accept.

Resources