What I did was use code from another command which does work. The command grabs images from a link then pastes them in the chat. I have made 3 other commands which post things such as hug | kiss | bye, etc... I thought I can simply add a similar thing for NSFW commands but that doesn't seem to be the case. The command partially works the text goes through but doesn't respond with an image like other commands.
Here are a few examples of the output for the command
Image of the output for discord command
[![enter image description here][1]][1]
Here is the code for the command that does not work
const fetch = require('node-fetch');
const config = require('../../config.js');
module.exports = {
config: {
name: "lewd",
aliases: [""],
category: "nsfw",
description: "Sends an NSFW image ;)",
usage: `${config.PREFIX}cat`,
},
run: async (bot, message, args) => {
const res = await fetch('https://gallery.fluxpoint.dev/api/nsfw/lewd');
const img = (await res.json()).link;
const embed = new Discord.MessageEmbed()
.setTitle(`OwO`)
.setImage(img)
.setFooter(`Requested ${message.member.displayName}`, message.author.displayAvatarURL({ dynamic: true }))
.setTimestamp()
.setColor(message.guild.me.displayHexColor);
message.channel.send(embed);
}
}
If you need the code that does work and output an image here it is
const fetch = require('node-fetch');
const config = require('../../config.js');
module.exports = {
config: {
name: "hug",
aliases: [""],
category: "images",
description: "hug",
usage: `${config.PREFIX}cat`,
},
run: async (bot, message, args) => {
const res = await fetch('https://some-random-api.ml/animu/hug');
const img = (await res.json()).link;
const embed = new Discord.MessageEmbed()
.setTitle(`;)`)
.setImage(img)
.setFooter(`Requested ${message.member.displayName}`, message.author.displayAvatarURL({ dynamic: true }))
.setTimestamp()
.setColor(message.guild.me.displayHexColor);
message.channel.send(embed);
}
} ```
[1]: https://i.stack.imgur.com/UjIwV.png
Related
I am trying to make a command to send an embed but I can't figure out how to customize an embed using arguments
const { MessageEmbed } = require("discord.js")
module.exports = {
category: 'Role Select Msg',
description: 'Sends a embeded message for roles or for announcemnts',
permissions: ['ADMINISTRATOR'],
slash: 'both',
guildOnly: true,
minArgs: 2,
expectedArgs: '<channel> <text>',
expectedArgsTypes: ['CHANNEL', 'STRING'],
callback: ({ message, interaction, args }) => {
const channel = message ? message.mentions.channels.first() : interaction.options.getChannel('channel')
const description = interaction.options.getString('text')
if (!channel || channel.type !== 'GUILD_TEXT'){
return 'Please tag a text channel.'
}
const embed = new MessageEmbed()
.setDescription(description)
channel.send(embed)
if(interaction){
interaction.reply({
content: 'Sent message!',
ephemeral: true
})
}
}
}
I want to customize something like a title or description based on what someone that used the command input for .
I have figured out the easiest way that I have found to customize an embed using user input is just to use args[] and pass in the array placement of the expected args.
const { MessageEmbed } = require("discord.js")
module.exports = {
category: 'Role Select Msg',
description: 'Sends a embeded message for roles or for announcemnts',
permissions: ['ADMINISTRATOR'],
slash: 'both',
guildOnly: true,
testOnly: true,
minArgs: 2,
expectedArgs: '<channel> <title>',
expectedArgsTypes: ['CHANNEL', 'STRING'],
callback: async ({ interaction, args }) => {
const channel = interaction.options.getChannel('channel')
if (!channel || channel.type !== 'GUILD_TEXT'){
return 'Please tag a text channel.'
}
const embed = new MessageEmbed()
.setTitle(args[1])
channel.send({embeds: [embed]})
return `Message sent to ${channel}`
if someone put in any text for the <.text.> expected arg it will set it as the title with no issue.
for a normal message command you can use args or split and collector for example:
// Defining the channel you want to send the embed to
const channel = await message.mentions.channels.first() || message.guild.channels.cache.get(args[0]) || message.channel;
// Defining the first embed
const embed = new MessageEmbed()
.setDescription(`Please type your title and description separated by a \`+\`, __example:__ Title+Description`)
const msg = await message.channel.send({embeds: [embed]})
// Using message collector to collect the embed's title and description
const filter = m => m.author.id === message.author.id //Filter the message of only the user who run the command
message.channel.awaitMessages({
filter,
max: 1,
time: 120000,
errors: ["time"]
}).then(async collected => {
const msgContent = collected.first().content
const embedFields = msgContent.split('+'); // You can use any symbol to split with not only +
const customEmbed = new MessageEmbed()
.setTitle(`${embedFields[0]}`)
.setDescription(`${embedFields[1]}`)
.setFooter({text: `${embedFields[2]}`})
channel.send({embeds: [customEmbed]}) // send the embed to the channel
message.reply({content: `Your embed was sent to ${channel}`})
}) // reply to the main command
If it was an interaction command, You can use Options:
// Defining the options
const channel = interaction.options.getChannel('channel')
const title = interaction.options.getString('title') // Title of the embed
const descr = interaction.options.getString('description') // Description for the embed
// You can add also add a custom footer:
const footer = interaction.options.getString('footer')
//Now it's simpler than using a normal message command
const customEmbed = new MessageEmbed()
.setTitle(`${title}`)
.setDescription(`${descr}`)
.setFooter({text: `${footer}`})
channel.send({embeds: [customEmbed]})
interaction.reply({content: `Your embed was sent to ${channel}`, ephemeral: true}) // reply to your interaction
// Of course you need to add the options to the interaction, and check it required option or not
Example of the output:
https://i.imgur.com/T1QAqg1.png
After doing some trial and error, I've found one of some solutions for your problem.
if(message.author.id == "") {
const embed = new MessageEmbed()
.setDescription("To create a customized embed, you need to do an `args[0]` and `args[1]`")
.setColor('RANDOM')
.setTimestamp()
message.channel.send({embeds: [embed]})
const msg_filter = (m) => m.author.id === message.author.id;
const collector = await message.channel.createMessageCollector({filter: msg_filter, max: 2, timer: 15000})
collector.on('end', collected => {
let i = 0;
collected.forEach((value) => {
i++;
if (i === 1) embed.setTitle(value.content);
else if (i === 2) embed.setDescription(value.content);
})
console.log(i)
message.channel.send({embeds: [embed]});
})
} else {
return message.reply("```Only the Developer Can use these command.```")
}
To achieve these kind of command, You need to use a collector function
See more here
Using max: 2 makes it to wait for two args which is the arsg[0] and args[1], Then use any ++ so you can make it to equal for .setTitle and .setDescription
I have been getting an error as mentioned in the title. Whenever I use that command, the bot creates a channel that brings up a select menu, through which the user can "teleport" to another channel while deleting the newly created channel in the process. This code successfully works twice, after which it gives the error. What should be done to fix the error so that the user can use the command as many times as they'd like? I'll work on this code further once the solution is found, but until then, I'm really stumped here. (Questions shall be answered upon questioning; apologies for the messy coding)
module.exports.run = async (client, msg, args) => {
const guild = client.guilds.cache.get('855845132879921214')
const channel = guild.channels.cache.get('959851265456734319')
const newChannel = await msg.guild.channels.create(`teleporter`)
await newChannel.permissionOverwrites.edit(msg.author.id, {
SEND_MESSAGES: false,
VIEW_CHANNEL: true,
})
const {MessageActionRow, MessageSelectMenu, MessageEmbed} = require('discord.js')
const embed = new MessageEmbed()
.setTitle(`Teleporter!`)
.setDescription("Through this interaction, you can now teleport to the main channel of the desired category!")
const row = new MessageActionRow()
.addComponents(
new MessageSelectMenu()
.setCustomId('teleport')
.setPlaceholder('Choose a channel')
.addOptions([
{
label: 'Rules',
description: "Click to check the rules",
value: 'rules',
},
{
label: 'General',
description: "Click to go to the main chat",
value: 'general',
},
{
label: 'Media',
description: "Click to go to media channel",
value: 'media',
},
{
label: 'Bots',
description: "Click to go to the bots channel",
value: 'bots',
}
]),
)
await newChannel.send({content: `<#${msg.author.id}>`,embeds: [embed], components: [row]})
const wait = require('util').promisify
client.on('interactionCreate', async interaction => {
const member = await interaction.guild.members.fetch({
user: interaction.user.id,
force: true
})
if(!interaction.isSelectMenu()) {
interaction.deferUpdate()}
else if (interaction.values == 'general'){
msg.member.roles.add('958421069650337822')
msg.member.roles.remove('943159431800172584')
let tele = msg.guild.channels.cache.find(channel => channel.name == 'teleporter')
tele.delete()
msg.member.roles.add('943159431800172584')
msg.member.roles.remove('958421069650337822')
}
}
)
}
Don't cache.find and delete, do it like;
const newChannel = await client.channels.fetch("id")
newChannel.delete()
This code should be separated with the first section as your command and the second part as a separate listener, so I have coded as such.
const {
MessageActionRow,
MessageSelectMenu,
MessageEmbed,
} = require('discord.js');
module.exports.run = async (client, msg, args) => {
const guild = client.guilds.cache.get('855845132879921214');
const channel = guild.channels.cache.get('959851265456734319');
const newChannel = await msg.guild.channels.create(`teleporter-${msg.author.username}`, {
permissionOverwrites: [{
id: guild.id,
deny: ["VIEW_CHANNEL"],
}, {
id: msg.author,
deny: ["SEND_MESSAGES"],
allow: ["VIEW_CHANNEL"],
}],
});
// In the event that more than one person uses this command at once, you will need to be able to tell the diffrence when you look up the channel later. So I added the username to the channel name.
const embed = new MessageEmbed()
.setTitle(`Teleporter!`)
.setDescription("Through this interaction, you can now teleport to the main channel of the desired category!");
const row = new MessageActionRow()
.addComponents(
new MessageSelectMenu()
.setCustomId('teleport')
.setPlaceholder('Choose a channel')
.addOptions([{
label: 'Rules',
description: "Click to check the rules",
value: 'rules',
}, {
label: 'General',
description: "Click to go to the main chat",
value: 'general',
}, {
label: 'Media',
description: "Click to go to media channel",
value: 'media',
}, {
label: 'Bots',
description: "Click to go to the bots channel",
value: 'bots',
}]),
);
await newChannel.send({
content: `${msg.author}`,
embeds: [embed],
components: [row],
});
};
This section would go either in the main bot.js file, or if you have your events in seperate files, it would go in the interactionCreate file (may need to be changed a bit if you don't have one, let me know)
const wait = require('util').promisify;
client.on('interactionCreate', async interaction => {
const member = interaction.member;
const guild = interaction.guild;
if (interaction.isSelectMenu()) {
const menuName = interaction.customId;
interaction.deferUpdate();
if (menuName === 'teleport') {
const tele = guild.channels.cache.find(channel => channel.name == `teleporter-${member.user.username}`);
// lookup the channel using the previously mentioned channel name setup
const choice = interaction.value;
if (choice === 'general') {
member.roles.add('958421069650337822');
member.roles.remove('943159431800172584');
} else if (choice === 'rules') {
member.roles.add('roleID');
member.roles.remove('roleID');
} else if (choice === 'media') {
member.roles.add('roleID');
member.roles.remove('roleID');
} else if (choice === 'bots') {
member.roles.add('roleID');
member.roles.remove('roleID');
}
tele.delete();
}
}
});
Hi can someone help me I have this error when I run my command lyrics: DiscordAPIError: Cannot send an empty message
(it's a music bot that uses a command handler)
you can contact me on discord : R Λ Z#9217
const { MessageEmbed } = require("discord.js");
const lyricsFinder = require("lyrics-finder");
module.exports = {
name: "lyrics",
aliases: ['ly'],
category: "Music",
description: "View the lyrics of a song",
args: false,
usage: "",
permission: [],
owner: false,
player: true,
inVoiceChannel: true,
sameVoiceChannel: true,
execute: async (message, args, client, prefix) => {
const player = message.client.manager.get(message.guild.id);
if (!player.queue.current) {
let thing = new MessageEmbed()
.setColor("RED")
.setDescription("There is no music playing.");
return message.channel.send(thing);
}
let lyrics = null;
const title = player.queue.current
try {
lyrics = await lyricsFinder(player.queue.current.title, "");
if (!lyrics) lyrics = `No lyrics found for ${title}.`, { title: title }
} catch (error) {
lyrics = `No lyrics found for ${title}.`, { title: title }
}
let lyricsEmbed = new MessageEmbed()
.setTitle(`${title} - Lyrics`, { title: title })
.setDescription(`${lyrics}`)
.setColor("#F8AA2A")
.setTimestamp();
if (lyricsEmbed.description.length >= 2048)
lyricsEmbed.description = `${lyricsEmbed.description.substr(0, 2045)}...`;
return message.channel.send(lyricsEmbed).catch(console.error);
}
};
Updating to v13 will cause a lot of errors because of breaking changes!
You can find them all listed in the guide right here.
But in your case, it was about how Discord.js handles parameters with the channel.send().
- channel.send(embed);
+ channel.send({ embeds: [embed, embed2] });
- channel.send('Hello!', { embed });
+ channel.send({ content: 'Hello!', embeds: [embed, embed2] });
So right now i am trying to make a info command,almost everything is working fine but i'm getting stuck on how to get all the roles of a user.
My info command should show when the account got created,the user name,the user nickname,the user profile picture his id and of course his role.
I have tried several times to get the user roles with "different" method but it never worked...
Here's my code:
const { MessageEmbed } = require("discord.js");
module.exports.run =(client, message, args) => {
const user_mention = message.mentions.users.first();
if (!args.length) {
const user = message.author
const target = message.guild.member(user);
const mrole = target.roles.filter(r => r.name !== '#everyone').map(role => role.name).join(' | ')
const embed = new MessageEmbed()
.setColor("RANDOM")
.setThumbnail(message.author.avatarURL())
.addField(`Account Created the:`, ` ${message.author.createdAt}`)
.addField(`User name: `, message.author.tag)
.addField(`User nickname: `, message.author.username)
.addField("User profile picture: ",message.author.avatarURL({format: "png", dynamic: true, size: 512}))
.addField('Roles: ', mrole)
.setFooter(`ID: ${message.author.id}`)
return message.channel.send(embed);
} else {
const user = message.mentions.users.first();
const target = message.guild.member(user);
const mrole = target.roles.filter(r => r.name !== '#everyone').map(role => role.name).join(' | ')
const embed = new MessageEmbed()
.setColor("RANDOM")
.setThumbnail(user_mention.avatarURL())
.addField(`Account Created the:`, ` ${user_mention.createdAt}`)
.addField(`User name: `, user_mention.tag)
.addField(`User nickname: `, user_mention.username)
.addField("User profile picture: ",user_mention.avatarURL({format: "png", dynamic: true, size: 512}))
.addField('Roles: ', mrole)
.setFooter(`ID: ${user_mention.id}`)
return message.channel.send(embed);
}
};
module.exports.help = {
name: "info",
aliases: ['information', 'i'],
category: 'server',
description: "give info about a user",
usage: "<member>",
cooldown: 10,
args: false
};
and the type error is target.roles.filter is not a function.
Thanks and have a good day!
Try target.roles.cache.filter... because v12 of discord.js has a cache property where v11 doesn't. You can view changes from v11 to v12 here!
Discord.js v12 requires a cache property when using a filter. So, to get the user's roles, you would just fix one line.
target.roles.filter( ... ); to target.roles.cache.filter( ... );
const user = message.author
const target = message.guild.member(user);
const mrole = target.roles.cache.filter(r => r.name !== '#everyone').map(role => role.name).join(' | ');
This is my current code:
const superagent = require("snekfetch");
const Discord = require('discord.js')
const random = require('random')
const os = require('os')
module.exports.run = async (client, message, args) => {
if (!message.channel.nsfw) {
message.react('💢');
return message.channel.send({embed: {
color: 16734039,
description: "CO TY ROBISZ! TE ZDJENCIA SA TYLKO DLA DOROSLYCH! (idz na kanal NSFW)"
}})
}
superagent.get('https://nekos.life/api/v2/img/ero')
.end((err, response) => {
const embed = new Discord.RichEmbed()
.setTitle(":smirk: Eevee")
.setImage(random.choice(os.listdir("./app/eevee")))
.setColor(`RANDOM`)
.setFooter(`Tags: eevee`)
.setURL(response.body.url);
message.channel.send(embed);
}).catch((err) => message.channel.send({embed: {
color: 16734039,
description: "Something is wrong... :cry:"
}}));
}
module.exports.help = {
name: "eevee",
description: "Fajno zdjencia",
usage: "eevee",
type: "NSFW"
}
When I try to run it, I get this error message:
TypeError: os.listdir is not a function
Is there anything I can do to fix this problem?
I don't really know the os package but after a bit of researching I've found no readdir function. If you want to get all files of a directory you also can do it like this:
const fs = require('fs')
const allMyFiles = fs.readdirSync();
Also you are creating your embed with RichEmbed() which is outdated. Since v12 you have to use MessageEmbed():
const exampleEmbed = new Discord.MessageEmbed()
.setTitle('Test')
[...]