I have connected MongoDB to my discord.js code and have made a setwelcome command as per-server data so that each server can customize their own welcome message. Everything works great, I just want to know if there is any way that I can make the message appear as an embed? Here's the code:
//importing all the needed files and languages
const mongo = require('./mongo')
const command = require('./command')
const welcomeSchema = require('./schemas/welcome-schema')
const mongoose = require('mongoose')
const Discord = require('discord.js')
mongoose.set('useFindAndModify', false);
//my code is inside this export
module.exports = (client) => {
//this next line is for later
const cache = {}
command(client, 'setwelcome', async (message) => {
const { member, channel, content, guild } = message
//checking to see that only admins can do this
if (!member.hasPermissions === 'ADMINISTRATOR') {
channel.send('You do not have the permission to run this command')
return
}
//simplifying commands
let text = content
//this is to store just the command and not the prefix in mongo compass
const split = text.split(' ')
if (split.length < 2) {
channel.send('Please provide a welcome message!')
return
}
split.shift()
text = split.join(' ')
//this is to not fetch from the database after code ran once
cache[guild.id] = [channel.id, text]
//this is to store the code inside mongo compass
await mongo().then(async (mongoose) => {
try {
await welcomeSchema.findOneAndUpdate({
_id: guild.id
}, {
_id: guild.id,
channelId: channel.id,
text,
}, {
upsert: true
})
} finally {
mongoose.connection.close()
}
})
})
//this is to fetch from the database
const onJoin = async (member) => {
const { guild } = member
let data = cache[guild.id]
if (!data) {
console.log('FETCHING FROM DATABASE')
await mongo().then( async (mongoose) => {
try {
const result = await welcomeSchema.findOne({ _id: guild.id })
cache[guild.id] = data = [result.channelId, result.text]
} finally {
mongoose.connection.close()
}
})
}
//this is to simplify into variables
const channelId = data[0]
const text = data[1]
/*this is where the message sends on discord. the second of these 2 lines is what I want embedded
which is basically the welcome message itself*/
const channel = guild.channels.cache.get(channelId)
channel.send(text.replace(/<#>/g, `<#${member.id}>`))
}
//this is to test the command
command(client, 'simjoin', message => {
onJoin(message.member)
})
//this is so the command works when someone joins
client.on('guildMemberAdd', member => {
onJoin(member)
})
}
I know how to usually make an embed, but I'm just confused at the moment on what to put as .setDescription() for the embed.
Please advise.
If you just want to have the message be sent as an embed, create a MessageEmbed and use setDescription() with the description as the only argument. Then send it with channel.send(embed).
const embed = new Discord.MessageEmbed();
embed.setDescription(text.replace(/<#>/g, `<#${member.id}>`));
channel.send(embed);
By the way, if you are confused about how to use a specific method you can always search for the method name on the official discord.js documentation so you don’t have to wait for an answer here. Good luck creating your bot!
Related
I'm working with the latest mongoose version of today (6.2.7) and I'm having a really weird bug.
This is my Schema:
const testSchema = new Schema<ITestSchema>({
age: Number
}, { timestamps: true });
const testModel = model<ITestSchema>("test", testSchema);
When I'm creating new collections out of it everything is working perfect! and I'm getting timestamps (updatedAt and createdAt) added to the collection.
But When I'm working with sessions the timestamps are not added and i see only "age", "_d" and "__v".
This is the example code for the creation with the sessions:
const test = async () => {
const session: ClientSession = await mongoose.startSession();
try {
session.startTransaction();
const newTest = new testModel({
age: 30,
}, { session });
await newTest.save({ session });
await session.commitTransaction();
} catch (error) {
await session.abortTransaction();
throw error;
} finally {
await session.endSession();
}
};
I tried read the doc several times and searched for similar issues online but could not find any.
Thanks 3>
i know the question is old but i just came across this and found a solution, you mistake is that you are using session in 2 different places both when creating the model and when saving, the thing is if you use session only on testModel it also won't work, so the session must only be used when calling save function
sample code:
const modelObject = {
'_id' : new Types.ObjectId(),
...dto
}
const newItem = new this.model(modelObject)
return newItem.save({
session
});
For some reason, the function .save() isn't saving my documents on MongoDB. All seem right and the first two registers work and update successfully, but my third register 'specialBanner' doesn't work.
When I console log service it doesn't show as part of the special object, although when I console special.specialBanner it is there.
Has anyone experienced something like this before?
Thanks for your help :)
const updateSpecial = async (req, res, next) => {
const { title, description, specialBanner } = req.body;
let special;
try {
special = await Special.findById(specialId);
} catch (err) {
const error = new HttpError(
"Something went wrong, could not update special.",
500
);
return next(error);
}
if (title) {
special.title = title;
}
if (description) {
special.description = description;
}
if (specialBanner) {
special.specialBanner = specialBanner;
}
try {
//Here if I check 'special I get all the right inputs, but the 'specialBanner'.
special = await special.save();
} catch (err) {
const error = new HttpError(
"Something went wrong, could not update special.",
500
);
return next(error);
}
res.status(200).json({ special: special.toObject({ getters: true }) });
};
I assume you are using mongoose and, Special is a collection.
Replace the line
special = await Special.findById(specialId)
with
special = await Special.findById(specialId).exec()
I can't figure out how to save fetched events from Calendar API. I was able to print out array of events in console. I would require save multiple events at once and have verification if they already exist in database with unique id.
Here's my event.js scheme in express js.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const EventSchema = new Schema({
id: {
type: String,
required: false,
unique:true
},
start: {
type: String
},
end: {
type: String
},
status: {
type: String
},
creator: {
type: Array
},
description: {
type: String
}
});
module.exports = Event = mongoose.model('events', EventSchema);
Here's my event.js router in express js.
router.post("/google/get", async (req, res, next) => {
const {
google
} = require('googleapis')
const {
addWeeks
} = require('date-fns')
const {
OAuth2
} = google.auth
const oAuth2Client = new OAuth2(
process.env.GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET
)
oAuth2Client.setCredentials({
refresh_token: process.env.GOOGLE_REFRESH_TOKEN,
})
const calendar = google.calendar({
version: 'v3',
auth: oAuth2Client
})
calendar.events.list({
calendarId: 'MY CALENDAR ID',
timeMin: new Date().toISOString(),
timeMax: addWeeks(new Date(), 1).toISOString(),
singleEvents: true,
orderBy: 'startTime',
},
function (err, response) {
if (err) {
console.log("The API returned an error: " + err)
return
}
var events = response.data.items
events.forEach(function (event) {
var start = event.start.dateTime || event.start.date
console.log("%s - %s", start, event.summary)
})
}
)
In Mongoose, in order to save something to a database, all you need to do is to instantiate the model that you created. Your event schema exports Event as a model that you can then treat as a regular object. So you would do something along the lines of:
let currentEvent = new Event({id, start, end, status, creator, description});
currentEvent.save();
Once that is done, it should be stored in your MongoDB. I assume that as the code for this is not visible it is already set up and working. You can just run the above inside of your for loop with some minor tweaks to grab each value correctly and it should sort your issue out!
As for your unique ID and making sure that it doesn't already exist in your database, you can use the same model to find values by checking the id against your database and seeing if it exists. As follows:
Event.findById(id, (err, event) => {
if(event == null) {
let currentEvent = new Event({id, start, end, status, creator, description});
currentEvent.save();
} else {
alert("Error, this event already exists")
}
});
I believe something like this should work, however I might have it wrong with how to check if the event exists, I can't remember if it returns null or something different, so just console log the value of event and check to see what it returns if there isn't an event that exists with that ID, and just re-run your if statement with that instead.
So when I use my discord bots kick command it says everything twice. I've tried restarting Visual Studio Code but it still doesn't work. I haven't duplicated my code or anything so I'm pretty confused on what the problem could be
const Discord = require('discord.js');
const client = new Discord.Client();
const prefix = '!';
const fs = require('fs');
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js'));
for(const file of commandFiles){
const command = require(`./commands/${file}`);
client.commands.set(command.name, command);
}
client.once('ready', () => {
console.log('KeyBot is online!');
});
client.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if (command === 'ping') {
message.channel.send('pong!');
}
});
client.on('message', (message) => {
if (!message.guild) return;
if (message.content.startsWith('!kick')) {
const user = message.mentions.users.first();
if (user) {
const member = message.guild.member(user);
if (member) {
member
.kick('Optional reason that will display in the audit logs')
.then(() => {
message.reply(`Successfully kicked ${user.tag}`);
})
.catch((err) => {
message.reply('I was unable to kick the member');
console.error(err);
});
} else {
message.reply("That user isn't in this guild!");
}
} else {
message.reply("You didn't mention the user to kick!");
}
}
});
I am using axios and express.js API to connect to my mongo DB. I have a .get() request that works for one collection and doesn't work for any other collection. This currently will connect to the database and can access one of the collections called users. I have another collection setup under the same database called tasks, I have both users and tasks setup the same way and being used the same way in the code. The users can connect to the DB (get, post) and the tasks fails to connect to the collection when calling the get or the post functions. When viewing the .get() API request in the browser it just hangs and never returns anything or finishes the request.
any help would be greatly appreciated!
The project is on GitHub under SCRUM-150.
API connection
MONGO_URI=mongodb://localhost:27017/mydb
Working
methods: {
//load all users from DB, we call this often to make sure the data is up to date
load() {
http
.get("users")
.then(response => {
this.users = response.data.users;
})
.catch(e => {
this.errors.push(e);
});
},
//opens delete dialog
setupDelete(user) {
this.userToDelete = user;
this.deleteDialog = true;
},
//opens edit dialog
setupEdit(user) {
Object.keys(user).forEach(key => {
this.userToEdit[key] = user[key];
});
this.editName = user.name;
this.editDialog = true;
},
//build the alert info for us
//Will emit an alert, followed by a boolean for success, the type of call made, and the name of the
//resource we are working on
alert(success, callName, resource) {
console.log('Page Alerting')
this.$emit('alert', success, callName, resource)
this.load()
}
},
//get those users
mounted() {
this.load();
}
};
Broken
methods: {
//load all tasks from DB, we call this often to make sure the data is up to date
load() {
http
.get("tasks")
.then(response => {
this.tasks = response.data.tasks
})
.catch(e => {
this.errors.push(e);
});
},
//opens delete dialog
setupDelete(tasks) {
this.taskToDelete = tasks;
this.deleteDialog = true;
},
//opens edit dialog
setupEdit(tasks) {
Object.keys(tasks).forEach(key => {
this.taskToEdit[key] = tasks[key];
});
this.editName = tasks.name;
this.editDialog = true;
},
//build the alert info for us
//Will emit an alert, followed by a boolean for success, the type of call made, and the name of the
//resource we are working on
alert(success, callName, resource) {
console.log('Page Alerting')
this.$emit('alert', success, callName, resource)
this.load()
}
},
//get those tasks
mounted() {
this.load();
}
};
Are you setting any access controls in the code?
Also refer to mongoDB's documentation here:
https://docs.mongodb.com/manual/core/collection-level-access-control/
Here is my solution:
In your app.js, have this:
let mongoose = require('mongoose');
mongoose.connect('Your/Database/Url', {
keepAlive : true,
reconnectTries: 2,
useMongoClient: true
});
In your route have this:
let mongoose = require('mongoose');
let db = mongoose.connection;
fetchAndSendDatabase('yourCollectionName', db);
function fetchAndSendDatabase(dbName, db) {
db.collection(dbName).find({}).toArray(function(err, result) {
if( err ) {
console.log("couldn't get database items. " + err);
}
else {
console.log('Database received successfully');
}
});
}