discord bot problem embed thumbnail attachment - javascript

I am not very experienced in javascript and I have a problem to display my attached image.
when someone type #1 bot send an embed with caracteristics and i want post the image too !
I don't know if I formatted it wrong or if I should load the image first. So the image is my local folder in the same directory as my index.js file
I had problems with color too! I didn't manage to modify it! I didn't manage to modify it
I would have liked to be able to change the color of the name title or description but I don't know if it's possible my tests were unsuccessful
Could you help me a little bit please? Here is my code. Thanks in advance.
const { token, prefix } = require('../config.json');
const Discord = require('discord.js');
const client = new Discord.Client();
// Listen to the Bot being ready
client.once('ready', () => onClientReady());
function onClientReady()
{
// Listen to Messages in the channel
client.on('message', (message) => onMessageReceived(message));
}
// Upon a message being received, handle how we interact
function onMessageReceived(message)
{
if(message.author.bot) return;
if (message.content.toLowerCase().includes('#1'))
message.channel.send({ embed: {
color: 3447003,
title: "SpaceShips #1 New_York",
url: "http://google.com",
description: "RANK: 74 / SCORE: 121",
Thumbnail: (url="attachment://000793.jpg"),
fields: [{
name: "__**POWER**__",
value: "A-G 0: **39**",
"inline": true
},
{
name: "__**POWER**__",
value: "E-W: **76**",
"inline": true
},
{
name: "__**AUTONOMY**__",
value: "EY-W Nrg: **74**",
"inline": true
},
{
name: "__**AUTONOMY**__",
value: "B-P 0 Nrg: **73**",
"inline": true
},
{
name: "__**DISPLACEMENT**__",
value: "L-A: **79**",
"inline": true
},
{
name: "__**DISPLACEMENT**__",
value: "3D-V: **67**",
"inline": true
},
{
name: "__**SPECIALS**__",
value: "EM-W: **34**",
"inline": true
},
{
name: "__**SPECIALS**__",
value: "3D-W: **42**",
"inline": true
}
],
}
});
}
client.login(token);

If your working with python, and just want to send an image, try this:
await channel.send(file=discord.File('my_image.png'))

You may simply add an image value to the embed object you're sending like so:
message.channel.send({ embed: {
color: 3447003,
title: "SpaceShips #1 New_York",
url: "http://google.com",
description: "RANK: 74 / SCORE: 121",
thumbnail: {
url: "attachment://000793.jpg"
},
}
}); // Removed fields to clear up the clutter, you may add them like before!
As far as color is concerned it's a RGB value you may Google up the value for the colour you like and replace it!

If you want only send the image then here i suppose (Node.Js)
const path = require('path');
const Discord = require('discord.js');
let pic = path.resolve('test.jpg')
// the picture, if you console.log it will send the path of the file for example mine /src/image/test.jpg
message.channel.send(new Discord.MessageAttachment(pic))

In fact it isn't possible in local to put an image in a embed... we only can put attach file...
Si I used an web link and hosted my images on a server and it works!
Thanks for your help.

Related

Why do I get channels link instead of attachment?

I'm trying to make a bot. When I type ".test" bot waits for a file. After receiving it, he must send me a Discord link from which I can download the same file. But he only refers to the message where I've sent the file.
Before that, I somehow did it and started experimenting something. After that I was unable to get the same result.
There is my code:
module.exports = {
commands: 'test',
callback: (message, arguments, text) => {
const msg_filter = (m) => m.author.id === message.author.id;
message.channel.awaitMessages({ filter: msg_filter, max: 1, time: 60000})
.then((collected) => {
console.log(collected.first())
console.log(collected.first().attachment)
console.log(collected.first().url)
console.log("finish")
}).catch('Error. No respond.')
}
}
Console output:
//First
attachments: Collection(1) [Map] {
'myId' => MessageAttachment {
attachment: 'https://cdn.discordapp.com/attachments/914907287603261510/myId/sample.pdf',
name: 'sample.pdf',
id: 'myId',
size: 3028,
url: 'https://cdn.discordapp.com/attachments/914907287603261510/myId/sample.pdf',
proxyURL: 'https://media.discordapp.net/attachments/914907287603261510/myId/sample.pdf',
height: null,
width: null,
contentType: 'application/pdf',
ephemeral: false
}
},
//Second
undefined
//Third
https://discord.com/channels/901476184532062209/914907287603261510/917789424857780224
collected is a collection that contains every message that got caught by channel.awaitMessages(), so collected.first() is a message.
To access this message's attachments, which is a collection, you would need to do collected.first().attachments (beware of the plural).
With this in mind, you can manage every attachment in a for-each loop, or just get the first attachment via collected.first().attachments.first()

Keep repeating the prompter questions with Inquirer.js based on answer?

I'm using Inquirer.js to create a CLI's prompter which allows users to enter/reply to some input/questions. In the last question, I want to add a feature that if the user replies no to Are you done? question, then the prompter will restart asking the questions until the user replies yes. I'm almost there with the functionality.
It's working, but only on the first time when I enter no. The second time I enter no, the prompter stops.
How can I run this on a loop to accomplish the desired behavior? What I'm doing wrong?
This is what I have some far:
import inquirer from 'inquirer';
inquirer
.prompt([
// { bunch of other questions previously },
{
type: 'confirm',
name: 'repeat_questions',
message: 'Are you done?',
},
])
.then((answers) => {
if (answers.repeat_questions) {
return inquirer.prompt([
// { bunch of other questions previously },
{
type: 'confirm',
name: 'repeat_questions',
message: 'Are you done?',
},
]);
}
})
.catch((error) => {
if (error.isTtyError) {
throw new Error(`Prompt couldn't be render in current environment`);
}
});
One way is a recursive function:
import inquirer from "inquirer";
const questions = [
{
type: "number",
name: "children_count",
message: "How many children do you have?",
},
{
type: "input",
name: "first_child_name",
message: "What is the eldest child's name?",
},
{
type: "confirm",
name: "is_finished",
message: "Are you done?",
},
];
function getAnswers() {
return inquirer.prompt(questions).then((answers) => {
if (answers.is_finished) {
return answers;
} else {
return getAnswers();
}
});
}
getAnswers()
.then(console.log)
.catch((error) => {});
The variable repeat_questions doesn't make sense, if the user says no to if they are done, repeat_questions is also no. So instead I renamed it to is_finished.

Is there a way of making "embed pages" with Object-based embeds? (Discord.js)

I've been looking around for a way to make embed pages with discord.js but all of the tutorials I've seen are for a MessageEmbed. I would like to have some way to react to the embed and have it switch to the next.
This is my original code:
client.on('message', (message) => {
if (message.content.toLowerCase() == prefix + "help") {
const Embed = {
color: 0x91A6A6,
title: 'Help Menu. Page 1.',
author: {
name: 'KLSB',
icon_url: bot.user.avatarURL()
},
description: '\n How to use KLSB. \n',
fields: [
{
name: '!-help',
value: 'Opens a help menu.',
inline: true,
},
{
name: '!-cat',
value: 'Grabs a random cat picture from the internet.',
inline: true,
},
{
name: '!-dog',
value: 'Grabs a random dog picture from the internet.',
inline: true,
},
{
name: '!-panda',
value: 'Grabs a random panda picture from the internet.',
inline: true,
},
{
name: '!-bird',
value: 'Grabs a random panda picture from the internet.',
inline: true,
},
{
name: '!-meme',
value: 'Finds a meme from Reddit.',
inline: true,
},
{
name: '!-animememe',
value: 'Finds a anime meme from Reddit.',
inline: true,
},
{
name: '!-animalmeme',
value: 'Finds a animal meme from Reddit.',
inline: true,
},
{
name: '!-hug',
value: "Sends a hug through the internet!",
inline: true,
},
{
name: '!-8ball',
value: "As they say, it sees the future!",
inline: true,
},
],
};
message.channel.send({ embed: Embed });
}})
If anyone has some examples, please share them with me (and it would help if you could explain what's happening :D)
Yes, it is possible. The one I'm going to show you uses reaction collectors to control which page to go to. You can modify it accordingly to fit with your pages needs, but this is the basic gist.
I first set up an array called Pages that would be what you wrote in the description, you can add additional arrays accordingly for your titles and whatnot. I also have page set to one since that's the default page and it will be the counter of which page the user is currently on.
There's multiple steps to show how this works:
Create initial embed + send embed (which I see you have already done, but you'll need to modify it accordingly to fit with the pages array.
Then add the reactions (I chose :rewind: and :fast_forward:. Note: Do not simply just copy them from the Discord channel, as I have learned here.)
Then create two separate filters, one for each ReactionCollector. I've labeled mine isBackwards and isForwards accordingly.
Create a ReactionCollector for both forwards and backwards.
I've labeled mine backwards and forwards
Then inside of each event handler, I just shifted the page and the descriptions and whatnot, and edited the embed accordingly.
Note: The second reaction takes a while to load. I haven't found a function where you can put both embeds at the same time... so it might take a while for the second embed to pop up.
Code:
//pages is very flexible, as long as you change the array at the top you're set
let pages = ["Page one", "Page two", "Page three", "Page four"];
let page = 1;
if (message.content.startsWith("!embed")) {
const embed = new Discord.MessageEmbed()
.setColor(0xffffff) //sets color here
.setFooter(`Page ${page} of ${pages.length}`)
.setDescription(pages[page - 1])
message.channel.send(embed).then(msg => {
msg.react('⏪').then(r => {
msg.react('⏩');
//filters
const isBackwards = (reaction, user) => reaction.emoji.name === '⏪' && user.id === message.author.id;
const isForwards = (reaction, user) => reaction.emoji.name === '⏩' && user.id === message.author.id;
const backwards = msg.createReactionCollector(isBackwards);
const forwards = msg.createReactionCollector(isForwards);
backwards.on("collect", r => {
if (page === 1) return;
page--;
embed.setDescription(pages[page - 1]);
embed.setFooter(`Page ${page} of ${pages.length}`);
msg.edit(embed)
});
forwards.on("collect", r => {
if (page === pages.length) return;
page++;
embed.setDescription(pages[page - 1]);
embed.setFooter(`Page ${page} of ${pages.length}`);
msg.edit(embed)
});
});
});
}

Disord js bot user-info issue

I'm trying to create a bot, and one of its commands is user-info
for eg. !user-info #<username>
and i want it to display username, id and the avatar
like:
username:<username>
Id:<User Id>
Avatar:<the avatar >
Below is the code i used:
else if (message.content.startsWith(`${prefix}user-info`)) {
var member = message.mentions.users.first();
message.channel.send(`Username: ${member.username}\n ID:${member.id}\n Avatar:${member.displayAvatarURL()}` );
}
However it doesn't work, when i remove the avatar part the output comes out as :
Username:undefined
Id:<the id>
When I add the avatar part I just get a huge error on the command module when I use the bot command. What's the right way and what did I get wrong?
I'd suggest you use an Embed for this, as those can display images in a better way, the code for your request would be:
var user = message.mentions.users.first();
message.channel.send({
embed: {
title: `Profile of ${user.tag}`,
thumbnail: {
url: user.displayAvatarURL(),
},
fields: [
{
title: "ID:",
value: user.id
}
]
}
});
You can find more on this here

Cannot get Discord.js to embed THEN delete

EDIT: Trying to make it more clear. I want the embed listed below in the part where it says EMBED GOES HERE.
Unsure if i can even do that. My structure is calling externally for files named in example: test.js through swap args. Creating a very rough command handler.
module.exports = {
name: 'test',
description: "Embed",
execute(message, args){
message.delete();
message.channel.send(`**EMBED GOES HERE**`).then(async sentMessage => {
await sentMessage.delete({ timeout: 10000 });
});
}
}
Where this is the embed.
"embed": {
"title": "Test",
"thumbnail": 'google.com',
"url": "google.com",
"description": 'test',
"color": 16763981,
"footer": {
}
An embed is a specially formatted JSON object, which can be easily assigned to any variable. However, the data portion of channel.send is also an object, so in the end it will be an object nested in an object. (The second one, I will create inline) This may be a bit confusing, because an embed is an option, not part of the content.
let myEmbed = {
title: "Test",
thumbnail: { url: 'google.com'},
url: "google.com",
description: 'test',
color: 16763981,
footer: { }
};
message.channel.send({embed: myEmbed }).then(async sentMessage => {
await sentMessage.delete({ timeout: 10000 });
message.delete();
});

Categories