I am trying to send an embed whenever a invite is created.
Channel set file
let config = require("../config.json");
const { MessageEmbed } = require("discord.js");
const Discord = require("discord.js");
const client = new Discord.Client();
module.exports = {
name: "setinvite",
description: "set invite channel log.",
async execute(message, args) {
if (!message.member.hasPermission(`ADMINISTRATOR`)) {
return message.channel.send(
`:x: You do not have permission to use this command!`
);
} else {
let channelx =
message.mentions.channels.first() ||
message.guild.channels.cache.find((c) => c.id === args[0]);
if (!channelx)
return message.channel.send(
`:x: Please specify a channel to make it as the modlogs!`
);
message.channel.send(`${channelx} has been set!`);
}
},
};
Index.js Modules (PS: I took the most relevant ones.)
const Discord = require("discord.js");
const client = new Discord.Client();
const fs = require("fs");
const { MessageEmbed } = require("discord.js");
const guildInvites = new Map();
const { channelx } = require("./commands/setinvite");
Index.js file
client.on("inviteCreate, message", async (invite) => {
const setc = client.channels.cache.get(`${channelx}`);
message.guild.fetchInvites().then((invites) => {
let allInvites = invites.map((i) => ({
name: "Invite",
value: `**Inviter:** ${i.inviter}
**Code:** https://discord.gg/${i.code}
**Usages:** ${i.uses} of ${i.maxUses === 0 ? "∞" : i.maxUses}
**Expires on:** ${
i.maxAge
? new Date(i.createdTimestamp + i.maxAge * 1000).toLocaleString()
: "never"
}`,
inline: true,
}));
setc.send(new Discord.MessageEmbed().addFields(allInvites));
});
});
I don't think the two events (inviteCreate, message) belong I did it because I received a error:
ReferenceError: message is not defined
Now, the channel set features works as intended but whenever the invite is created the embed doesn't send.
You can't merge all events inside one function.
You only need to keep the inviteCreate event. Then, you have to find a way to get the guild without using the "message" variable. Instead you can use the "invite" parameter that is present inside the inviteCreate event.
client.on("inviteCreate", async (invite) => {
const setc = client.channels.cache.get(`${channelx}`);
invite.guild.fetchInvites().then((invites) => {
let allInvites = invites.map((i) => ({
name: "Invite",
value: `**Inviter:** ${i.inviter}
**Code:** https://discord.gg/${i.code}
**Usages:** ${i.uses} of ${i.maxUses === 0 ? "∞" : i.maxUses}
**Expires on:** ${
i.maxAge
? new Date(i.createdTimestamp + i.maxAge * 1000).toLocaleString()
: "never"
}`,
inline: true,
}));
setc.send(new Discord.MessageEmbed().addFields(allInvites));
});
});
Related
I know this is a duplicate but it is a specific issue i think.
I am getting an error while performing a slash command: „The application did not respond“.
What I am trying to do is an Slash Command, that can only be performed by someone with the Administrator Role. The command should be give the User role to the mentioned user.
If someone knows a better way to do that or a GitHub Link etc. I would like to see this as well. Anyway - here is my code:
const DiscordJS = require('discord.js');
const { Routes } = require('discord-api-types/v9');
const { Intents, Client, MessageEmbed } = require('discord.js');
const { token, client_id, guild_id, admin_role_id, user_role_id } = require('./config.json')
const client = new DiscordJS.Client({
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES],
})
client.on('ready', () => {
console.log('The bot is ready')
const guild = client.guilds.cache.get(guild_id)
let commands
if (guild) {
commands = guild.commands
}
else {
commands = client.application?.commands
}
commands?.create({
name: 'user',
description: 'Makes the mentioned member a user.',
requireRoles: true,
options: [{
name: 'user',
description: 'The user the role should be given to.',
required: true,
type: DiscordJS.Constants.ApplicationCommandOptionTypes.USER
}]
})
})
client.on('interactionCreate, a', async (interaction) => {
if (!interaction.isCommand()) {
return
}
const { commandName, options } = interaction
if (commandName === 'user') {
const user_id = options.get('user')?.value;
const guild = client.guilds.cache.get(guild_id);
if (!guild) {
return console.log(`Can't find the guild with ID ${server_id}.`);
}
guild.members.fetch(user_id)
.then(member => {
console.log(member.roles.cache)
const embedSuccess = new MessageEmbed()
.setColor('#5ee067')
.setDescription('<#' + user_id + '> was given the <#&' + user_role_id + '> role.');
const embedUserInfo = new MessageEmbed()
.setDescription('Dear <#' + user_id + '>, \n you are able…');
const embedFailure = new MessageEmbed()
.setColor('#ffa2a2')
.setDescription("Could not perform command because the user that requested it doesn't have the required roles to execute it.")
if (interaction.user.roles.cache.has(admin_role_id)) {
const member = interaction.options.getMember('target');
member.roles.add(user_role_id)
interaction.reply({
content: '<#' + user_id + '>',
embeds: [ embedSuccess, embedUserInfo ]
})
}
else {
interaction.reply({
embeds: [ embedFailure ]
})
}
})
.catch(console.error);
}
})
client.login(token)
Thanks.
I was making a discord bot using NodeJS, and everytime i go boot up the bot it shows this error:
headers = (await fetch(filtered.fileUrl, { method: 'HEAD' })).headers
^^^^^
SyntaxError: Unexpected identifier
What i knew is that, fetch requires node-fetch. At first, i thought the problem was that i was using node-fetch#3.0.0, which doesn't support const fetch = require('node-fetch') but even when i downgraded it to node-fetch#2.6.1 this exact issue still persists.
Full code:
const fetch = require('node-fetch')
const Booru = require('booru')
const Discord = require('discord.js')
const { escapeMarkdown } = Discord.Util
const path = require('path')
const Color = `RANDOM`;
module.exports = {
info: {
name: "booru",
description: "booru image scraper",
cooldown: 30,
},
async execute(client, message, args, Discord) {
const tag_query = args.join(' ');
if (!message.content.includes('help')) {
if (!message.content.includes('something')) {
const hornyEmbed = new Discord.MessageEmbed()
.setTitle('embed cut to preserve space')
if (!message.channel.nsfw) return message.channel.send(hornyEmbed)
Booru.search('gelbooru', tag_query, {
limit: 1,
random: true
})
.then(posts => {
const filtered = posts.blacklist(['blacklist, of course.'])
if (filtered.length === 0) {
const notfoundEmbed = new Discord.MessageEmbed()
.setDescription("embed cut to preserve space")
message.channel.send(notfoundEmbed)
}
let tags =
filtered.tags.join(', ').length < 50
? Discord.Util.escapeMarkdown(filtered.tags.join(', '))
: Discord.Util.escapeMarkdown(filtered.tags.join(', ').substr(0, 50))
+ `... [See All](https://giraffeduck.com/api/echo/?w=${Discord.Util
.escapeMarkdown(filtered.tags.join(',').replace(/(%20)/g, '_'))
.replace(/([()])/g, '\\$1')
.substring(0, 1200)})`
let headers
let tooBig = false
let imgError = false
try {
headers = (await fetch(filtered.fileUrl, {
method: 'HEAD'
})).headers
} catch (e) {
imgError = true
}
if (headers) {
tooBig = parseInt(headers.get('content-length'), 10) / 1000000 > 10
}
for (let post of posts) {
embed_nsfw = new Discord.MessageEmbed()
.setTitle('you horny')
.setColor('#FFC0CB')
.setAuthor('-')
.setDescription(`-` +
`**Provided by:** Gelbooru.com | `, +`[**Booru Page**](${filtered.postView}) | ` +
`**Rating:** ${filtered.rating.toUpperCase()} | ` +
`**File:** ${path.extname(filtered.file_url).toLowerCase()}, ${headers ? fileSizeSI(headers.get('content-length')) : '? kB'}\n` +
`**Tags:** ${tags}` +
(!['.jpg', '.jpeg', '.png', '.gif'].includes(
path.extname(filtered.fileURL).toLowerCase(),
) ?
'`The file will probably not embed.`' :
'') +
(tooBig ? '\n`The image is over 10MB and will not embed.`' : '') +
(imgError ? '\n`I got an error while trying to get the image.`' : ''),
)
.setImage(filtered.sampleUrl)
message.channel.send(embed_nsfw);
}
})
}
if (message.content.includes('something')) {
const helpEmbed = new Discord.MessageEmbed()
.setTitle('cut to preserver space')
message.channel.send(helpEmbed)
}
}
if (message.content.includes('help')) {
const helpEmbed = new Discord.MessageEmbed()
.setTitle('cut to preserver space')
message.channel.send(helpEmbed)
}
}
}
I know this code is extremely messy, because it's basically a frankenstein's code put together from different codes i found. So aside from the solution for the main topic, a pointer on another issue i hadn't noticed will also be appreciated.
NodeJS version 16.13.0,
NPM version 8.1.0,
DiscordJS version 12.5.3,
Running on a Heroku server.
try add async to .then(posts => .
Booru.search('gelbooru', tag_query, {
...
.then(async posts => {
const filtered = posts.blacklist(['blacklist, of course.'])
if (filtered.length === 0) {
const notfoundEmbed = new Discord.MessageEmbed()
.setDescription("embed cut to preserve space")
message.channel.send(notfoundEmbed)
}
...
try {
headers = (await fetch(filtered.fileUrl, {
method: 'HEAD'
})).headers
}
I am making a Discord Bot that informs Moderators when a user joins a specific voice channel. The Bot is supposed to also have a spam protection that the bot will only log a message once per minute per user.
This is what I have tried before:
const { Client } = require("discord.js");
const { config } = require("dotenv");
const fs = require('fs');
const client = new Client({
partials: ['MESSAGE', 'CHANNEL', 'REACTION']
});
config({
path: __dirname + "/.env"
})
var supportchannel = '827574015526567947'
var dutychannel = '847445933969113118'
var ondutyrole = '847447374925398016'
client.on("ready", () => {
console.log(`Hi, ${client.user.username} is now online!`);
global.timer = 0;
client.user.setStatus('online');
client.user.setActivity('me getting developed', { type: "WATCHING"})
.then(presence => console.log('status set'))
.catch(console.error);
});
client.on('voiceStateUpdate', (oldMember, newMember) => {
let newUserChannel = newMember.channelID;
let oldUserChannel = oldMember.channelID;
if(newUserChannel === supportchannel)
{
if (timer == 0){
timer = 1
setTimeout(() => {
timer = 0
}, 60000);
const Userfm = client.users.cache.get(newMember.id);
if (Userfm) {
const channelfx = client.channels.cache.get(dutychannel)
let roleId = ondutyrole
channelfx.send(`<#&${roleId}> **${Userfm.tag}** requires Support`);
}
}else{
return;
}
}
console.log("User joined vc with id "+newUserChannel)
});
client.login(process.env.TOKEN);
This doesn't work the way intended because the cooldown is not separate for every user but sets a countdown that blocks every user from getting the Moderator's attention for 60 seconds (the users all share a cooldown).
I thought that the code ran asynchronously for every user.
The same goes for this code in which I made use of the wait-sync npm library:
const { Client } = require("discord.js");
const { config } = require("dotenv");
const fs = require('fs');
const waitSync = require('wait-sync');
const client = new Client({
partials: ['MESSAGE', 'CHANNEL', 'REACTION']
});
config({
path: __dirname + "/.env"
})
var supportchannel = '827574015526567947'
var dutychannel = '847445933969113118'
var ondutyrole = '847447374925398016'
client.on("ready", () => {
console.log(`Hi, ${client.user.username} is now online!`);
global.timer = 0;
client.user.setStatus('online');
client.user.setActivity('me getting developed', { type: "WATCHING"})
.then(presence => console.log('status set'))
.catch(console.error);
});
client.on('voiceStateUpdate', (oldMember, newMember) => {
let newUserChannel = newMember.channelID;
let oldUserChannel = oldMember.channelID;
if(newUserChannel === supportchannel)
{
const Userfm = client.users.cache.get(newMember.id);
if (Userfm) {
const channelfx = client.channels.cache.get(dutychannel)
let roleId = ondutyrole
channelfx.send(`<#&${roleId}> **${Userfm.tag}** requires Support`);
waitSync(60);
}
}
console.log("User joined vc with id "+newUserChannel)
});
client.login(process.env.TOKEN);
If you know how to solve this problem please let me know.
Thanks in advance ;)
What you can do is probably to have some sort of mapping that keeps track of the timer for each user and have the user IDs be the keys:
const timers = {};
client.on('voiceStateUpdate', (oldMember, newMember) => {
...
// If we don't have any timer set for this user, go ahead and set it
if (!timers[newMember.id]) {
timers[newMember.id] = 1;
setTimeout(() => {
// Delete the timer from the mapping
delete timers[newMember.id];
}, 60000);
...
i have a problem sending text from yaml. Saving text works but sending does not. Here's the code:
const { Message, MessageEmbed } = require("discord.js")
const { channel } = require('./kanal')
const db = require('quick.db')
module.exports = {
name: "reklama",
guildOnly: true,
description:
"Change guild prefix. If no arguments are passed it will display actuall guild prefix.",
usage: "[prefix]",
run(msg, args, guild) {
if (!guild) {
const guld = new MessageEmbed()
.setTitle("Błąd!")
.setColor("RED")
.setDescription("Tą komende można tylko wykonać na serwerze!")
.setThumbnail('https://emoji.gg/assets/emoji/3485-cancel.gif')
.setTimestamp()
.setFooter(`${msg.author.tag} (${msg.author.id})`, `${msg.author.displayAvatarURL({dynamic: true})}`)
msg.channel.send(guild)
}
const { settings } = client
const prefixArg = args[0]
if (!settings.get(guild.id)) {
settings.set(guild.id, { prefix: null })
}
if (!prefixArg) {
let Reklama = client.settings.get(guild.id).Reklama
let Kanal = client.settings.get(guild.id).Kanał
const embed = new MessageEmbed()
.setTitle(`Informacje o serwerze: ${msg.guild.name}`)
.addField("Treść reklamy:", Reklama)
.addField("Kanał do wysyłania reklam:", Kanal)
msg.channel.send(embed)
}
setInterval(() => {
Kanal.send(`${Reklama}`)
}, 1000)
},catch(e){
console.log(e)
}
}
Here is a part of command handler:
const args = msg.content.slice(length).trim().split(" ")
const cmdName = args.shift().toLowerCase()
const cmd =
client.commands.get(cmdName) ||
client.commands.find(
(cmd) => cmd.aliases && cmd.aliases.includes(cmdName),
)
try {
cmd.run(msg, args)
} catch (error) {
console.error(error)
}
})
}
The problem is that when I start the bot, it shows me such an error:
let Reklama = client.settings.get(guild.id).Reklama
^
TypeError: Cannot read property 'id' of undefined
The problem is you don't pass the guild variable to your run method. You call cmd.run(msg, args) but run accepts three parameters.
You can either pass the guild or get it from the msg like this:
module.exports = {
name: 'reklama',
guildOnly: true,
description:
'Change guild prefix. If no arguments are passed it will display actuall guild prefix.',
usage: '[prefix]',
run(msg, args) {
// destructure the guild the message was sent in
const { guild } = msg;
if (!guild) {
const embed = new MessageEmbed()
.setTitle('Błąd!')
.setColor('RED')
.setDescription('Tą komende można tylko wykonać na serwerze!')
.setThumbnail('https://emoji.gg/assets/emoji/3485-cancel.gif')
.setTimestamp()
.setFooter(
`${msg.author.tag} (${msg.author.id})`,
`${msg.author.displayAvatarURL({ dynamic: true })}`,
);
return msg.channel.send(embed);
}
const { settings } = client;
const prefixArg = args[0];
if (!settings.get(guild.id)) {
settings.set(guild.id, { prefix: null });
}
if (!prefixArg) {
let Reklama = client.settings.get(guild.id).Reklama;
let Kanal = client.settings.get(guild.id).Kanał;
const embed = new MessageEmbed()
.setTitle(`Informacje o serwerze: ${msg.guild.name}`)
.addField('Treść reklamy:', Reklama)
.addField('Kanał do wysyłania reklam:', Kanal);
msg.channel.send(embed);
}
setInterval(() => {
Kanal.send(`${Reklama}`);
}, 1000);
},
catch(e) {
console.log(e);
},
};
So i am coding a bot , in Node.js with Visual Studio Code. I want to have a channel, that when a user joins the guild , will send 'Welcome user and invited by thisuser(Total Invites: 5)
The code is :
module.exports = (client) => {
const invites = {} // { guildId: { memberId: count } }
const getInviteCounts = async (guild) => {
return await new Promise((resolve) => {
guild.fetchInvites().then((invites) => {
const inviteCounter = {} // { memberId: count }
invites.forEach((invite) => {
const { uses, inviter } = invite
const { username, discriminator } = inviter
const name = `${username}#${discriminator}`
inviteCounter[name] = (inviteCounter[name] || 0) + uses
})
resolve(inviteCounter)
})
})
}
client.guilds.cache.forEach(async (guild) => {
invites[guild.id] = await getInviteCounts(guild)
})
client.on('guildMemberAdd', async (member) => {
const { guild, id } = member
const invitesBefore = invites[guild.id]
const invitesAfter = await getInviteCounts(guild)
console.log('BEFORE:', invitesBefore)
console.log('AFTER:', invitesAfter)
for (const inviter in invitesAfter) {
if (invitesBefore[inviter] === invitesAfter[inviter] - 1) {
const channelId = '731801004462571602'
const channel = guild.channels.cache.get(channelId)
const count = invitesAfter[inviter]
channel.send(
`Please welcome <#${id}> to the Discord! Invited by ${inviter} (${count} invites)`
)
invites[guild.id] = invitesAfter
return
}
}
})
}
This code works perfectly with console but i am facing a problem,never post the message in the channel!
The message might not be being sent because of the channel ID double check you are using the right channel ID and you might want to try changing
const channel = guild.channels.cache.get(channelId) to this
const channel = client.channels.cache.get(channelId)