How do I fetch the creator of a channel in discord? - javascript

bot.on('channelCreate', async channel => {
if (!channel.guild) return;
const fetchedLogs = await channel.guild.fetchAuditLogs({
limit: 1,
type: 'CHANNEL_CREATE',
});
const logbook = channel.guild.channels.cache.get("ChannelID")
const deletionLog = fetchedLogs.entries.first();
if (!deletionLog) return logbook.send(`A channel was updated but no relevant autid logs were found`);
const { executor, user } = deletionLog;
if (user.id) {
logbook.send(`${executor.tag} created a channel`);
} else {
logbook.send(`A channel was created but idk who did.`);
}
});
I am a newbie when it comes to fetching actions through Discord Audit Logs; so I am experimenting and somehow came up with this code. However, when I create a channel, it does not send any messages saying that a channel has been created by #user. I have no idea what my next step will be. All I wanted to do was to know who created the channel.
Discord.JS: v12.2.0

client.on("channelCreate", async channel => {
if (!channel.guild) return false; // This is a DM channel.
const AuditLogFetch = await channel.guild.fetchAuditLogs({limit: 1, type: "CHANNEL_CREATE"}); // Fetching the audot logs.
const LogChannel = client.channels.cache.get("722052103060848664"); // Getting the loggin channel. (Make sure its a TextChannel)
if (!LogChannel) return console.error(`Invalid channel.`); // Checking if the channel exists.
if (!AuditLogFetch.entries.first()) return console.error(`No entries found.`);
const Entry = AuditLogFetch.entries.first(); // Getting the first entry of AuditLogs that was found.
LogChannel.send(`${Entry.executor.tag || "Someone"} created a new channel. | ${channel}`) // Sending the message to the logging channel.
});
If the code I provided is not working, please make sure the bot has access to view AuditLogs.

Related

How can i get my discord.js v14 bot to stop saying "The application did not respond" if the slash command works?

i have multiple commands that work perfectly fine but i always get this message in return.
here is the code for that command. it works perfectly fine i guess it just doesn't respond to the interaction even though i feel like it should be?
how can i get it to ignore this message or reply properly?
const Discord = require('discord.js');
const { EmbedBuilder, SlashCommandBuilder } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
// command name
.setName('totalfrozencheckouts')
// command description
.setDescription('Add up every message in the frozen checkouts channel after a specific message ID')
.addStringOption(option =>
option.setName('messageid')
.setDescription('The message ID')
.setRequired(true)),
async execute(interaction) {
const channel = '<#' + process.env.FROZENCHECKOUTS + '>';
const messageId = interaction.options.getString("messageid");
// Check if the channel mention is valid
if (!channel.startsWith('<#') || !channel.endsWith('>')) {
return interaction.channel.send(`Invalid channel mention. Please use the format: ${this.usage}`);
}
// Extract the channel ID from the channel mention
const channelId = channel.slice(2, -1);
// Try to fetch the messages from the requested channel and message ID
interaction.guild.channels.cache.get(channelId).messages.fetch({ after: messageId })
.then(messages => {
// Create an array of the message contents that are numbers
const numbers = messages.map(message => message.content).filter(content => !isNaN(content));
// Check if there are any messages
if (numbers.length === 0) {
return interaction.channel.send(`No messages were found in ${channel} after message ID https://discord.com/channels/1059607354678726666/1060019655663689770/${messageId}`);
}
// Adds up the messages
const sum = numbers.reduce((accumulator) => accumulator + 1, 1);
// Create an embed object
const embed = new EmbedBuilder()
.setColor(0x4bd8c1)
.setTitle(`Total Checkouts in #frozen-checkouts for today is:`)
.addFields(
{name: 'Total Checkouts', value: sum.toString() , inline: true},
)
.setThumbnail('https://i.imgur.com/7cmn8uY.png')
.setTimestamp()
.setFooter({ text: 'Frozen ACO', iconURL: 'https://i.imgur.com/7cmn8uY.png' });
// Send the embed object
interaction.channel.send({embeds: [embed]});
})
.catch(error => {
console.error(error);
interaction.channel.send('An error occurred while trying to fetch the messages. Please try again later.');
});
}
}
I don't really know what to try because it literally works I just don't know how to get it to either ignore that message or respond with nothing. It doesn't break the bot its just annoying to look at.
Use interaction.reply instead of interaction.channel.send to reply.

.addArgument is not a function Discord bot

Here is my Discord command module code, for some reason this is spitting out that .addArgument is not a function.
const Discord = require('discord.js');
const { SlashCommandBuilder } = require('#discordjs/builders');
data = new SlashCommandBuilder()
.setName('purge')
.setDescription('Purges a number of messages from the channel.')
.addArgument('number', 'The number of messages to purge.')
.addArgument('channel', 'The channel to purge messages from.')
.setExecute(async (interaction, args) => {
const channel = interaction.guild.channels.cache.find(c => c.name === args.channel);
if (!channel) return interaction.reply('Channel not found.');
const messages = await channel.messages.fetch({ limit: args.number });
await channel.bulkDelete(messages);
interaction.reply(`Purged ${messages.size} messages.`);
}
);
It just gives me this:
TypeError: (intermediate value).setName(...).setDescription(...).addArgument is not a function
The reason you are getting this error is because there is nothing called .addArgument() in the SlashCommandBuilder. If you want to add arguments like numbers or channels, you need to use .addNumberOption() or .addChannelOption(). The way you will need to use to add a channel and number option is like this:
.addNumberOption(option => {
return option
.setName('number') // Set the name of the argument here
.setDescription('The number of messages to purge.') // Set the description of the argument here
.setRequired() // This is optional. If you want the option to be filled, you can just pass in true inside the .setRequired() otherwise you can just remove it
})
.addChannelOption(option => {
return option
.setName('channel')
.setDescription('The channel to purge messages from.')
.setRequired()
})
You can learn more about slash commands and options here => Options | discord.js

How to check the existence of a user in Discord.js without errors?

Explain
I am developing a user verification bot.
Within the requirements I need to remove the user reactions on a specific message, but removing the reactions discord.js triggers the messageReactionRemove event and causes another function to be executed that sets the roles to a user.
Problem/Error
The problem happens when a user leaves the server, discord.js removes the reactions but in turn triggers another event messageReactionRemove and my bot blows up with an error called "Uknow Member"
Codes
Listener when an user leaves the server:
// All this code works fine :)
client.on("guildMemberRemove", async (member) => {
warn(`El usuario ${member.user.username} abandono el servidor`);
try {
const channel = await client.channels.fetch(CHANNELS.VERIFICATION_CHANNEL);
const message = await channel.messages.fetch(
MESSAGES.BOT_VERIFICATION_MESSAGE_ID
);
message.reactions.cache.map((reaction) => {
// After removing the reaction, discord.js fires the event "messageReactionRemove"
reaction.users.remove(member.user.id);
});
} catch (err) {
console.error(err);
}
});
Listener when an user remove a reaction from a message:
if (!user.bot) {
try {
const channelId = reaction.message.channelId;
const messageId = reaction.message.id;
const emojiName = reaction.emoji.name;
const userExists = await getMember(user.id); // <-- This explodes in an error
if (!userExists) {
warn(`El usuario ${user.username} no existe en el servidor`);
return;
}
if (
channelId === CHANNELS.VERIFICATION_CHANNEL &&
messageId === MESSAGES.BOT_VERIFICATION_MESSAGE_ID &&
emojiName === EMOJIS.VERIFICATION_EMOJI
) {
addTownLoyalRoleToNewUsers(reaction, user);
}
// other messages validations ...
} catch (err) {
error(err.message, err);
}
}
Code for add the verification role:
const addTownLoyalRoleToNewUsers = async (reaction, user) => {
const member = await reaction.message.guild.members.fetch(user.id); // <-- This also blows up in an error
const townRoyalUsersLength = await getUsersLengthByRole(
ROLES.TOW_LOYAL_ROLE_ID
);
if (townRoyalUsersLength <= MAX_LENGTH_TOW_LOYAL_USERS) {
member.roles.add(ROLES.TOW_LOYAL_ROLE_ID);
} else {
member.roles.add(ROLES.VERIFIED_ROLE_ID);
}
const otherRoles = ROLES.AFTER_VERIFICATION();
if (otherRoles.length) member.roles.add(otherRoles);
};
Error images
Error when an user leaves a server
Interestingly when the user leaves, the guildMemberRemove event still owns the nonexistent user
If you want to only remove the member who is leaving, then this line of code should do the trick, add it to your guildMemberRemove event
client.channels.cache.get('ChannelIdWithMessage').messages.fetch('MessageIdToRemoveReactionsFrom').then((message) => {
message.reactions.cache.filter(reaction => reaction.users.remove(member.user.id))
})
There are 2 parts to discord.js you should know, there is the Discord API, which is where those errors come from, and then there are the objects, which make interacting with the Discord API easier.
I'm assuming that your getMember() function tries to fetch the member from the API by ID (guild.members.fetch(id)). Note the user is not "non-existent", it's the GuildMember. The object is simply data from the event, but you can't interact with it in the API. You seem to expect the getMember() function to return a falsy value, like null or undefined, if the member is not found. Instead, it gets a 404 and rejects.
Instead, use a .catch() like this:
const userExists = await getMember(user.id).catch(() => null); // null if rejected

Get count of member's messages in channel in discord.js

Is there any way how to count messages of specified user in specified Discord channel in discord.js? When I use:
const countMyMessages = async (channel, member) => {
const messages = await channel.messages.fetch()
const myMessages = message.filter(m => m.author.id === member.id)
console.log(myMessages.size)
}
Only 50 messages are fetched, so I can't count all messages of user. And option limit can have max value 100. /guilds/guild_id/messages/search API on the other hand is not available for bots.
You will need to use a storage system to keep this kind of statistics on Discord.
I recommend you to use SQLite at first (like Enmap npm package).
I can quickly draw a structure for you based on this one.
const Enmap = require("enmap");
client.messages = new Enmap("messages");
client.on("message", message => {
if (message.author.bot) return;
if (message.guild) {
const key = `${message.guild.id}-${message.author.id}`;
client.messages.ensure(key, {
user: message.author.id,
guild: message.guild.id,
messages: 0
});
client.messages.inc(key, "messages");
// Do your stuff here.
console.log(client.messages.get(key, "messages"))
}
});

discord.js get message's id and delete it

When a user joins the server, the bot sends a welcome message, i want to take that welcome message's ID and make the bot delete it if the users leaves after he joins. I tried to save the message's id in a variable and make the bot delete the message when the user leaves but without success. I already took a look at the docs, but I really can't understand how to make it.
Define an object to hold the welcome messages by guild and user. You may want to use a JSON file or database (I'd highly recommend the latter) to store them more reliably.
When a user joins a guild...
Send your welcome message.
Pair the the message's ID with the user within the guild inside of the object.
When a member leaves the guild...
Fetch their welcome message.
Delete the message from Discord and the object.
Example setup:
const welcomeMessages = {};
client.on('guildMemberAdd', async member => {
const welcomeChannel = client.channels.get('channelIDHere');
if (!welcomeChannel) return console.error('Unable to find welcome channel.');
try {
const message = await welcomeChannel.send(`Welcome, ${member}.`);
if (!welcomeMessages[member.guild.id]) welcomeMessages[member.guild.id] = {};
welcomeMessages[member.guild.id][member.id] = message.id;
} catch(err) {
console.error('Error while sending welcome message...\n', err);
}
});
client.on('guildMemberRemove', async member => {
const welcomeChannel = client.channels.get('channelIDHere');
if (!welcomeChannel) return console.error('Unable to find welcome channel.');
try {
const message = await welcomeChannel.fetchMessage(welcomeMessages[member.guild.id][member.id]);
if (!message) return;
await message.delete();
delete welcomeMessages[member.guild.id][member.id];
} catch(err) {
console.error('Error while deleting existing welcome message...\n', err);
}
});
To do this you would have to store the id of the welcome message and the user that it is tied to (ideally put this in an object). And when the user leaves you would use those values to delete that message.
Example code:
const Discord = require('discord.js');
const client = new Discord.Client();
const welcomeChannel = client.channels.find("name","welcome"); // Welcome is just an example
let welcomes = [];
client.on('message', (message) => {
if(message.channel.name === 'welcome') {
const welcomeObj = { id: message.id, user: message.mentions.users.first().username };
welcomes.push(welcomeObj);
}
});
client.on('guildMemberRemove', (member) => {
welcomes.forEach(welcome, () => {
if(welcome.user === member.user.username) {
welcomeChannel.fetchMessage(welcome.id).delete();
}
});
});
This only works if the welcome message includes a mention to the user so make sure that's in the welcome message.
Also I can't test this code myself at the moment so let me know if you encounter any problems.

Categories

Resources