TypeError: Cannot read properties of undefined (reading 'ban') - discord.js

client.on("channelCreate", async function(channel) {
const logs = await channel.guild.fetchAuditLogs({ limit: 1, type: 'CHANNEL_CREATE' });
const log = logs.entries.first();
if (!log) return;
const kanal = channel.guild.channels.cache.find(ch => ch.name === 'ticket')
const embed = new MessageEmbed()
.setTitle("🆘Protection System🆘")
.setDescription(`ο/η ${log.executor} έγινε banned επειδή έκανε αρκετά κανάλια`)
.setColor("RED")
const get = db.get(`channel2_${log.executor.id}`)
if(get === true)return channel.delete(),kanal.send({embeds: [embed]}),logs.executor.ban('Protection : Channel Created')
});
When I run this code, it returns this error:
TypeError: Cannot read properties of undefined (reading 'ban')

In your current code, the logs variable refers to GuildAuditLogs which is the collection of audit logs. It doesn't have an executor property. Instead, what you are looking for is the log variable (without an 's'). It contains the executor property. But using the executor property gives you an User object, so it still wouldn't have an .ban() property. So you would have to fetch the GuildMember who did the action. So, your fixed code would look like this:
client.on("channelCreate", async function(channel) {
const logs = await channel.guild.fetchAuditLogs({ limit: 1, type: 'CHANNEL_CREATE' });
const log = logs.entries.first();
const logExecutorMember = await channel.guild.members.fetch(log.executor.id)
if (!log) return;
const kanal = channel.guild.channels.cache.find(ch => ch.name === 'ticket')
const embed = new MessageEmbed()
.setTitle("🆘Protection System🆘")
.setDescription(`ο/η ${log.executor} έγινε banned επειδή έκανε αρκετά κανάλια`)
.setColor("RED")
const get = db.get(`channel2_${log.executor.id}`)
if(get === true)return channel.delete(),kanal.send({embeds: [embed]}),logExecutorMember.ban('Protection : Channel Created')
});

Related

how to check if nested docs and collection in firebase exist and if don't how to create, in react native

I am new to Firebase and I have to create a chat system. I found that the doc structure should be nested
e.g if a person sends a message, a new doc with its id will be created in the main collection and then a new collection will be added to the doc. now each doc in that nested collection will be considered as a message obj.
a rough sketch of how the new message in the nested document will be added
but the problem is when there is no doc with UI exist or no collection in that doc exist
firestore().collection("chatBox").doc(uid).collection("message").add(
{
text: "this is my first message",
user: {_id:356},
avatar: "link of avatar",
name: "john",
createdAt: new Date().getTime()
}
)
const sendMessage = async (messages = []) => {
const msg = messages[0];
const id = msg.user?._id?.toString();
const collectionRef = firestore().collection(CHATBOX);
const doc = collectionRef.doc(id);
const docExists = await doc.get().then(function (doc) {
return doc.exists;
});
if (docExists) {
const collection = doc.collection(MESSAGES);
const isCollectionEmpty = collection.get().then(col => {
return col.empty;
});
if (isCollectionEmpty) doc.set({id: MESSAGES});//creating new collection
else collection.add({...msg, createdAt: new Date().getTime()});//inserting doc if collection exist
} else {
collectionRef.add(id);// creating doc in main collection
}
};
The ability to create a document only if it does not exist can be done using the following Transaction. Here, the createDocIfNotExist method creates the document with the given data, only if it does not already exist. It returns a Promise<boolean> indicating whether the document was freshly created or not.
async createDocIfNotExist(docRef, initData) {
return docRef
.firestore
.runTransaction((transaction) => {
const docSnap = await transaction.get(docRef);
if (docSnap.exists)
return false; // exists already
transaction.set(docRef, initData);
return true; // was created
});
}
Applying this to your code then gives:
const sendMessage = async (messages = []) => {
const msg = messages[0];
const msgUserId = msg.user!._id!.toString(); // id renamed, consider using senderId/recipientId instead
const chatboxColRef = firestore().collection(CHATBOX); // collectionRef renamed
const userChatboxDocRef = chatboxColRef.doc(msgUserId); // doc renamed
const isNewChatbox = await createDocIfNotExist(
userChatboxDocRef,
{ id: msgUserId }
);
const userChatboxMessagesColRef = userChatboxDocRef.collection(MESSAGES); // collection renamed
return userChatboxMessagesColRef
.add({
...msg,
createdAt: new Date().getTime() // consider using firebase.firestore.FieldValue.serverTimestamp() instead
});
};
This can be further reduced to:
const sendMessage = async (messages = []) => {
const msg = messages[0];
const msgUserId = msg.user!._id!.toString();
const userChatboxDocRef = firestore()
.collection(CHATBOX);
.doc(msgUserId);
await createDocIfNotExist(
userChatboxDocRef,
{ id: msgUserId }
);
return userChatboxDocRef
.collection(MESSAGES)
.add({
...msg,
createdAt: new Date().getTime()
});
};
Note: Avoid using the variable name doc as it is ambiguous and could be an instance of DocumentData, DocumentReference, or DocumentSnapshot (at minimum, use docData, docRef and docSnap/docSnapshot respectively). Similarly, use colRef for a CollectionReference and qSnap/querySnap for QuerySnapshot objects.

Discord.js v12 How to get total number on reactions from fetched embed

So i've been trying to count the reactions statistic after it was accepted or rejected, i'd try to find a solution but i can't here's my code
module.exports = {
name: 'accept-suggestion',
cooldown: 3,
description: 'Accept a sugegstion',
permissions: 'MANAGE_ROLES',
usage: '[suggestion id] [reason]',
async run(client, message, args, cmd, Discord){
message.delete()
const messageID = args[0];
const acceptMsg = args.slice(1).join(" ");
if(!messageID) return message.reply('Please specify a suggestion Id!').then(msg => {
msg.delete({ timeout: 3000 })
})
if(!acceptMsg) return message.reply('Please specify a reason!').then(msg => {
msg.delete({ timeout: 3000})
})
try {
const suggestionChannel = message.guild.channels.cache.get(
'SuggestionChannel_ID'
);
const moderator = message.author.tag
const suggestedEmbed = await suggestionChannel.messages.fetch(messageID);
console.log(suggestedEmbed)
const data = suggestedEmbed.embeds[0];
const dataStats = suggestedEmbed[0];
let upVote = dataStats.reactions.cache.get('✅').count;
let downVote = dataStats.reactions.cache.get('❌').count;
const acceptEmbed = new Discord.MessageEmbed()
.setTitle("Suggestion (Accepted)")
.setColor('#1dc44a')
.setAuthor(data.author.name, data.author.iconURL)
.setDescription(data.description)
.addFields(
{name: `Accepted by ${moderator}`, value: ` > ${acceptMsg}`},
{name: 'Statistic', value: `${upVote}\n${downVote}`}
)
.setFooter(`${data.author.name}'s suggestion`, data.author.iconURL)
suggestedEmbed.edit(acceptEmbed).then(msg => msg.reactions.removeAll())
const user = await client.users.cache.find(
(u) => u.tag === data.author.name
);
user.send("Your suggestion has been accepted!")
} catch(err) {
console.log(err)
}
}
}
you maybe wondering why i put .reactions after dataStats, i put it because i thought it would work by seeing the output off the suggestedEmbed(the output: https://pastebin.com/yEhDecur) i hope someone could fix this :)
Running the fetch() method with a id parameter only returns a single Message so accessing it like a array/collection won't work
const dataStats = suggestedEmbed[0];
this needs to change to
const dataStats = suggestedEmbed;
https://discord.js.org/#/docs/discord.js/stable/class/MessageManager?scrollTo=fetch

Discord.js cannot read property

I am trying to code a bot that will send a message when someone joins a voice channel. Code and error are below.
const Discord = require("discord.js");
const config = require("./config.json");
const bot = new Discord.Client();
bot.login(config.BOT_TOKEN);
bot.once('ready', () => {
console.log(`Bot ready, logged in as ${bot.user.tag}!`);
})
bot.on('voiceStateUpdate', (oldMember, newMember) => {
const newUserChannel = newMember.voice.channelID
const oldUserChannel = oldMember.voice.channelID
const textChannel = message.guild.channels.cache.get('766783720312537089')
if (newUserChannel === '764231813248843806') {
textChannel.send(`${newMember.user.username} (${newMember.id}) has joined the channel`)
} else if (oldUserChannel === '764231813248843806' && newUserChannel !== '764231813248843806') {
textChannel.send(`${newMember.user.username} (${newMember.id}) has left the channel`)
}
})
Error:
TypeError: Cannot read property 'channelID' of undefined
This is pretty easy to solve. The problem is that voiceStateUpdate does indeed take two variables, however they are not oldMember, newMember but oldState, newState.
As usual with functions it doesn't really matter what you call them but it makes more sense to use oldState, newState because they are a voiceState. As such they do not have a voice property.
So to fix this, all you have to do is use the correct voiceState properties.
const newUserChannel = newState.channelID;
const oldUserChannel = oldState.channelID;
Note: newState.user is also not a thing, however it does provide you with the member object so I suggest you use that instead.
EDIT: Your entire code should look a little something like this.
bot.on('voiceStateUpdate', (oldState, newState) => {
const newUserChannel = newState.channelID;
const oldUserChannel = oldState.channelID;
const textChannel = newState.guild.channels.cache.get('766783720312537089');
if (newUserChannel === '764231813248843806') {
textChannel.send(`${newState.member.user.username} (${newState.id}) has joined the channel`)
} else if (oldUserChannel === '764231813248843806' && newUserChannel !== '764231813248843806') {
textChannel.send(`${newState.member.user.username} (${newState.id}) has left the channel`)
}
});

Run client.setActivity out of client.once('ready' etc. discord.js

I am trying to set the status of the bot based on a user message (not in the code below), but I keep getting the error
TypeError: Cannot read property 'setActivity' of null
code is below, thanks in advance
client.once('ready', () => {
console.log('Ready!');
client.user.setActivity("your every move", { type: "WATCHING" }) //works
});
function setStatus(game, type){
client.user.setActivity(game, type)
}
setStatus("your every move", { type: "WATCHING" }) //returns "TypeError: Cannot read property 'setActivity' of null"
client.login(config.token);
this code should set the activity. Usage would be +activity watching/playing/listening game
BTW the setStatus function also works if you have it in a function (if you call that function in client. or that function that calls the function is called by client.)
const Discord = require("discord.js");
const client = new Discord.Client();
const cfg = require("./config.json");
const prefix = "+";
client.once('ready', () => {
console.log('Ready!');
setStatus("your every move", { type: "WATCHING" })
});
client.on("message", message =>{
if(message.content.startsWith(prefix)){
args = message.content.substr(prefix.length).split(/ +/);
cmd = args[0].toLowerCase();
if(cmd == "activity"){
let type = args[1].toUpperCase();
console.log(type);
let game = args
game.splice(0,2);
setStatus(game.join(" "), { type: type });
}
}
});
function setStatus(game, type){
client.user.setActivity(game, type)
}
client.login(cfg.token);

TypeError: Cannot read property 'forEach' of undefined discord.js

I'm having this issue: TypeError: Cannot read property 'forEach' of undefined on my discord bot after adding aliases. It worked before I added aliases to it so I'm assuming the problem is somewhere around there. I can't seem to find where the problem is originating from so any help would be appreciated!
code:
const botconfig = require("./botconfig.json");
const Discord = require("discord.js");
const fs = require("fs");
const bot = new Discord.Client({disableEveryone: true});
bot.commands = new Discord.Collection();
bot.aliases = new Discord.Collection();
let profile = require("./profiles.json");
fs.readdir("./commands/", (err, files) => {
if(err) console.log(err);
let jsfile = files.filter(f => f.split(".").pop() === "js")
if(jsfile.length <= 0){
console.log("Couldn't find commands");
return;
};
jsfile.forEach((f, i) => {
let props = require(`./commands/${f}`);
console.log(`${f} loaded!`);
bot.commands.set(props.help.name, props);
props.help.aliases.forEach(alias => {
bot.aliases.set(alias, props.help.name);
});
});
});
bot.on("ready", async () => {
console.log(`${bot.user.username} is online`);
bot.user.setActivity("$ Made by xkillerx15");
});
bot.on("message", async message => {
if(message.author.bot) return;
if(message.channel.type === "dm") return;
let prefix = botconfig.prefix;
let messageArray = message.content.split(" ");
let cmd = messageArray[0];
let args = messageArray.slice(1);
let commandfile = bot.commands.get(cmd.slice(prefix.length)) || bot.commands.get(cmd.slice(prefix.length));
if(commandfile) commandfile.run(bot,message,args);
if(!profile[message.author.id]){
profile[message.author.id] = {
coins: 0
};
}
let coinAmt = Math.floor(Math.random() * 15) + 1;
let baseAmt = Math.floor(Math.random() * 15) + 1;
if(coinAmt === baseAmt){
profile[message.author.id] = {
coins: profile[message.author.id].coins + coinAmt
};
fs.writeFile("./profiles.json", JSON.stringify(profile), (err) => {
if(err) console.log(err)
});
}
});
bot.login(botconfig.token);
exact error:
TypeError: Cannot read property 'forEach' of undefined
at jsfile.forEach (C:\Users\Jordy\Desktop\jbot\index.js:23:28)
at Array.forEach (<anonymous>)
at fs.readdir (C:\Users\Jordy\Desktop\jbot\index.js:19:12)
at FSReqWrap.args [as oncomplete] (fs.js:140:20)
your problem is that aliases is undefined which means is not an object so you can't use forEach
there is one possibility:
commands file should contains aliases inside help object.
so it should something like this
exports.help = {
aliases:[...props]
}

Resources