Discord.js mention players on welcome - javascript

a few days ago i made a code to mention users when they join my discord server, this is the code i currently have:
bot.on( "guildMemberAdd", member => {
let textChannel = member.guild.channels.find(channel => channel.id === '569582472812298240');
if (textChannel){
var messages = [
`Brace yourselves. <#${member.user.id}> just joined the server.`,
`Challenger approaching - <#${member.user.id}> has appeared`,
`Welcome <#${member.user.id}>. Leave your weapon by the door.`,
`Big <#${member.user.id}> showed up!`,
`<#${member.user.id}> just joined... or did they?`,
`Ready player <#${member.user.id}>`,
`<#${member.user.id}> hopped into the server. Kangaroo!!`,
`<#${member.user.id}> joined. You must construct additional pylons.`,
`Hello. Is it <#${member.user.id}> you're looking for?`,
`Where's <#${member.user.id}> in the server!`,
`It's dangerous to go alone, take <#${member.user.id}>`
]
textChannel.send({embed: {
color: 3447003,
description: messages[ Math.floor( Math.random() * 11 ) ],
timestamp: new Date(),
}
});
}
});
The problem? Sometimes i get the correct nickname of the person as you can see in this picture, but other times i get just numbers and i can't even click on that 'link'...
Correct way:
They are clickable and i can see their profile.
Incorrect way:
I can't click their id, nothing can be done with it.
Not sure why this happens randomly, any help would be extremely appreciated.

If someone joins the server and then leaves, and you have no other mutual servers with them and are not their friend, it'll just show their user id. This is a client side thing and there isn't really any real fix for mentions. You can however opt to just send their username instead of a mention.

You could try running toString on the member object, as it will automatically generate the right mention (as sometimes it can be prepended with <#!), but the likely reason it still won't work is because your Discord client did not cache the user that just joined.
It can be either because you're in a log channel, the server has too many members or the member left before your Discord client cached the user. You can either try to not use an embed, or (probably the best solution) provide the full username as well as the mention in the embed.

Try this:
bot.on('guildMemberAdd', member => {
var ran = randomRange(0,2);
var greeting;
switch (ran) {
case 0:
greeting = "Brace yourselves. " + member.user + " just joined the server.";
break;
case 1:
greeting = "Challenger approaching - " + member.user + " has appeared";
break;
case 2:
greeting = "Welcome " + member.user + ". Leave your weapon by the door.";
break;
// add more if you want (but dont forget to also change the values in line 2
}
member.guild.channels.get('CHANNEL ID HERE').send(greeting);
});
And add this function:
function randomRange(min, max) { // returns an int >= min and <= max
return Math.floor(Math.random() * (max - min + 1)) + min;
}

Related

How do I import values ​from MongoDB into a Discord embed?

I have all the data I need in the mongoDB Database, I just dont know how I can send parts of the data in an Discord embed.
for example the data:
new birthdaySchema({
User: username.username,
Birthday: birthdayString,
Month: showMonth,
Day: showDay,
Year: showYear
Year, Month and Day are just there to sort the birthdays and birthdayString = Day of Month
I also use moment-timezone (UTC)
const dateTime = moment.utc().format(`DD MM YYYY, hh:mm:ss`);
My goal is with a slash commad like /next-birthdays the data in the embed should look like
${birthdayString} ${Year}\n${User} (and this 10 times, so the the upcoming birthdays of 10 users)
And if the birthday and the actual date and time from moment-timezones (UTC) is matching.
Then the Bot should make a new embed with a title (Happy Birthday) and in the description (Today is ${User}'s Birthday, blah blah blah) and at last it should give that User the birthday role on this server.
Hope someone can help me :)
I have something similar to what might be able to help you :)
This is achieved by using the mongoose library (which I'm guessing you are likely using).
In my code I have a reference to the JS file where my schema is held:
const Messages = require("../models/benSchema2");
Then, you could have a variable and store all entries from the database inside it in an array form, like this:
const messageOrdered = await Messages.find({}).sort({ messages: -1 });
(In my case, I get all entries from the database, sorting by descending order of messages. Perhaps you might be able to sort it based on birthdayString?)
Then you can have a for loop, starting at i=0 and stopping at 9 which should get the nearest 10 birthdays. I have my code in here but it could be refactored to be more efficient. Also, my code works based off user ID data being stored in the database but it should be able to work by refining it to work on usernames.
let content = "";
for (let i = 0; i < messageOrdered.length; i++) {
if (i === 5) {
break;
}
const userID = await client.users.fetch(messageOrdered[i].UserID);
let user = userID.username;
if (i === 0) {
content += `πŸ₯‡ ${i + 1}: ${user} - ${messageOrdered[i].messages}\n`;
} else if (i === 1) {
content += `πŸ₯ˆ ${i + 1}: ${user} - ${messageOrdered[i].messages}\n`;
} else if (i === 2) {
content += `πŸ₯‰ ${i + 1}: ${user} - ${messageOrdered[i].messages}\n`;
} else {
content += `πŸŽ–οΈ ${i + 1}: ${user} - ${messageOrdered[i].messages}\n`;
}
} (bit spaghetti code but oh well :))
Once you get the nearest 10 and they are all added to the content string then in your final MessageEmbed you can do:
.addField("Global Positions (Text):", content)
Then finally send it.
I hope this has helped somehow :)

How to get text from individual users

I'm trying to make a notes command for specific users, but my Discord bot makes the notes any note that a user public has said. How do I fix this? I already know the problem with my code, but I don't know how to fix it.
if (command == "Note") {
const notes = db.fetch('userInfo');
while (!args[0]) return message.channel.send("Here are your notes: " + notes);
db.set('userInfo', args.join(' '));
message.channel.send((args.join(' ')) + (" successfully noted!"));
}
You have a row called userInfo, this row gets updated whenever someone executes the command. If you want it to link with a user, you're better of using the id of the user because everyone has a different ID. I suggest using something like:
const notes = db.fetch(`userInfo.${message.author.id}`)
while (!args[0]) return message.channel.send("Here are your notes: " + notes )
db.set('userInfo.${message.author.id}', args.join(' '))
message.channel.send(args.join(' ') + " successfully noted!")

Getting prices with an npm package not working

Actually I think there is an even better way to get the prices using this npm (you can open it to see better how it works):
https://github.com/jaggedsoft/node-binance-api than using the "coin "variable I am trying to use but I don't know how it could be possible, if you guys could help me to figure out with a better idea or the best way to pull prices with this package using discord it would be awesome, I've been already some days sticked to it :/
What I need:
To be able to replace "ticker.XRPBTC" (code below).
For example if I write ETH it should be changed from ticker.XRPBTC to ticker.ETHBTC
var coin = (message.content.toUpperCase()).slice(2) + "BTC";
binance.prices((error, ticker) => {
console.log("Price of " + coin + ":", ticker.XRPBTC);
});
for that I made the variable coin, I thought I could just write ticker.coin but it does not work...
I have tried this:
As an example:
ticker.XRPBTC - This code works, output: the actual price of the currency.
What I am trying:
var coin = XRPBTC
console.log(ticker.coin) - output: undefined
btw. I am writting console.log to test it in the console but I also have an error if I write:
if (msg.startsWith ("eth")) {
message.reply ("Price of " + coin + ":", ticker.TRXBTC);
}
an explanation of what ticker does:
The ticker has the function to get the last price of each currency, it can be for example ETHBTC, XRPBTC, TRXBTC etc. in this case eth, xrp and trx are the currencies. So in the ticker I just need to write it that way so that I can get the price for that pair.
As you can see in the code I sent you above, I am getting the text exactly how the ticker would "need it to look".
So if I write eth, the variable "coin" is transforming it into ETHBTC
Best!
I think you're looking for property access. You might want to check if the coin exists first, e.g.
var coin = message.content.toUpperCase().slice(2) + "BTC";
console.log(coin); // logs e.g. "ETHBTC"
binance.prices((error, ticker) => {
if (coin in ticker) {
var price = ticker[coin]; // <- property access
message.reply("Price of " + coin + ": " + price);
} else {
// handle error, e.g.
message.reply("Coin " + coin + " doesn't exist");
}
});

nodejs discord bot - message with words separated by emojis

I'm writing my first Discord bot. I want him to read a users message, and then send the message back, with words separated by emojis. So the effect would be something like this: https://i.stack.imgur.com/ysg4f.png
So this is theoretically working - I say theoretically, because I used completely ridiculous solution just to show what I'm aiming for:
if (message.substring(0, 2) == "m.") {
var args = message.substring(2).trim().split(/ +/g);
var cmd = args.shift().toLowerCase();
switch (cmd) {
// m.clap
case "clap":
bot.sendMessage({
to: channelID,
message:
":clap: " + args[0] + " :clap: " + args[1] + " :clap: " + args[2],
});
break;
}
}
So, obviously, this only works for max. three words sentences, and I need it to work for any length of the sentence.
I tried wrapping the "sendMessage" function in a for loop, iterating from 0 to args.length, but that makes the bot send each word in a separate message, obviously. And it won't let me put a for loop inside of the sendMessage function.
Any help would be greatly appreciated. Thank you!!!
You can use the join() method.
message: ':clap: ' + args.join(':clap: ')

setTimeout for client using command

So what I'm trying to do is create a "cooldown" like system for my discord bot, I've tried using a database method, here which doesn't work for me.
I'm using the discord.js package.
Here is my code:
if (msg.content.startsWith("!point")) {
var usr = msg.content.split(" ").slice(1).join(" ");
if (!usr) {
bot.sendMessage(msg, "```Error: 1\n Reason: Please state a name.```");
return;
}
if (usr == msg.author.username) {
bot.sendMessage(msg, "```Error: 3\n Reason: You're unable to point yourself.```");
return;
}
if (!db["users"][usr]) {
db["users"][usr] = 0;
}
console.log(usr + " has " + db["users"][usr]);
db["users"][usr] += 1;
console.log(usr + " now has " + db["users"][usr]);
fs.writeFileSync('database.json', JSON.stringify(db));
bot.sendMessage(msg, usr + " has received 1 point");
}
Unless it's very important that the cooldown survives a crash, or the cool down is a very long duration I recomend creating an object with keys that are are either channel or user or server id's depending on what you want the rate limit to apply to. Then every time a command is run set that to the current time. Something like
rateLimitObject[msg.author.id] = "current time";
Then whenever someone runs a command just ensure that the current time is greater than the time in the object with that index by more than a certain amount.
If you are looking to just simply stop people from spamming the command something similar to what's used in pvpcraft here may be more ideal.
https://github.com/macdja38/pvpcraft/blob/master/middleware/rateLimits.js

Categories