const mongoose = require("mongoose");
const Messages = require("./models/messages.js");
var mongoUrl;
/**
*
*
* @class DiscordMessages
*/
class DiscordMessages {
/**
*
*
* @static
* @param {string} [dbUrl] - A valid mongo database URI.
* @return {Promise} - The mongoose connection promise.
* @memberof DiscordMessages
*/
static async setURL(dbUrl) {
if (!dbUrl) throw new TypeError("A database url was not provided.");
mongoUrl = dbUrl;
return mongoose.connect(dbUrl, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false
});
}
/**
*
*
* @static
* @param {string} [userId] - Discord user id.
* @param {string} [guildId] - Discord guild id.
* @return {objcet} - The user data object.
* @memberof DiscordMessages
*/
static async createUser(userId, guildId) {
if (!userId) throw new TypeError("An user id was not provided.");
if (!guildId) throw new TypeError("A guild id was not provided.");
const isUser = await Messages.findOne({ userID: userId, guildID: guildId });
if (isUser) return false;
const newUser = new Messages({
userID: userId,
guildID: guildId
});
await newUser.save().catch(e => console.log(`Failed to create user: ${e}`));
return newUser;
}
/**
*
*
* @static
* @param {string} [userId] - Discord user id.
* @param {string} [guildId] - Discord guild id.
* @return {objcet} - The user data object.
* @memberof DiscordMessages
*/
static async deleteUser(userId, guildId) {
if (!userId) throw new TypeError("An user id was not provided.");
if (!guildId) throw new TypeError("A guild id was not provided.");
const user = await Messages.findOne({ userID: userId, guildID: guildId });
if (!user) return false;
await Messages.findOneAndDelete({ userID: userId, guildID: guildId }).catch(e => console.log(`Failed to delete user: ${e}`));
return user;
}
/**
*
*
* @static
* @param {string} [userId] - Discord user id.
* @param {string} [guildId] - Discord guild id.
* @param {number} [messages] - Amount of messages to append.
* @return {objcet} - The user data object.
* @memberof DiscordMessages
*/
static async appendMessage(userId, guildId, messages) {
if (!userId) throw new TypeError("An user id was not provided.");
if (!guildId) throw new TypeError("A guild id was not provided.");
if (messages == 0 || !messages || isNaN(parseInt(messages))) throw new TypeError("An amount of messages was not provided/was invalid.");
const user = await Messages.findOne({ userID: userId, guildID: guildId });
if (!user) {
const newUser = new Messages({
userID: userId,
guildID: guildId,
messages: messages
});
await newUser.save().catch(e => console.log(`Failed to save new user.`));
return messages;
};
user.messages += parseInt(messages, 10);
await user.save().catch(e => console.log(`Failed to append messages: ${e}`) );
return user.messages
}
/**
*
*
* @static
* @param {string} [userId] - Discord user id.
* @param {string} [guildId] - Discord guild id.
* @param {number} [messages] - Amount of messages to set.
* @return {objcet} - The user data object.
* @memberof DiscordMessages
*/
static async setMessages(userId, guildId, messages) {
if (!userId) throw new TypeError("An user id was not provided.");
if (!guildId) throw new TypeError("A guild id was not provided.");
if (messages == 0 || !messages || isNaN(parseInt(messages))) throw new TypeError("An amount of messages was not provided/was invalid.");
const user = await Messages.findOne({ userID: userId, guildID: guildId });
if (!user) return false;
user.messages = messages;
user.save().catch(e => console.log(`Failed to set messages: ${e}`) );
return user;
}
/**
*
*
* @static
* @param {string} [userId] - Discord user id.
* @param {string} [guildId] - Discord guild id.
* @param {boolean} [fetchPosition=false] - Wheter to fetch the users position.
* @return {objcet} - The user data object.
* @memberof DiscordMessages
*/
static async fetch(userId, guildId, fetchPosition = false) {
if (!userId) throw new TypeError("An user id was not provided.");
if (!guildId) throw new TypeError("A guild id was not provided.");
const user = await Messages.findOne({
userID: userId,
guildID: guildId
});
if (!user) return false;
let userobj = {}
if (fetchPosition === true) {
const leaderboard = await Messages.find({
guildID: guildId
}).sort([['messages', 'descending']]).exec();
userobj.position = leaderboard.findIndex(i => i.userID === userId) + 1;
}
userobj.data = user
return userobj;
}
/**
*
*
* @static
* @param {string} [userId] - Discord user id.
* @param {string} [guildId] - Discord guild id.
* @param {number} [messages] - Amount of messages to subtract.
* @return {objcet} - The user data object.
* @memberof DiscordMessages
*/
static async subtractMessages(userId, guildId, messages) {
if (!userId) throw new TypeError("An user id was not provided.");
if (!guildId) throw new TypeError("A guild id was not provided.");
if (messages == 0 || !messages || isNaN(parseInt(messages))) throw new TypeError("An amount of messages was not provided/was invalid.");
const user = await Messages.findOne({ userID: userId, guildID: guildId });
if (!user) return false;
user.messages -= messages;
user.save().catch(e => console.log(`Failed to subtract messages: ${e}`) );
return user;
}
/**
*
*
* @static
* @param {string} [guildId] - Discord guild id.
* @param {number} [limit] - Amount of maximum enteries to return.
* @return {Array} - The leaderboard array.
* @memberof DiscordMessages
*/
static async fetchLeaderboard(guildId, limit) {
if (!guildId) throw new TypeError("A guild id was not provided.");
if (!limit) throw new TypeError("A limit was not provided.");
var users = await Messages.find({ guildID: guildId }).sort([['messages', 'descending']]).exec();
return users.slice(0, limit);
}
/**
*
*
* @static
* @param {string} [client] - Your Discord.CLient.
* @param {array} [leaderboard] - The output from 'fetchLeaderboard' function.
* @param {boolean} [fetchUsers=false] - Wheter to fetch each users position.
* @return {*}
* @memberof DiscordMessages
*/
static async computeLeaderboard(client, leaderboard, fetchUsers = false) {
if (!client) throw new TypeError("A client was not provided.");
if (!leaderboard) throw new TypeError("A leaderboard id was not provided.");
if (leaderboard.length < 1) return [];
const computedArray = [];
if (fetchUsers) {
for (const key of leaderboard) {
const user = await client.users.fetch(key.userID) || { username: "Unknown", discriminator: "0000" };
computedArray.push({
guildID: key.guildID,
userID: key.userID,
messages: key.messages,
position: (leaderboard.findIndex(i => i.guildID === key.guildID && i.userID === key.userID) + 1),
username: user.username,
discriminator: user.discriminator
});
}
} else {
leaderboard.map(key => computedArray.push({
guildID: key.guildID,
userID: key.userID,
messages: key.messages,
position: (leaderboard.findIndex(i => i.guildID === key.guildID && i.userID === key.userID) + 1),
username: client.users.cache.get(key.userID) ? client.users.cache.get(key.userID).username : "Unknown",
discriminator: client.users.cache.get(key.userID) ? client.users.cache.get(key.userID).discriminator : "0000"
}));
}
return computedArray;
}
}
module.exports = DiscordMessages;