I changed my command handler and am no longer exporting anything from profileData (used to be command handler file). The file is checking for their profile and holding the data in profileData, or if they don't have on then create one for them. I want to export the profileData to be used in other files instead of querying in every single command. How can I achieve this. I have tried putting module.exports and exports.profileData = profileData all over the place and nothing works im just lost on how to do this. Any help would be appreciated.
profileData-
const profileModel = require("../../models/profileSchema");
module.exports = (client) => {
client.on("message", async (message) => {
const prefix = 's!'
if (!message.content.startsWith(prefix) || message.author.bot) return;
try {
const 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(err);
}
})
}
module.exports.config = {
displayName: 'Profile Data',
dbName: 'PROFILEDATA',
loadDBFirst: true
}
balance-
const { MessageEmbed } = require("discord.js");
const { profileData } = require("../../Features/client/profileData");
module.exports = {
name: "balance",
aliases: ["bal"],
category: "Economy",
cooldown: "20s",
permissions: ["ADMINISTRATOR"],
maxArgs: 0,
description: "Check your wallet and bank balance!",
execute: async ({ message, client }) => {
let balPlaceholder = "'s balance";
const BalEmbed = new MessageEmbed()
.setColor("#0bbffc")
.setAuthor("Saoul 2")
.setTitle(`${message.author.username}${balPlaceholder}`)
.addFields(
{ name: "💸 Wallet:", value: `${profileData.coins}`, inline: true },
{ name: "🏦 Bank:", value: `${profileData.bank}`, inline: true }
)
.setTimestamp()
.setFooter(
`Command Requested By ${message.author.tag}`,
client.user.displayAvatarURL()
);
message.channel.send(BalEmbed);
},
};
If I understand you correctly: you want to export the profileData, and if none can be found, create a new profile and use that. The following snippet might solve your problem.
const profileModel = require("../../models/profileSchema");
let data = getData(client);
exports.data = data;
async function getData(client) {
client.on("message", async(message) => {
const prefix = 's!'
if (!message.content.startsWith(prefix) || message.author.bot) return;
try {
const 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();
return profile;
} else {
return profileData;
}
} catch (err) {
console.log(err);
}
})
}
module.exports.config = {
displayName: 'Profile Data',
dbName: 'PROFILEDATA',
loadDBFirst: true
}
This is all I needed to get the function to run when a message is sent through the command handler.
module.exports = {
getData: async (message) => {
try {
Related
Main bot file
const {
Client,
GatewayIntentBits,
Routes,
EmbedBuilder,
ActivityType,
} = require('discord.js');
const { token, clientId, guildId } = require('../config.json');
const { REST } = require('#discordjs/rest');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildBans,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
});
const { UrlCommand } = require('../Commands/UrlCommand.json');
client.on('ready', (client) => {
console.log(`${client.user.username}#${client.user.discriminator} running`);
client.user.setPresence({
activities: [{ name: 'connections', type: ActivityType.Watching }],
});
});
client.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'url') {
console.log(`called ${interaction.commandName} command`);
const urlEmbed = new EmbedBuilder()
.setColor('0x0099FF')
.setTitle('LEPSES')
.setURL('https://lepses.com')
.setAuthor({
name: 'LEPSES Bot',
// TODO: replace icon
iconURL:
'https://upload.wikimedia.org/wikipedia/commons/thumb/8/89/Latin_capital_letter_L_with_descender.svg/497px-Latin_capital_letter_L_with_descender.svg.png',
})
.setDescription('You choose, we connect!')
.addFields(
// TODO : add more data in the fields
{ name: 'Regular field title', value: 'Some value here' },
{ name: '\u200B', value: '\u200B' },
{
name: 'Inline field title',
value: 'Some value here',
inline: true,
},
{
name: 'Inline field title',
value: 'Some value here',
inline: true,
}
);
await interaction.reply({ embeds: [urlEmbed] });
}
if (interaction.commandName === 'clear') {
if (interaction.options.get('amount') >= 5000) {
interaction.reply('You cannot delete more than 5000 messages');
} else {
try {
const amount = interaction.options.getInteger('amount');
const Channel = interaction.channel;
if (amount) {
Channel.bulkDelete(amount, true);
await interaction.reply(`${amount} messages purged`);
} else {
Channel.bulkDelete(50, true);
await interaction.reply(`50 messages purged`);
}
} catch (err) {
console.log(err.message);
}
}
}
});
const rest = new REST({ version: '10' }).setToken(token);
async function main() {
// const commands = [];
const commands = [UrlCommand];
try {
console.log(
`Started refresing application ${commands.length} commands`
);
await rest.put(Routes.applicationGuildCommands(clientId, guildId), {
body: commands,
});
client.login(token);
} catch (error) {
console.log('ERROR=================================================');
console.log(error.message);
console.log('ERROR=================================================');
}
}
main();
URL Command in json file
{
"name": "url",
"description": "Visit us now!!"
}
Url command was in the main file earlier but now I'm moving older commands to external files to make the code smaller and easier to change in the future. But as soon as the code runs it shows BASE_TYPE_REQUIRED error. It runs normally if I declare commands as an empty array. What do I do?
You have to write the exported command in JavaScript as well. JSON is a storage file type. Try refering to discord.js command handling guide and see if it helps you.
so I'm making a message count command with discord.js and MongoDB but the "messageCount" value just never gets created. I searched it up and looked at docs but I couldn't find what was wrong.
Codes:
message-counter.js file:
const mongo = require("mongoose")
const schema = require("./schemas/rank/message-count-schema")
module.exports = client => {
client.on('messageCreate', async (message) => {
const { author } = message
const { id } = author
mongo.connect(
process.env.MONGO_URI,
{ keepAlive: true }
)
const dataQuery = await schema.findOne({ _id: id })
if (!dataQuery) {
const newSchem = schema(
{
_id: id
},
{
$setOnInsert: { messageCount: 1 }
},
{
$inc: { messageCount: 1 }
},
{
upsert: true
}
)
await newSchem.save()
}
else {
dataQuery.updateOne(
{
$inc: { messageCount: 1 }
},
{
upsert: true
}
)
}
})
}
message-count-schema.js file:
const mongoose = require('mongoose');
const messageCountSchema = new mongoose.Schema({
_id: {
type: String,
required: true
},
messageCount: {
type: Number,
required: true
}
})
module.exports = mongoose.model('message-count', messageCountSchema);
Can someone tell me what's wrong and how to fix it? I'm not asking to be spoon fed, just what's wrong.
The thing is $setOnInsert is only valid for update operations when the upsert value is set to true. It exists in these methods => updateOne(), updateMany, findAndModify(). In this case, when it not an update operation, the $setOnInsert doesn't run which is why your data doesn't have the messageCount value.
Like caladan said before, and adding to that you need .findbyId() if you want to use _id, is your message count is per user or per guild?
if per user you can add to your schema a userID String item and use
const member = await message.mentions.members.first() || message.guild.members.cache.get(args[0]) || message.author;
const dataQuery = await schema.findOne({ UserID: member.id })
const messagecount = dataQuery.messageCount;
console.log(messagecount)
If per guild, you can add GildId item in your schema, and use:
const dataQuery = await schema.findOne({ GuildId: message.guild.id })
const messagecount = dataQuery.messageCount;
console.log(messagecount)
I need some help please,
When I click on the button Submit, it doesn't do what I want it to, it doesn't show up with any errors, and the bot doesn't crash so I'm not sure how to fix it.
This has never happened to me before so I'm just wondering I'm someone could point me in the right direction.
Suggest.js :
const { ButtonInteraction, MessageEmbed } = require("discord.js");
const DB = require('../Structures/Handlers/Schemas/SuggestDB');
const { APPLICATIONID } = require("../Structures/config.json")
const Embed1 = require('../Commands/Suggest/suggestion');
module.exports = {
name: "interactionCreate",
/**
*
* #param {ButtonInteraction} interaction
*/
async execute(interaction) {
if(!interaction.isButton()) return;
const { guildId, customId, message } = interaction;
DB.findOne({GuildID: guildId, MessageID: message.id}, async(err, data) => {
if(err) throw err;
if(!data) return interaction.reply({content: "No data was found in the database", ephemeral: true});
const Embed = message.embeds[0];
if(!Embed) return;
switch(customId) {
case "Submit" : {
await guild.channels.cache
.get(APPLICATIONID)
.send({ embeds: [Embed1] });
}
}
})
}
}
Suggestion.js
const { CommandInteraction, MessageEmbed, MessageActionRow, MessageButton, ButtonInteraction }
= require("discord.js");
const DB = require("../../Structures/Handlers/Schemas/SuggestDB");
module.exports = {
name:"suggest",
description: "Suggest",
options: [
{
name: "suggestion",
description: "Describe your suggestion",
type: "STRING",
required: true
}
],
/**
*
* #param {CommandInteraction} interaction
* #param {ButtonInteraction} interaction1
*/
async execute(interaction) {
const { options, guildId, member, user } = interaction;
const Suggestion = options.getString("suggestion");
const Embed1 = new MessageEmbed()
.setColor("AQUA")
.setAuthor(user.tag, user.displayAvatarURL({dynamic: true}))
.addFields(
{name: "Suggestion", value: Suggestion, inline: false}
)
.setTimestamp()
const row = new MessageActionRow();
row.addComponents(
new MessageButton()
.setCustomId("Submit")
.setLabel("Submit")
.setStyle("PRIMARY")
.setEmoji("📩"),
)
try {
const M = await interaction.reply({embeds: [Embed1], components: [row], fetchReply: true});
await DB.create({GuildID: guildId, MessageID: M.id, Details: [
{
MemberID: member.id,
Suggestion: Suggestion
}
]})
} catch (err) {
console.log(err)
}
},
};
Any help is appreciated.
If you need any more information / code files, just reply and I'll will add it straight away.
I made a bot that verifies people with API and stores the data in mongoose but I want the code to work in discord DMS but I have no clue how to make it give roles in a specific server when the command is run in DMS this is my code:
const fetch = require('node-fetch')
const ignSchema = require('../schemas/ign-schema')
const mongo = require('../mongo')
module.exports = {
commands: ['verifyme'],
minArgs: 0,
maxArgs: null,
expectedArgs: "<minecraft name>",
callback: async(message, arguments, text) => {
const playerName = arguments.join(' ')
fetch(`https://api.hypixel.net/player?key=MYAPIKEY&name=${playerName}`)
.then(response => response.json())
.then(async data => {
player = data
const target = message.author
const author2 = message.author.tag
const uuid = data["player"]["uuid"]
const discordid = data["player"]["socialMedia"]["links"]["DISCORD"]
let verifyRole = message.guild.roles.cache.find(role => role.name === '[Verified]');
let memberTarget = message.guild.members.cache.get(target.id);
const guildId = message.guild.id
const userId = message.author.id
const UUID = uuid
const _id = UUID
if (discordid == author2) {
await mongo().then(async mongoose => {
try {
const results2 = await ignSchema.findOne({
_id,
})
const {
UUID,
userData,
discordName
} = results2
if (UUID == uuid) {
if (author2 == discordName) {
if (message.member.roles.cache.some(role => role.name === "[Verified]")) {
message.reply('you are already verified')
} else {
memberTarget.roles.add(verifyRole)
message.reply('welcome back')
}
} else {
message.reply(`you already used this minecraft account to verify ${discordName}, if you want to change this please contact <#390929478790152192>`)
mongoose.connection.close()
return
}
} else {}
} catch {
const userData = {
timestamp: new Date().getTime(),
}
await mongo().then(async(mongoose) => {
try {
await ignSchema.findOneAndUpdate({
_id
}, {
UUID,
discordName: author2,
HypixelName: playerName,
userId: userId,
guildId: guildId,
$push: {
userData: userData
},
}, {
upsert: true
})
memberTarget.roles.add(verifyRole)
message.reply('you are succesfully verified')
} finally {
mongoose.connection.close()
}
})
}
})
} else {
message.reply(`change your linked discord account in hypixel from ${discordid} to ${author2},`)
}
console.log(`${discordid}`)
})
},
}
and this is the error I get:
UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'roles' of null
If there is more than one server the bot is in, this is not possible without making major assumptions as to the guild they are in.
If there is only one server, message.guild.roles can be changed to client.guilds.cache.get('your_servers_id').roles.
How can I replace the oldguild(old server's name) to a new one when server updated? I tried with GuildID(discord server id) and everything but nothing seem to work. When the bot saves it, then looks like this in the MongoDB Compass: Screenshot, and for example this is how it looks like in MongoDB Compass normally: Old name server, but I want it look like this New name server.
This is my code.
client.on("guildUpdate", (oldguild, newguild) => {
var name = [oldguild.name, newguild.name];
if(name[0] == null) {
name[0] = oldguild.name
}
if(name[1] == null) {
name[1] = oldguild.name
}
if(oldguild.name !== newguild.name)
{
async function guildUpdated() {
const servername = new setprefixModel ({
_id: mdb.Types.ObjectId(),
GuildID: setprefixModel.GuildId,
Guild: oldguild.name,
Prefix: setprefixModel.Prefix
});
const reqservername = await setprefixModel.findOne({ Guild: oldguild.name });
if(!reqservername) {
return await servername.save();
}
else {
const updatedDocument = await setprefixModel.findOneAndUpdate(
{ Guild: oldguild.name },
{ Guild: newguild.name },
{ new: true }
);
updatedDocument;
}
}
guildUpdated();
}
})
client.on("guildUpdate", (oldguild, newguild) => {
var name = [oldguild.name, newguild.name];
if(name[0] == null) {
name[0] = oldguild.name
}
if(name[1] == null) {
name[1] = oldguild.name
}
if(oldguild.name !== newguild.name)
{
async function guildUpdated() {
const servername = new setprefixModel ({
_id: mdb.Types.ObjectId(),
GuildID: String,
Guild: oldguild.name,
Prefix: String
});
const reqservername = await setprefixModel.findOne({ Guild: oldguild.name });
if(!reqservername) {
return await servername.save();
}
else {
const updatedDocument = await setprefixModel.findOneAndUpdate(
{ Guild: oldguild.name },
{ Guild: newguild.name },
{ new: true }
);
updatedDocument;
}
}
guildUpdated();
}
})
Changed at const servername.