Let's say I have this:
const db = require('../../Models/warns')
const { Message, MessageEmbed } = require('discord.js')
const reason = args.slice(1).join(" ")
db.findOne({ guildid: message.guild.id, user: user.user.id}, async(err, data) => {
if(err) throw err;
if(!data) {
data = new db({
guildid: message.guild.id,
user : user.user.id,
content : [
{
moderator : message.author.id,
reason : reason
}
]
})
} else {
const obj = {
moderator: message.author.id,
reason : reason
}
data.content.push(obj)
}
data.save()
});
Why is push undefined (TypeError: Cannot read properties of undefined (reading 'push'))? Is there anything I am missing?
Same thing goes if I have this:
const sembed = new MessageEmbed()
.setTitle(`${user.user.tag}'s warns`)
.setDescription(
data.content.map(
(w, i) =>
`\`${i + 1}\` | Moderator : ${message.guild.members.cache.get(w.moderator).user.tag}\nReason : ${w.reason}`
)
)
.setColor("BLUE")
message.channel.send({ embeds: [sembed] });
map is also undefined.
(I am using discordjs v13)
Models/warns:
const { Schema, model } = require('mongoose');
module.exports = model("warns", new Schema({
userId: String,
guildId: String,
moderatorId: String,
reason: String,
timestamp: Number,
})
);
NOTE: This code is by using mongoose npm package (A database, pretty much like quick.db but better)
Related
The /tag [tag name] command is supposed to send the tag description or a message if the tag doesn't exist. Currently I have no items in the model. When I run the command with any arguments I get TypeError: Cannot read properties of undefined (reading 'findOne'). Here is my code:
commands/tag.js:
const { Tags } = require('../models/tag.js');
const { SlashCommandBuilder } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('tag')
.setDescription('Show a tag.')
.addStringOption(option =>
option
.setName('name')
.setDescription('The name of the tag')
.setRequired(true)
),
async execute(interaction) {
const name = interaction.options.getString('name');
const tag = Tags.findOne({where: { name: name } });
if (tag) return interaction.reply(tag.get('description'));
return interaction.reply('That tag doesn\'t exist!');
}
}
models/tag.js:
module.exports = (db, DataTypes) => {
return db.define('tags', {
name: {
type: DataTypes.STRING,
unique: true,
},
description: DataTypes.TEXT,
});
}
db-init.js (this is run manually):
const { Sequelize, DataTypes } = require('sequelize');
const db = new Sequelize({
dialect: 'sqlite',
storage: './database.sqlite',
});
require('./models/tag.js')(db, DataTypes);
const force = process.argv.includes('--force') || process.argv.includes('-f');
db.sync({ force }).then(async () => {
console.log('Database synced.');
db.close();
}).catch(console.error);
commands/addTag.js:
const { Tags } = require('../models/tag.js');
const { SlashCommandBuilder } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('addtag')
.setDescription('Create a tag!')
.addStringOption(option =>
option
.setName('name')
.setDescription('The name of your tag')
.setRequired(true)
)
.addStringOption(option =>
option
.setName('description')
.setDescription('The tag description')
.setRequired(true)
),
async execute(interaction) {
const name = interaction.options.getString('name');
const description = interaction.options.getString('description');
try {
const tag = await Tags.create({
name: name,
description: description,
});
return interaction.reply(`Tag \`${tag.name}\` created.`);
} catch (error) {
if (error.name = 'SequelizeUniqueConstraintError') return interaction.reply('That tag already exists!');
return interaction.reply({ content: 'An error occured.', ephemeral: true });
}
}
}
The /addtag [tag name] [tag description] command is supposed to create a tag or send a message if the tag already exists. Whenever I run the command, I don't get any errors but the bot says the tag already exists even though it doesn't. Can someone please explain why these commands don't function properly?
In your commands/tag.js you are requiring const { Tags } = require('../models/tag.js'); which is just a function definition to define a database, not the actual database. That function doesn't have a definition of 'findOne' like javascript is responding.
you probably need to create the db object like you are in the db-init.js file
I am working on a discord bot. And, I am having issues writing to the database. I am using these three files to communicate with the database. For some reason I am getting a:
TypeError: Cannot read properties of undefined (reading 'createLap') Error. It is coming from the second file that I posted.
const mongoose = require('mongoose');
const lapSchema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
guildId: String,
memberId: String,
laps:{type: Number, default: 0},
})
module.exports = mongoose.model('Lap', lapSchema, 'laps');
const { SlashCommandBuilder } = require('#discordjs/builders');
const Lap = require('../../schemas/lap');
module.exports = {
data: new SlashCommandBuilder()
.setName('lap')
.setDescription('It\'s been a pleasure watching you race! Let\'s take a look at your stats!')
.addSubcommand(subcommand =>
subcommand
.setName("tag-someone-else")
.setDescription("Gets laps of a user that has been tagged!")
.addUserOption(option => option.setName("target").setDescription("The user mentioned"))),
async execute(interaction, client) {
let user = (interaction.options.getUser("target") ? interaction.options.getUser("target") : interaction.user);
console.log(user);
const userProfile = await client.createLap(interaction.member);
await interaction.reply({content: `${interaction.user.tag} has ${userProfile.laps}.`})
},
};
const mongoose = require("mongoose");
const Lap = require('../schemas/lap');
module.exports = (client) => {
client.createLap = async (member) =>{
console.log("Hitting here");
let lapProfile = await Lap.findOne({memberId: member.id, guildId: member.guild.id});
if (lapProfile){
return lapProfile;
}else{
console.log("hits here")
lapProfile = await new Lap({
_id: mongoose.Types.ObjectId(),
guildId: member.guild.id,
memberId: member.id,
});
await lapProfile.save().catch(err => console.log(err));
console.log("Lap Created! This is great news.");
return lapProfile;
}
};
};
module.exports = (client) => {
client.handleEvents = async (eventFiles, path) =>{
for (const file of eventFiles) {
const event = require(`../events/${file}`);
if (event.once) {
client.once(event.name, (...args) => event.execute(...args, client));
} else {
client.on(event.name, (...args) => event.execute(...args, client));
}
}
}
}
So I'm making a setnote command so people can keep track of how much they have donated. However, It will only add it when I add them to the database and not after. I don't know why. So it just isn't updating or sending the message that it's even updated.
const { MessageEmbed } = require('discord.js')
const notesModel = require('../models/notesSchema')
module.exports = {
name: 'setnote',
aliases: ['sn'],
description: 'Add a note to a user.',
async execute(message, args, client, cmd, Discord, notesData) {
const mentionedMember = message.mentions.members.first() || message.guild.members.cache.get(args[0])
if (!args[0]) return message.channel.send('Please mention someone to add note to.')
if (!args[1]) return message.channel.send('Please state an amount to add to the user.')
const amountToAdd = args[1]
if (isNaN(args[1])) return message.channel.send('You have to add a number when setting note.')
let userData = await notesModel.findOne({
userID: mentionedMember.id,
serverID: message.guild.id,
})
if (!userData) {
userData = await notesModel.create({
userID: mentionedMember.id,
serverID: message.guild.id,
notes: 0
})
const response = await notesModel.findOneAndUpdate({
serverID: message.guild.id,
userID: mentionedMember.id
}, {
$inc: {
notes: +amountToAdd
}
})
userData = await notesModel.findOne({serverID: mentionedMember.guild.id, userID: mentionedMember.id});
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
const addedNote = new MessageEmbed()
.setTitle(`<a:red_check:845104782833352704> Successfully Added Note <a:red_check:845104782833352704>`)
.setDescription(`${mentionedMember.user.tag} has now donated \`${numberWithCommas(userData.notes)}\``)
.setColor('GREEN')
message.channel.send(addedNote)
}
}
}
I know this question has been answered before but I can't seem to implement the changes into what im working with. I'm trying to create a daily command that rewards a user for doing s!daily. I get the error,
TypeError: profileData.findOneAndUpdate is not a function
at Object.execute (C:\Users--\Desktop\DiscBot\commands\daily.js:35:43)
at module.exports (C:\Users--\Desktop\DiscBot\events\client\message.js:34:13)
daily.js, one having error at line 35 for findOneAndUpdate is not a function
const Schema = require('../models/profileSchema')
//cache users that claim daily rewards
let claimedCache = []
const clearCache = () => {
claimedCache = []
setTimeout(clearCache, 1000 * 60 * 10)
}
clearCache()
//message to make it easier later
const alreadyClaimed = 'You have already claimed your daily rewards'
module.exports = {
name: "daily",
aliases: ["day", "d"],
permissions: [],
description: "Claim your daily rewards!",
async execute(message, args, cmd, client, Discord, profileData) {
const { serverID, member } = message
const { id } = member
//If user is in cache return message
if (claimedCache.includes(id)) {
console.log('Returning from cache')
message.reply(alreadyClaimed)
return
}
//Put everything in object for later
const obj = {
guildId: serverID,
userId: id,
}
//Results is an update that either updates if is user is not in array and doesn't if they are, but it doesn't know what findOneAndUpdate is (thought it was just a mongo/mongoose function??)
try {
const results = await profileData.findOneAndUpdate(obj)
console.log('RESULTS:', results)
if (results) {
const then = new Date(results.updatedAt).getTime()
const now = new Date().getTime()
const diffTime = Math.abs(now - then)
const diffDays = Math.round(diffTime / (1000 * 60 * 60 * 24))
if (diffDays <= 1) {
claimedCache.push(id)
message.reply(alreadyClaimed)
return
}
}
//after the update increase coins by 50 and send claimed message
await profileRewardsSchema.findOneAndUpdate(obj, obj, {
upsert: true,
})
claimedCache.push(id)
const amount = 50;
await profileModel.findOneAndUpdate(
{
userID: id,
},
{
$inc: {
coins: amount,
},
}
);
message.reply('You have claimed your daily rewards!')
}catch (err) {
console.log(err);
}
}
}
message.js, heres where I make profileModel a thing using mongoose to pass it into my commands
const profileModel = require("../../models/profileSchema");
const config = require('../../config.json');
module.exports = async (Discord, client, message) => {
//command handler start
const prefix = 's!';
if (!message.content.startsWith(prefix) || message.author.bot) return;
//database junk
let profileData;
try {
profileData = await profileModel.findOne({ userID: message.author.id });
if (!profileData) {
let profile = await profileModel.create({
userID: message.author.id,
serverID: message.guild.id,
coins: 10,
bank: 0,
});
profile.save();
}
} catch (err) {
console.log("Error creating new database profile");
}
const args = message.content.slice(prefix.length).split(/ +/);
const cmd = args.shift().toLowerCase();
const command = client.commands.get(cmd) || client.commands.find(a => a.aliases && a.aliases.includes(cmd));
if(!command) return message.channel.send(":x: This is not a valid command");
try {
command.execute(message, args, cmd, client, Discord, profileData);
} catch (err) {
message.reply('There was an error executing that command!');
}
};
profileSchema.js, Where profile is made into mongo database
const mongoose = require("mongoose");
const profileSchema = new mongoose.Schema({
userID: { type: String, require: true, unique: true },
serverID: { type: String, require: true },
coins: { type: Number, default: 10 },
bank: { type: Number },
},
{
timestamps: true,
}
)
const model = mongoose.model("ProfileModels", profileSchema);
module.exports = model;
main.js, where mongoose is connected, then passed on
mongoose.connect(process.env.MONGODB_SRV, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false
})
You are trying to call findOneAndUpdate on the document, which you passed to execute function at message.js. Check the example of how to use findOneAndUpdate
https://mongoosejs.com/docs/tutorials/findoneandupdate.html
Most of the time this error happen when you call findOneAndUpdate in mongoose when you call it on the instance of the model NOT the actual model
so instead of this
var NewUser = new User(req.user);
NewUser.findOneAndUpdate...
do this
var NewUser = new User(req.user);
User.findOneAndUpdate(
{ name: NewUser.name },
{ name: NewUser.name},
{ upsert: true });
Here is my code for the >top10 command of my discord bot:
const Discord = require("discord.js");
module.exports.run = async(bot, message, args, con) => {
const top10query = `SELECT user, points, lstmsg FROM scores WHERE guild = '${message.guild.id}' ORDER BY cast(points as SIGNED) ASC LIMIT 10`
//const top10 = con.query(top10query)
const query = querytxt => {
return new Promise((resolve, reject) => {
con.query(querytxt, (err, results, fields) => {
if (err) reject(err);
resolve([results, fields]);
});
});
};
const [results, fields] = await query(top10query);
const map1 = results.map(results => `User: ${(bot.fetchUser(results.user)).username} Messages: ${results.points} Last message: ${results.lstmsg}`);
message.channel.send(map1)
}
module.exports.help = {
name: "top10",
usage: "``prefix`` top10",
description: "top 10 points",
}
The data for "user" is stored as the user ID. I get 'undefined' when I use the >top10 command.
Any ideas?
EDIT:
I've tried replacing
const map1 = results.map(results => `User: ${(bot.fetchUser(results.user)).username} Messages: ${results.points} Last message: ${results.lstmsg}`);
message.channel.send(map1)
With
const map1 = results.map(results => `User: ${(bot.users.get(results.user.id)).username} Messages: ${results.points} Last message: ${results.lstmsg}`);
But I'm getting this error:
(node:21128) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'username' of undefined
Replace
User: ${(bot.fetchUser(results.user)).username
with:
User: ${bot.users.get(results.user).username
You want to do
const map1 = await results.map(async result => {
const user = await client.fetchUser(result);
return `User: ${user.username} Messages: ${result.points} Last message: ${result.lstmsg}`;
});