Getting an image URL from a message - node.js

I want to get the image URL or the image itself from a message, and put it in my embed. I have no idea to do it myself, hope you can help me :)
client.on('messageReactionAdd', (reaction, user, message) => {
const eggsa = client.emojis.find(emoji => emoji.name === "eggsa");
if (reaction.emoji.name === 'eggsa') {
const msg = reaction.message;
const guild = msg.guild;
const guildMembers = guild.members;
const guildMember = guildMembers.get(user.id);
if (!guildMember.roles.some(r=>["Leder"].includes(r.name)) ) return guildMember.send(" ',:^\\ ");
const message = reaction.message;
const kanal = reaction.message.guild.channels.find('name', 'sitater');
var embed = new Discord.RichEmbed()
.setDescription(message.content)
.setTimestamp()
.setFooter(message.author.username, reaction.message.author.avatarURL)
.setImage()
kanal.send({embed});
}
});

You can simply use the .attachments property from the message object. This returns you all attachments of this message included all pictures. From there on, you can use the property .url and this gives you the image url that you can add in your embed.
In the following code I added a check if there are even attachments. If yes, add the first image url as image of the embed.
Here is the code:
client.on('messageReactionAdd', (reaction, user, message) => {
const eggsa = client.emojis.find(emoji => emoji.name === 'eggsa');
if (reaction.emoji.name === 'eggsa') {
const msg = reaction.message;
const guild = msg.guild;
const guildMembers = guild.members;
const guildMember = guildMembers.get(user.id);
if (!guildMember.roles.some(r => ['Leder'].includes(r.name))) return guildMember.send(" ',:^\\ ");
const message = reaction.message;
const kanal = reaction.message.guild.channels.find('name', 'sitater');
const embed = new Discord.RichEmbed()
.setDescription(message.content)
.setTimestamp()
.setFooter(message.author.username, reaction.message.author.avatarURL);
if (message.attachments.size !== 0) {
embed.setImage(message.attachments.first().url);
}
kanal.send({ embed });
}
});

Related

So, I got a question. Is it possible to have a embed welcome message in a Discord bot that gets deleted after a few seconds?

var TOKEN = ""
const client = ("TOKEN");
const { Client, MessageEmbed } = require('discord.js');
const channel = ("CHANNELID");
const embed = new MessageEmbed()
('guildMemberAdd', member => {
const embed = new Discord.RichEmbed()
.setColor('#0099ff')
.setDescription(`Welcome ${member}! You are the ${membercount}th member!`)
.setImage(member.user.avatarURL)
})
That is my current code for this but, I'm unsure because there are some errors to it.
Yes it is possible.
Please don't use this code, it will not work based on how you have it coded now
var TOKEN = ""
const client = ("TOKEN");
const { Client, MessageEmbed } = require('discord.js');
const channel = ("CHANNELID");
const embed = new MessageEmbed()
('guildMemberAdd', member => {
const embed = new Discord.RichEmbed()
.setColor('#0099ff')
.setDescription(`Welcome ${member}! You are the ${membercount}th member!`)
.setImage(member.user.avatarURL)
})
Please use the code below:
// var TOKEN = "" //token is never a variable
// const client = ("TOKEN"); //please find a different way to code this as this will cause confusion later on
const TOKEN = ""
const { Client, MessageEmbed } = require('discord.js');
const client = new Client({
intents: [], // pick the intents you need here https://discord.com/developers/docs/topics/gateway#list-of-intents
})
client.login(TOKEN)
client.on('guildMemberAdd', member => {
const welcomeChannel = client.channels.cache.get("channel_id")
const membercount = member.guild.members.cache.filter(member => !member.user.bot).size
const timeout = 30 * 1000 //30 being how many seconds till the message is deleted.
const embed = new MessageEmbed()
.setColor('#0099ff')
.setTitle(`${member.displayName} has joined us!`)
.setDescription(`Welcome ${member}!\nYou are member number ${membercount}!`)
.setThumbnail(member.displayAvatarURL())
welcomeChannel.send({
embeds: [embed]
}).then((message) => {
setTimeout(() => {
message.delete()
}, timeout);
})
})
Yes, you can!
just use
.then(msg => {
setTimeout(() => {
msg.delete().catch(() => null)
}, 5000)
})

i am makeing a minecraft ping discord bot and it is throwing this error when my server is offline

(node:7548) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'substr' of null
at Client. (C:\Users\RCIIND_4\Desktop\Vs Code\index.js:67:83)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
(Use node --trace-warnings ... to show where the warning was created)
(node:7548) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:7548) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
This is the code
const ms = require('ms')
const fetch = require('node-fetch')
const Discord = require('discord.js')
const client = new Discord.Client()
const config = require('./config.json')
/**
* This function is used to update statistics channel
*/
const updateChannel = async () => {
// Fetch statistics from mcapi.us
const res = await fetch(`https://mcapi.us/server/status?ip=${config.ipAddress}${config.port ? `&port=${config.port}` : ''}`)
if (!res) {
const statusChannelName = `【🛡】Status: Offline`
client.channels.cache.get(config.statusChannel).setName(statusChannelName)
return false
}
// Parse the mcapi.us response
const body = await res.json()
// Get the current player count, or set it to 0
const players = body.players.now
// Get the server status
const status = (body.online ? "Online" : "Offline")
// Generate channel names
const playersChannelName = `【👥】Players: ${players}`
const statusChannelName = `【🛡】Status: ${status}`
// Update channel names
client.channels.cache.get(config.playersChannel).setName(playersChannelName)
client.channels.cache.get(config.statusChannel).setName(statusChannelName)
return true
}
client.on('ready', () => {
console.log(`Ready. Logged as ${client.user.tag}.`)
setInterval(() => {
updateChannel()
}, ms(config.updateInterval))
})
client.on('message', async (message) => {
if(message.content === `${config.prefix}force-update`){
if (!message.member.hasPermission('MANAGE_MESSAGES')) {
return message.channel.send('Only server moderators can run this command!')
}
const sentMessage = await message.channel.send("Updating the channels, please wait...")
await updateChannel()
sentMessage.edit("Channels were updated successfully!")
}
if(message.content === `${config.prefix}stats`){
const sentMessage = await message.channel.send("Fetching statistics, please wait...")
// Fetch statistics from mcapi.us
const res = await fetch(`https://mcapi.us/server/status?ip=${config.ipAddress}${config.port ? `&port=${config.port}` : ''}`)
if (!res) return message.channel.send(`Looks like your server is not reachable... Please verify it's online and it isn't blocking access!`)
// Parse the mcapi.us response
const body = await res.json()
const attachment = new Discord.MessageAttachment(Buffer.from(body.favicon.substr('data:image/png;base64'.length), 'base64'), "icon.png")
const embed = new Discord.MessageEmbed()
.setAuthor(config.ipAddress)
.attachFiles(attachment)
.setThumbnail("attachment://icon.png")
.addField("Version", body.server.name)
.addField("Connected", `${body.players.now} players`)
.addField("Maximum", `${body.players.max} players`)
.addField("Status", (body.online ? "Online" : "Offline"))
.setColor("#FF0000")
.setFooter("Open Source Minecraft Discord Bot")
sentMessage.edit(`:chart_with_upwards_trend: Here are the stats for **${config.ipAddress}**:`, { embed })
}
})
client.login(config.token)
This is the updated code
const ms = require('ms')
const fetch = require('node-fetch')
const Discord = require('discord.js')
const client = new Discord.Client()
const config = require('./config.json')
/**
* This function is used to update statistics channel
*/
const updateChannel = async () => {
// Fetch statistics from mcapi.us
const res = await fetch(`https://mcapi.us/server/status?ip=${config.ipAddress}${config.port ? `&port=${config.port}` : ''}`)
if (!res) {
const statusChannelName = `【🛡】Status: Offline`
client.channels.cache.get(config.statusChannel).setName(statusChannelName)
return false
}
// Parse the mcapi.us response
const body = await res.json()
// Get the current player count, or set it to 0
const players = body.players.now
// Get the server status
const status = (body.online ? "Online" : "Offline")
// Generate channel names
const playersChannelName = `【👥】Players: ${players}`
const statusChannelName = `【🛡】Status: ${status}`
// Update channel names
client.channels.cache.get(config.playersChannel).setName(playersChannelName)
client.channels.cache.get(config.statusChannel).setName(statusChannelName)
return true
}
client.on('ready', () => {
console.log(`Ready. Logged as ${client.user.tag}.`)
setInterval(() => {
updateChannel()
}, ms(config.updateInterval))
})
client.on('message', async (message) => {
if(message.content === `${config.prefix}force-update`){
if (!message.member.hasPermission('MANAGE_MESSAGES')) {
return message.channel.send('Only server moderators can run this command!')
}
const sentMessage = await message.channel.send("Updating the channels, please wait...")
await updateChannel()
sentMessage.edit("Channels were updated successfully!")
}
if(message.content === `${config.prefix}stats`){
const sentMessage = await message.channel.send("Fetching statistics, please wait...")
// Fetch statistics from mcapi.us
const res = await fetch(`https://mcapi.us/server/status?ip=${config.ipAddress}${config.port ? `&port=${config.port}` : ''}`)
if (!res) return message.channel.send(`Looks like your server is not reachable... Please verify it's online and it isn't blocking access!`)
// Parse the mcapi.us response
const body = await res.json()
let embed = new Discord.MessageEmbed()
.setAuthor(config.ipAddress);
if (attachment) { new Discord.MessageAttachment(Buffer.from(body.favicon.substr('data:image/png;base64,'.length), 'base64'), "icon.png")
embed = embed.attachFiles(attachment);
}
embed = embed.setThumbnail("attachment://icon.png")
.addField("Version", body.server.name)
.addField("Connected", `${body.players.now} players`)
.addField("Maximum", `${body.players.max} players`)
.addField("Status", (body.online ? "Online" : "Offline"))
.setColor("#FF0000")
.setFooter("Open Source Minecraft Discord Bot");
sentMessage.edit(`:chart_with_upwards_trend: Here are the stats for **${config.ipAddress}**:`, { embed })
}
})
client.login(config.token)
body.favicon is null, but you're trying to use it here:
body.favicon.substr(...)
If it's possible for this value to be null (and it clearly is) then you can't assume it'll have a value. You have to check first. From there, you need to decide what you want your code to do when this value is null. For example, you can add a null check like this:
const attachment = body.favicon ? new Discord.MessageAttachment(Buffer.from(body.favicon.substr('data:image/png;base64'.length), 'base64'), "icon.png") : null;
This uses the ?: conditional operator to check if body.favicon has a value. If it does, proceed as the code currently does. If it has no value, set attachment to null.
From there you need to decide what to do when attachment is null. You probably can't use it in the Discord API like that. So you might wrap some logic in conditional checks here too:
let embed = new Discord.MessageEmbed()
.setAuthor(config.ipAddress);
if (attachment) { // <--- here
embed = embed.attachFiles(attachment)
.setThumbnail("attachment://icon.png");
}
embed = embed.addField("Version", body.server.name)
.addField("Connected", `${body.players.now} players`)
.addField("Maximum", `${body.players.max} players`)
.addField("Status", (body.online ? "Online" : "Offline"))
.setColor("#FF0000")
.setFooter("Open Source Minecraft Discord Bot");
UPDATE
In your updated code you have removed the definition of attachment entirely. That would certainly simplify the problem. If that's what you want to do then you also need to remove any code which uses attachment. For example:
let embed = new Discord.MessageEmbed()
.setAuthor(config.ipAddress);
.addField("Version", body.server.name)
.addField("Connected", `${body.players.now} players`)
.addField("Maximum", `${body.players.max} players`)
.addField("Status", (body.online ? "Online" : "Offline"))
.setColor("#FF0000")
.setFooter("Open Source Minecraft Discord Bot");

Sending a newly created emoji after guild.emojis.create()

I have an addemoji command and I want it to send the new emoji created after the bot creates it. It sends like :emojiname: instead of the actual emoji added. How can I define the new emoji added? Somebody suggested that I use console.log but I have no idea how to use that information that it puts inside the log.
module.exports = {
name: 'addemoji',
description: 'ping pong',
execute(message, args) {
const Discord = require('discord.js');
const PREFIX = 'ly?';
const load = '<a:loading:824515478939762699>';
if (message.content.startsWith(PREFIX + 'addemoji')) {
if (message.guild.me.permissions.has('USE_EXTERNAL_EMOJIS')) {
if (message.guild.me.permissions.has('MANAGE_EMOJIS')) {
if (message.member.hasPermission('MANAGE_EMOJIS')) {
const match = /<(a?):(.+):(\d+)>/u.exec(message.content);
if (!match)
return message.reply(
'Please include a custom emoji in your message!',
);
// animated will be 'a' if it is animated or '' if it isn't
const [, animated, name, id] = match;
const url = `https://cdn.discordapp.com/emojis/${id}.${
animated ? 'gif' : 'png'
}`;
const user = message.mentions.users.first() || message.author;
const nameid = `<:${name}:${id}>`;
message.guild.emojis.create(url, name);
let newname = console.log(name);
let newid = console.log(id);
const embed = new Discord.MessageEmbed()
.setTitle(`Emoji added! <:${newname}:${newid}>`)
.setColor(0x7732a8);
message.channel.send(embed);
}
}
}
}
}
};
GuildEmojiManager#create() returns a Promise with the newly created emoji. You can access and display the new emoji by handling this promise, then using the <:name:id> wrapper for emoijs
message.guild.emojis.create(url, name).then(newEmoji => {
const embed = new Discord.MessageEmbed()
.setTitle(`Emoji added! <:${newEmoji.name}:${newEmoji.id}>`)
.setColor(0x7732a8)
message.channel.send(embed);
});

Making reactions with Partial Events

I've made a code for verify command, it's reacting to certain embed. But when I reboot the bot won't recognize it, so users can still react but won't get role at all. I've heard I can use Partial Event but I don't want to make it inside index.js.
Code:
let wembed = new Discord.MessageEmbed()
.setAuthor("Test")
.setColor("PURPLE")
.setDescription(arg1)
const reactmessage = await client.channels.cache.get(chx).send(wembed)
await reactmessage.react('✅');
const filter = (reaction, user) => reaction.emoji.name === '✅' && !user.bot;
const collector = reactmessage.createReactionCollector(filter);
collector.on('collect', async reaction => {
const user = reaction.users.cache.last();
const guild = reaction.message.guild;
const member = guild.member(user) || await guild.fetchMember(user);
member.roles.add("725747028323205170");
});
If there is a way of doing this help would be appreciated!
https://discordjs.guide/popular-topics/partials.html#enabling-partials
index.js:
const client = new Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] });
your messageReactionAdd file:
module.exports = async (reaction, user) => {
if(reaction.partial) await reaction.fetch();
}
Now all reactions are sent to messageReactionAdd, now you just have to validate the reaction and add the role if it corresponds to the right emoji and the right message

Values get overwritten by latest person to request the bot?

I have made a raffle ballot discord bot that allows a user to DM the bot their name and raffle entry amount. Once they have set the values they can start the entry of the raffle by DMing !enter. Once this has happend a function is called which then starts a for-loop the for loop will run based on the specified entry amount. I have also added in a delay within the for-loop due to the service to get the raffle tickets takes some time (Code is edited for SO Post due to sensitive API info)
Once this is complete it then sends a DM back to the user that had DMed the bot originally. The problem I am facing is that if multiple users DM at the same time or while it is running from the first DM the variables get overwritten by the latest person requesting the bot.
I assumed that by using a Discord.js bot each time a user DMs it creates a new instance of the script or node process?
Is it possible for the function that the bot calls once DMed to create a new process within the main node process so it doesn't get overwritten?
const Discord = require('discord.js');
const botconfig = require('./discordBotConfig.json');
const bot = new Discord.Client({disableEveryone: true});
const c = require('chalk');
// Chalk Theme
const ctx = new c.constructor({level: 2});
const error = c.red;
const waiting = c.magenta;
const success = c.green;
const discordBot = c.yellow;
// Current Raffles (API Link Later)
let activeRaffles = 'Raffle 1';
// User Parmas
let usrName = '';
let entryAmount = 0;
// Ticket
let raffleTicket = [];
let retryDelay = 3000;
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Enter
const enterIn = async () => {
console.log('User name', usrName);
raffleTicket.push(Math.random(0, 50));
}
// Init Raffle Entry
const raffleInit = async (entryAmount) => {
for (let i = 0; i < entryAmount; i++) {
enterIn();
await sleep(retryDelay);
}
dmUser();
}
const dmUser = () => {
// Discord Message Complete
let botCompleteMsg = new Discord.RichEmbed()
.setTitle('Finished!')
.setColor('#25E37A')
.addField('Name: ', usrName)
.addField('Tickets: ', raffleTicket)
.addField('Last Update: ', bot.user.createdAt);
bot.fetchUser(userID).then((user) => {
user.send(botCompleteMsg);
});
return; // End the application
}
// Discord Bot Setup
bot.on('ready', async () => {
console.log(discordBot(`${bot.user.username} is Online!`));
bot.user.setActivity('Entering Raffle');
});
bot.on('message', async message => {
if (message.channel.type === 'dm') {
let prefix = botconfig.prefix;
let messageArray = message.content.split(' ');
let cmd = messageArray[0];
if (cmd === `${prefix}name`) {
if (messageArray.length === 3) {
userID = message.author.id;
usrName = messageArray[1];
entryAmount = messageArray[2];
// Raffle summary
let raffleSummary = new Discord.RichEmbed()
.setTitle('Entry Summary')
.setColor('#8D06FF')
.addField('Name: ', usrName)
.addField('Entry Amount: ', entryAmount)
return message.author.send(raffleSummary), message.author.send('Type **!start** to begin entry or type **!set** again to set the entry details again.');
}
}
if (cmd === `${prefix}enter`) {
// Raffle summary
let startMessage = new Discord.RichEmbed()
.setTitle('Entering raffle!')
.setDescription('Thanks for entering! :)')
.setColor('#8D06FF')
return message.author.send(startMessage), raffleInit(entryAmount);
}
}
});
bot.login(botconfig.token);
You can store your user data in a list with classes.
var userData = [
{name: "sample#0000", entryNum: 0}
];

Resources