Compare commits

..

23 Commits

Author SHA1 Message Date
admin_rb bb90ca792c removed debug 2026-04-08 11:42:16 +02:00
admin_rb 0c84c85b62 changed order for quickmode 2026-04-08 11:38:39 +02:00
admin_rb 0218583d24 migrated 2026-04-08 11:37:01 +02:00
admin_rb e2cc63e6c9 renamed db column 2026-04-07 22:01:21 +02:00
admin_rb ad32efb156 added nut context to cooldown 2026-04-07 22:01:03 +02:00
admin_rb 466b9708cf re-added quotes chat command for adding them by reply function 2026-04-07 20:23:27 +02:00
admin_rb f41f848ad5 updated README 2026-04-07 08:57:59 +02:00
admin_rb 2c596fe23f attempted to streamline by breaking functions into separate source 2026-04-07 08:45:26 +02:00
admin_rb 83c204670d added sample env 2026-04-06 22:58:21 +02:00
admin_rb d8200e46df updated README 2026-04-06 22:55:34 +02:00
admin_rb 9d56ee5d34 added README.md 2026-04-06 22:54:26 +02:00
admin_rb e2e764c295 updated todo 2026-04-06 22:32:55 +02:00
admin_rb 6533510481 Updated more Thumbnails to reliable sources,, fixed quotes leaderboard 2026-04-06 22:31:54 +02:00
admin_rb 664224b14e updated gitignore 2026-04-06 22:05:13 +02:00
admin_rb e59a863a8d Added Local Nut Assets, Restructured Nut Handler 2026-04-06 21:59:37 +02:00
admin_rb 2691653132 Moved Assets to Subdir, Migrated some old commands 2026-04-06 21:27:16 +02:00
admin_rb 5e8fb7e729 moved to subdir 2026-04-06 20:07:58 +02:00
admin_rb f1f9d95685 updated todo 2026-04-06 17:22:11 +02:00
admin_rb 6d8d8402a5 fixed honors 2026-04-06 17:22:07 +02:00
admin_rb 202d0ef7bb fixed config 2026-04-06 17:22:02 +02:00
admin_rb d26b5e5c56 fixed nuts stats 2026-04-06 17:21:56 +02:00
admin_rb 564216ee8a Fixed Deprecation of Ephemeral 2026-04-06 16:21:57 +02:00
admin_rb 0769a482fb fixed Birthday Event, Renamed DB Colls 2026-04-06 15:47:54 +02:00
67 changed files with 1160 additions and 791 deletions
+6
View File
@@ -0,0 +1,6 @@
D_ID=
D_Token=
D_Prefix=
D_GuildID=
M_URI=
M_DB=
-3
View File
@@ -1,5 +1,2 @@
.env
node_modules
To-Do
cookies
findMessages.js
+59
View File
@@ -0,0 +1,59 @@
# Arthonor-Neo
**Moderately Advanced Discord Bot for Friends**
Arthonor-Neo is a custom Discord bot designed for community interaction and fun. It offers an assortment of commands for economy, social engagement, and server utilities. Suitable for small to medium-sized friend servers.
---
## Features
### Core Interactions
- Nut Economy Earn and spend nuts in server activities
- Honor System Show recognition and respect to users
- Quotes Save and retrieve memorable quotes
### Community & Events
- Automatic Welcome Messages Greet new members
- Birthday System Track and celebrate birthdays
- Automatic Birthday Cards Personalized greetings on birthdays
- Wednesday Frog Midweek server event
- Friday Reminder (Coming Soon)
---
## Differences from Version 2.x
### Legacy Commands (Chat Messages)
These have been mostly removed with certain exceptions:
- Quoteadd has been kept due to the technicaly incompabiltity of replying using slash commands.
- Nuts has been kept due to frequent usage
### Removed
- Timers
- WGE
- Weather commands
- GIF commands
- Certain developer tools
- WOKCommands Core
### Upgraded to Slash Commands
- Nuts
- Quotes
- Honor
- Birthdays
- Role Selection
- Channel Selection
- Meme Commands
### New and Improved
- Interactive Honor Menu
- Interactive Quote Menu
### Database Migration
Some structurual changes to the command schema, and removal of predefined schematics
- Tables renamed with prefixes, e.g. items_, config_, stats_, etc.
- Split tables into a relation-ish style
- made some data more machine-friendly
+1 -7
View File
@@ -1,9 +1,3 @@
- quotes leaderboard (count)
### ToDo?:
- quotes filter by channel
- event creation + reminder 1h before
- birthday role
- 8ball (neue Antworten)
- avatar
- mittwoch
- wetter
- WGE (help)
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 158 KiB

Before

Width:  |  Height:  |  Size: 536 KiB

After

Width:  |  Height:  |  Size: 536 KiB

+3 -3
View File
@@ -1,4 +1,4 @@
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js")
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, MessageFlags } = require("discord.js")
const { mClient } = require("../..")
require('dotenv').config()
@@ -9,7 +9,7 @@ module.exports = {
let description = interaction.message.embeds[0].data.description
const target = await interaction.guild.members.fetch(description.split(' ')[0].slice(2, -1))
const db = mClient.db(process.env.M_DB)
const honorsColl = db.collection('honors')
const honorsColl = db.collection('items_honors')
const reason = `[-] Quick Menu Dishonor`
const theirHonorLevel = await honorsColl.findOne({ userID: target.id })
@@ -36,7 +36,7 @@ module.exports = {
await interaction.reply({
embeds: [embed],
components: [row],
ephemeral: true
flags: MessageFlags.Ephemeral
})
}
}
+3 -3
View File
@@ -1,4 +1,4 @@
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js")
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, MessageFlags } = require("discord.js")
const { mClient } = require("../..")
require('dotenv').config()
@@ -9,7 +9,7 @@ module.exports = {
let description = interaction.message.embeds[0].data.description
const target = await interaction.guild.members.fetch(description.split(' ')[0].slice(2, -1))
const db = mClient.db(process.env.M_DB)
const reasonsColl = db.collection('honor-reasons')
const reasonsColl = db.collection('history_honors')
const history = await reasonsColl.findOne({ userID: target.user.id })
const embed = new EmbedBuilder()
@@ -30,7 +30,7 @@ module.exports = {
await interaction.reply({
embeds: [embed],
components: [select, row],
ephemeral: true
flags: MessageFlags.Ephemeral
})
}
}
+3 -3
View File
@@ -1,4 +1,4 @@
const { EmbedBuilder, ButtonBuilder, ActionRowBuilder, ButtonStyle } = require("discord.js")
const { EmbedBuilder, ButtonBuilder, ActionRowBuilder, ButtonStyle, MessageFlags } = require("discord.js")
const { mClient } = require("../..")
require('dotenv').config()
@@ -9,7 +9,7 @@ module.exports = {
let description = interaction.message.embeds[0].data.description
const target = await interaction.guild.members.fetch(description.split(' ')[0].slice(2, -1))
const db = mClient.db(process.env.M_DB)
const honorsColl = db.collection('honors')
const honorsColl = db.collection('items_honors')
const reason = `[+] Quick Menu Honor`
const theirHonorLevel = await honorsColl.findOne({ userID: target.id })
@@ -37,7 +37,7 @@ module.exports = {
await interaction.reply({
embeds: [embed],
components: [row],
ephemeral: true
flags: MessageFlags.Ephemeral
})
}
}
+4 -4
View File
@@ -1,4 +1,4 @@
const { EmbedBuilder } = require("discord.js")
const { EmbedBuilder, MessageFlags } = require("discord.js")
const { mClient } = require("../..")
require('dotenv').config()
@@ -13,15 +13,15 @@ module.exports = {
} else if (temp[5] === '**Dishonor**'){
honor = -1
} else {
return await interaction.reply({content: "ERROR", ephemeral: true})
return await interaction.reply({content: "ERROR", flags: MessageFlags.Ephemeral})
}
const target = await interaction.message.guild.members.fetch(temp[3].slice(2, -1))
temp = interaction.message.embeds[0].description.split('\r\n')
const reason = `${temp[1].slice(7, -1)}`
const db = mClient.db(process.env.M_DB)
const honorsColl = db.collection('honors')
const reasonsColl = db.collection('honor-reasons')
const honorsColl = db.collection('items_honors')
const reasonsColl = db.collection('history_honors')
const theirHonorLevel = await honorsColl.findOne({ userID: target.id })
await honorsColl.findOneAndUpdate({ userID: target.id }, { $inc: { honors: honor } }, { upsert: true })
+2 -2
View File
@@ -7,7 +7,7 @@ module.exports = {
description: 'navigate a page up',
async execute(interaction) {
const db = mClient.db(process.env.M_DB)
const honorsColl = db.collection('honors')
const honorsColl = db.collection('items_honors')
const min = 0
let skip = interaction.message.embeds[0].data.description.split('.')
skip = Number(skip[0]) - 6
@@ -23,7 +23,7 @@ module.exports = {
})
const embed = new EmbedBuilder()
.setTitle('Honors Leaderboard')
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152940755539722240/pngwing.com.png')
.setThumbnail(guild.iconURL({ dynamic: true}))
.setDescription(fields.toString())
.setColor('#5865F2') // Discord's blurple color
.setFooter({ text: 'Use ◄ ► to navigate' });
+2 -2
View File
@@ -6,7 +6,7 @@ module.exports = {
description: 'navigate a page down',
async execute(interaction) {
const db = mClient.db(process.env.M_DB)
const honorsColl = db.collection('honors')
const honorsColl = db.collection('items_honors')
const max = await honorsColl.countDocuments()
let skip = interaction.message.embeds[0].data.description.split('.')
skip = Number(skip[0]) +4
@@ -21,7 +21,7 @@ module.exports = {
})
const embed = new EmbedBuilder()
.setTitle('Honors Leaderboard')
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152940755539722240/pngwing.com.png')
.setThumbnail(guild.iconURL({ dynamic: true}))
.setDescription(fields.toString())
.setColor('#5865F2') // Discord's blurple color
.setFooter({ text: 'Use ◄ ► to navigate' });
+2 -2
View File
@@ -6,7 +6,7 @@ module.exports = {
description: 'navigate to your own placement',
async execute(interaction) {
const db = mClient.db(process.env.M_DB)
const honorsColl = db.collection('honors')
const honorsColl = db.collection('items_honors')
const self = await honorsColl.find({ userID: interaction.user.id }).toArray()
const all = await honorsColl.find().sort({ honors: -1 }).toArray()
@@ -31,7 +31,7 @@ module.exports = {
})
const embed = new EmbedBuilder()
.setTitle('Honors Leaderboard')
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152940755539722240/pngwing.com.png')
.setThumbnail(guild.iconURL({ dynamic: true}))
.setDescription(fields.toString())
.setColor('#5865F2') // Discord's blurple color
.setFooter({ text: 'Use ◄ ► to navigate' });
+1 -1
View File
@@ -12,7 +12,7 @@ module.exports = {
const to = await interaction.message.guild.members.fetch(temp[6].slice(2,-1))
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const nutsColl = db.collection('items_nuts')
await nutsColl.findOneAndUpdate({ userID: from.id }, { $inc: { nuts: -amount } }, { upsert: true })
await nutsColl.findOneAndUpdate({ userID: to.id }, { $inc: { nuts: +amount } }, { upsert: true })
+1 -1
View File
@@ -10,7 +10,7 @@ module.exports = {
const to = await interaction.message.guild.members.fetch(temp[6].slice(2,-1))
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const nutsColl = db.collection('items_nuts')
const yourBalance = await nutsColl.findOne({ userID: from.id })
const theirBalance = await nutsColl.findOne({ userID: to.id })
+2 -2
View File
@@ -7,7 +7,7 @@ module.exports = {
description: 'navigate a page up',
async execute(interaction) {
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const nutsColl = db.collection('items_nuts')
const min = 0
let skip = interaction.message.embeds[0].data.description.split('.')
skip = Number(skip[0]) - 6
@@ -23,7 +23,7 @@ module.exports = {
})
const embed = new EmbedBuilder()
.setTitle('Nuts Leaderboard')
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152940755539722240/pngwing.com.png')
.setThumbnail(guild.iconURL({ dynamic: true}))
.setDescription(fields.toString())
.setColor('#5865F2') // Discord's blurple color
.setFooter({ text: 'Use ◄ ► to navigate' });
+2 -2
View File
@@ -6,7 +6,7 @@ module.exports = {
description: 'navigate a page down',
async execute(interaction) {
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const nutsColl = db.collection('items_nuts')
const max = await nutsColl.countDocuments({ nuts: { $gt: 0 } })
let skip = interaction.message.embeds[0].data.description.split('.')
skip = Number(skip[0]) +4
@@ -21,7 +21,7 @@ module.exports = {
})
const embed = new EmbedBuilder()
.setTitle('Nuts Leaderboard')
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152940755539722240/pngwing.com.png')
.setThumbnail(guild.iconURL({ dynamic: true}))
.setDescription(fields.toString())
.setColor('#5865F2') // Discord's blurple color
.setFooter({ text: 'Use ◄ ► to navigate' });
+2 -2
View File
@@ -6,7 +6,7 @@ module.exports = {
description: 'navigate to your own placement',
async execute(interaction) {
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const nutsColl = db.collection('items_nuts')
const self = await nutsColl.find({ userID: interaction.user.id }).toArray()
const all = await nutsColl.find({ nuts: { $gt: 0 } }).sort({ nuts: -1 }).toArray()
@@ -31,7 +31,7 @@ module.exports = {
})
const embed = new EmbedBuilder()
.setTitle('Nuts Leaderboard')
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152940755539722240/pngwing.com.png')
.setThumbnail(guild.iconURL({ dynamic: true}))
.setDescription(fields.toString())
.setColor('#5865F2') // Discord's blurple color
.setFooter({ text: 'Use ◄ ► to navigate' });
+11 -62
View File
@@ -1,70 +1,19 @@
const { EmbedBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder } = require('discord.js');
const { mClient } = require('../..'); // Adjust the path as needed
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
const { quotesLeaderboard } = require("../../commands/slash/applications/quotes");
module.exports = {
name: 'quotes_leaderboard_right',
description: 'Navigate right through the quotes leaderboard',
name: 'quotes_leaderboard_left',
description: 'Navigate left through the quotes leaderboard',
async execute(interaction) {
await interaction.deferReply()
const db = mClient.db(process.env.M_DB)
const quotesColl = db.collection('quotes')
const maxValue = await quotesColl.countDocuments({ $and: [{ guildID: interaction.guild.id }, { count: { $gt: 0 } }] })
await interaction.deferReply();
let skip = interaction.message.embeds[0].data.fields[0].value.split('.')
skip = Number(skip[0]) - 6
if (skip >= (maxValue - (maxValue % 5))) {
skip = maxValue - (maxValue % 5)
}
// Parse current page from footer
let page = 1;
const footerText = interaction.message.embeds[0]?.footer?.text || '';
const match = footerText.match(/Page (\d+) of (\d+)/);
if (match) page = Number(match[1]);
const quotesData = await quotesColl.find({ count: { $gt: 0 } }).sort({ count: -1, messageID: -1 }).skip(skip).limit(5).toArray()
const fields = []
page--; // move to previous page
const guild = await interaction.client.guilds.fetch(interaction.guild.id)
quotesData.forEach(async (data, index) => {
let channel = await guild.channels.fetch(data.channelID)
let message = await channel.messages.fetch(data.messageID)
await delay(500)
fields.push({
name: `\u200b`,
value: `${skip + index + 1}. [#${data.messageID}](https://discord.com/channels/${data.guildID}/${data.channelID}/${data.messageID})\r\n**by** <@${data.by}> • ⭐ ${data.count}\r\n${message.content}`
})
})
await delay(5000)
console.log(fields)
const embed = new EmbedBuilder()
.setTitle('- Quotes Leaderboard -')
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152940755539722240/pngwing.com.png')
.setFields(fields)
.setColor('#5865F2') // Discord's blurple color
.setFooter({ text: 'Use ◄ ► to navigate' });
const row = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setLabel('◄')
.setStyle(ButtonStyle.Primary)
.setCustomId('quotes_leaderboard_left')
.setDisabled(skip - 6 < 0)
)
.addComponents(
new ButtonBuilder()
.setLabel('X')
.setStyle(ButtonStyle.Danger)
.setCustomId('abort')
)
.addComponents(
new ButtonBuilder()
.setLabel('►')
.setStyle(ButtonStyle.Primary)
.setCustomId('quotes_leaderboard_right')
.setDisabled(skip + 4 > maxValue)
)
await interaction.editReply({
embeds: [embed],
components: [row]
})
await quotesLeaderboard(interaction, page);
}
};
+9 -60
View File
@@ -1,70 +1,19 @@
const { EmbedBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder } = require('discord.js');
const { mClient } = require('../..'); // Adjust the path as needed
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
const { quotesLeaderboard } = require("../../commands/slash/applications/quotes");
module.exports = {
name: 'quotes_leaderboard_right',
description: 'Navigate right through the quotes leaderboard',
async execute(interaction) {
await interaction.deferReply()
const db = mClient.db(process.env.M_DB)
const quotesColl = db.collection('quotes')
const maxValue = await quotesColl.countDocuments({ $and: [{ guildID: interaction.guild.id }, { count: { $gt: 0 } }] })
await interaction.deferReply();
let skip = interaction.message.embeds[0].data.fields[0].value.split('.')
skip = Number(skip[0]) +4
if (skip >= (maxValue - (maxValue % 5))) {
skip = maxValue - (maxValue % 5)
}
// Parse current page from footer
let page = 1;
const footerText = interaction.message.embeds[0]?.footer?.text || '';
const match = footerText.match(/Page (\d+) of (\d+)/);
if (match) page = Number(match[1]);
const quotesData = await quotesColl.find({ count: { $gt: 0 } }).sort({ count: -1, messageID: -1 }).skip(skip).limit(5).toArray()
const fields = []
page++; // move to next page
const guild = await interaction.client.guilds.fetch(interaction.guild.id)
quotesData.forEach(async (data, index) => {
let channel = await guild.channels.fetch(data.channelID)
let message = await channel.messages.fetch(data.messageID)
await delay(500)
fields.push({
name: `\u200b`,
value: `${skip + index + 1}. [#${data.messageID}](https://discord.com/channels/${data.guildID}/${data.channelID}/${data.messageID})\r\n**by** <@${data.by}> • ⭐ ${data.count}\r\n${message.content}`
})
})
await delay(5000)
console.log(fields)
const embed = new EmbedBuilder()
.setTitle('- Quotes Leaderboard -')
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152940755539722240/pngwing.com.png')
.setFields(fields)
.setColor('#5865F2') // Discord's blurple color
.setFooter({ text: 'Use ◄ ► to navigate' });
const row = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setLabel('◄')
.setStyle(ButtonStyle.Primary)
.setCustomId('quotes_leaderboard_left')
.setDisabled(skip - 6 < 0)
)
.addComponents(
new ButtonBuilder()
.setLabel('X')
.setStyle(ButtonStyle.Danger)
.setCustomId('abort')
)
.addComponents(
new ButtonBuilder()
.setLabel('►')
.setStyle(ButtonStyle.Primary)
.setCustomId('quotes_leaderboard_right')
.setDisabled(skip + 4 > maxValue)
)
await interaction.editReply({
embeds: [embed],
components: [row]
})
await quotesLeaderboard(interaction, page);
}
};
+7 -7
View File
@@ -1,4 +1,4 @@
const { EmbedBuilder, UserSelectMenuBuilder, ActionRowBuilder } = require("discord.js")
const { EmbedBuilder, UserSelectMenuBuilder, ActionRowBuilder, MessageFlags } = require("discord.js")
const { mClient } = require("../..")
require('dotenv').config()
module.exports = {
@@ -6,16 +6,16 @@ module.exports = {
description: 'navigate left',
async execute(interaction) {
let oldEmbed = interaction.message.embeds[0].data
if (!oldEmbed.footer) { return interaction.reply({ content: 'Please use a Filter', ephemeral: true }) }
if (oldEmbed.fields && oldEmbed.fields[0].value == 0) { return interaction.reply({ content: 'This User has no Quotes', ephemeral: true }) }
if (!oldEmbed.footer) { return interaction.reply({ content: 'Please use a Filter', flags: MessageFlags.Ephemeral }) }
if (oldEmbed.fields && oldEmbed.fields[0].value == 0) { return interaction.reply({ content: 'This User has no Quotes', flags: MessageFlags.Ephemeral }) }
let userID = interaction.message.embeds[0].data.footer.text.split(' ')[5].slice(2, -1)
const target = await interaction.guild.members.fetch(userID)
if (!target) { return interaction.reply({ content: 'Please use a Filter', ephemeral: true }) }
if (!target) { return interaction.reply({ content: 'Please use a Filter', flags: MessageFlags.Ephemeral }) }
const db = mClient.db(process.env.M_DB)
const quotesColl = db.collection('quotes')
const quotes = await quotesColl.find({ by: target.id }).toArray()
const quotesColl = db.collection('items_quotes')
const quotes = await quotesColl.find({ userID: target.id }).toArray()
var index = Number((await interaction.message.embeds[0].data.title).split(' ')[2].slice(1))
if (!index) { index = 0 }
@@ -64,7 +64,7 @@ module.exports = {
.setURL(messageLink)
.setTitle(`- Quote #${index + 1} -`)
.setDescription(description)
.setFooter({ text: (`${footer} #${found.messageID} <@${found.by}>`) })
.setFooter({ text: (`${footer} #${found.messageID} <@${found.userID}>`) })
const select = new ActionRowBuilder()
.addComponents(
new UserSelectMenuBuilder()
+8 -8
View File
@@ -1,4 +1,4 @@
const { EmbedBuilder, UserSelectMenuBuilder, ActionRowBuilder } = require("discord.js")
const { EmbedBuilder, UserSelectMenuBuilder, ActionRowBuilder, MessageFlags } = require("discord.js")
const { mClient } = require("../..")
require('dotenv').config()
module.exports = {
@@ -6,20 +6,20 @@ module.exports = {
description: 'navigate right',
async execute(interaction) {
let oldEmbed = interaction.message.embeds[0].data
if (!oldEmbed.footer) { return interaction.reply({ content: 'Please use a Filter', ephemeral: true }) }
if (oldEmbed.fields && oldEmbed.fields[0].value == 0) { return interaction.reply({ content: 'This User has no Quotes', ephemeral: true }) }
if (!oldEmbed.footer) { return interaction.reply({ content: 'Please use a Filter', flags: MessageFlags.Ephemeral }) }
if (oldEmbed.fields && oldEmbed.fields[0].value == 0) { return interaction.reply({ content: 'This User has no Quotes', flags: MessageFlags.Ephemeral }) }
let userID = interaction.message.embeds[0].data.footer.text.split(' ')[5].slice(2, -1)
const target = await interaction.guild.members.fetch(userID)
if (!target) { return interaction.reply({ content: 'Please use a Filter', ephemeral: true }) }
if (!target) { return interaction.reply({ content: 'Please use a Filter', flags: MessageFlags.Ephemeral }) }
const db = mClient.db(process.env.M_DB)
const quotesColl = db.collection('quotes')
const quotes = await quotesColl.find({ by: target.id }).toArray()
const quotesColl = db.collection('items_quotes')
const quotes = await quotesColl.find({ userID: target.id }).toArray()
var index = Number((await interaction.message.embeds[0].data.title).split(' ')[2].slice(1))
if (!index) { index = 0 }
//if (index >= quotes.length){ return interaction.reply({content: 'Max Quotes Reached', ephemeral: true})}
//if (index >= quotes.length){ return interaction.reply({content: 'Max Quotes Reached', flags: MessageFlags.Ephemeral})}
if (index >= quotes.length) { index-- }
// will automatically reflect the next index due to how arrays think
@@ -64,7 +64,7 @@ module.exports = {
.setURL(messageLink)
.setTitle(`- Quote #${index + 1} -`)
.setDescription(description)
.setFooter({ text: (`${footer} #${found.messageID} <@${found.by}>`) })
.setFooter({ text: (`${footer} #${found.messageID} <@${found.userID}>`) })
const select = new ActionRowBuilder()
.addComponents(
new UserSelectMenuBuilder()
-106
View File
@@ -1,106 +0,0 @@
const { SlashCommandBuilder, Events } = require('discord.js')
const { mClient } = require('../..')
require('dotenv').config()
async function channelSet(interaction) {
const channel = interaction.options.getChannel('channel')
const purpose = interaction.options.getString('purpose')
const db = mClient.db(process.env.DB)
const channelColl = db.collection('channels')
await channelColl.findOneAndUpdate({
$and: [{ guildID: channel.guild.id }, { purpose: purpose }]
}, {
$set: {
guildID: channel.guild.id,
purpose: purpose,
channelID: channel.id
}
}, {
upsert: true
})
return await interaction.editReply({
content: `Set <#${channel.id}> as ${purpose} channel!`, ephemeral: true
})
}
async function channelSimulate(interaction) {
const purpose = interaction.options.getString('purpose')
switch (purpose) {
case 'birthday':
await interaction.client.emit('Birthday', interaction.member)
break;
case 'wge':
// For Future WGE Use
break;
case 'welcome':
await interaction.client.emit(Events.GuildMemberAdd, interaction.member)
break;
case 'logs':
// For Future Log Use
break;
default:
break;
}
return interaction.reply({ content: 'Done.', ephemeral: true })
}
module.exports = {
data: new SlashCommandBuilder()
.setName('channels')
.setDescription('rund um den honor')
.addSubcommand(s =>
s
.setName('set')
.setDescription('set a channel for a specific purpose')
.addStringOption(o =>
o.setName('purpose').setDescription('set the purpose').setRequired(true).addChoices({
name: 'birthday',
value: 'birthday'
}, {
name: 'welcome',
value: 'welcome'
}, {
name: 'logs',
value: 'logs'
}, {
name: 'wge',
value: 'wge'
}))
.addChannelOption(c =>
c.setName('channel').setDescription('choose a channel').setRequired(true)
)
)
.addSubcommand(s =>
s
.setName('simulate')
.setDescription('simulate a specific channel event')
.addStringOption(o =>
o.setName('purpose').setDescription('set the purpose').setRequired(true).addChoices({
name: 'birthday',
value: 'birthday'
}, {
name: 'welcome',
value: 'welcome'
}, {
name: 'logs',
value: 'logs'
}, {
name: 'wge',
value: 'wge'
}))
)
,
async execute(interaction) {
switch (interaction.options._subcommand) {
case 'set':
await interaction.deferReply()
channelSet(interaction)
break;
case 'simulate':
channelSimulate(interaction)
break;
default:
break;
}
}
}
+9
View File
@@ -0,0 +1,9 @@
const ping = require("../../../src/ping")
module.exports = {
name: 'ping',
description: 'dev tool',
aliases: ['p'],
async execute(message, args) {
return ping(message, args, 'legacy')
}}
@@ -1,5 +1,5 @@
const { EmbedBuilder } = require('discord.js')
const { mClient } = require('../../index')
const { mClient } = require('../../../index')
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
require('dotenv').config()
module.exports = {
@@ -32,7 +32,7 @@ module.exports = {
}
}
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const nutsColl = db.collection('items_nuts')
var nutsData = await nutsColl.findOne({ userID: target.id })
let content
@@ -1,5 +1,5 @@
const { EmbedBuilder } = require('discord.js')
const { mClient } = require('../../index')
const { mClient } = require('../../../index')
require('dotenv').config()
module.exports = {
name: 'nutsCooldown',
@@ -7,7 +7,7 @@ module.exports = {
aliases: ['ncd'],
async execute(message, args) {
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('cooldown')
const nutsColl = db.collection('items_cooldowns')
const cooldown = await nutsColl.findOne({ userID: message.author.id })
let content = `Du kannst wieder nussen! :)`
+61
View File
@@ -0,0 +1,61 @@
const { mClient } = require('../../../index')
require('dotenv').config()
module.exports = {
name: 'nuts',
description: 'get nuts',
aliases: ['n', 'nget', 'nutsget'],
async execute(message, args) {
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('items_nuts')
const nutsStatsColl = db.collection('stats_nuts')
const cdColl = db.collection('items_cooldowns')
const cdData = await cdColl.findOne({ userID: message.author.id })
if (cdData?.cooldown > (Date.now() / 1000)) {
return await message.reply({
content: `Du kannst erst <t:${Math.floor(cdData?.cooldown)}:R> wieder nussen :(`,
})
}
let cd = Math.floor((Date.now() + 3600000) / 1000)
await cdColl.findOneAndUpdate({
userID: message.author.id
}, {
$set: {
cooldown: cd,
application: 'nuts'
}
}, {
upsert: true
})
const amount = Math.floor(Math.random() * 10)
await nutsColl.findOneAndUpdate({
userID: message.author.id
}, {
$inc: { nuts: amount }
}, {
upsert: true
})
await nutsStatsColl.findOneAndUpdate(
{ userID: message.author.id },
{ $inc: { [`stat.${amount}`]: 1 } },
{ upsert: true }
)
await nutsStatsColl.findOneAndUpdate(
{ userID: "__global" },
{ $inc: { [`stat.${amount}`]: 1 } },
{ upsert: true }
)
let content = `Du hast ${amount} Nüsse bekommen! :chestnut:`
if (!amount) {
content = `Du hast leider keine Nüsse bekommen :(`
}
return await message.reply({
content: content
})
}
}
@@ -1,5 +1,5 @@
const { EmbedBuilder } = require('discord.js')
const { mClient } = require('../../index')
const { mClient } = require('../../../index')
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
require('dotenv').config()
module.exports = {
@@ -48,7 +48,7 @@ module.exports = {
}
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const nutsColl = db.collection('items_nuts')
const yourBalance = await nutsColl.findOne({ userID: from.id })
if (amount <= 0) {
return await message.reply({
@@ -1,5 +1,5 @@
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js')
const { mClient } = require('../../index')
const { mClient } = require('../../../index')
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
require('dotenv').config()
module.exports = {
@@ -27,7 +27,7 @@ module.exports = {
.setCustomId('nuts_leaderboard_right')
)
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const nutsColl = db.collection('items_nuts')
let skip = 0
const nutsData = await nutsColl.find({ nuts: { $gt: 0 } }).sort({ nuts: -1 }).skip(skip).limit(5).toArray()
let fields
@@ -37,7 +37,7 @@ module.exports = {
})
const embed = new EmbedBuilder()
.setTitle('Nuts Leaderboard')
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152940755539722240/pngwing.com.png')
.setThumbnail(guild.iconURL({ dynamic: true}))
.setDescription(fields.toString())
.setColor('#5865F2') // Discord's blurple color
.setFooter({ text: 'Use ◄ ► to navigate' });
+76
View File
@@ -0,0 +1,76 @@
const { EmbedBuilder, MessageFlags } = require("discord.js")
const { client, mClient } = require("../../../index")
module.exports = {
name: 'quotesadd',
description: 'adds a quote to the database by replying to the message',
category: 'Quotes',
aliases: ['qadd', 'qa'],
async execute(message, args) {
const refMessage = message.reference // message to be quoted has been replied to
const refMessageId = refMessage.messageId
const refChannelId = refMessage.channelId
const refGuildId = refMessage.guildId
var msgData = {}
var refData = {}
const quoteGuild = await client.guilds.fetch(refGuildId)
const quoteChannel = await quoteGuild.channels.fetch(refChannelId)
const quoteMessage = await quoteChannel.messages.fetch(refMessageId)
msgData = {
content: quoteMessage.content,
author: await quoteMessage.author,
reference: await quoteMessage.reference,
embed: await quoteMessage.embeds ? 'embed' : null
} // debug
if (msgData.reference) {
const quoteRefGuild = await client.guilds.fetch(msgData.reference.guildId)
const quoteRefChannel = await quoteRefGuild.channels.fetch(msgData.reference.channelId)
const quoteRefMessage = await quoteRefChannel.messages.fetch(msgData.reference.messageId)
refData = {
content: quoteRefMessage.content,
author: await quoteRefMessage.author,
embed: await quoteRefMessage.embeds.length > 0 ? 'embed' : null
}
}
const db = mClient.db(process.env.M_DB)
const quotesColl = db.collection('items_quotes')
const found = await quotesColl.findOne({ messageID: quoteMessage.id })
if (found) { return await message.reply({ content: 'Quote Already in Database', flags: MessageFlags.Ephemeral }) }
await quotesColl.findOneAndUpdate({ messageID: quoteMessage.id }, {
$set: {
messageID: quoteMessage.id,
channelID: quoteChannel.id,
guildID: quoteGuild.id,
userID: msgData.author.id,
count: 0
}
}, { upsert: true })
var description = ''
if (refData) {
description += `> ${refData.author}`
if (refData.embed) {
description += '*an embed / a command* '
} else {
description += refData.content
}
description += `\r\n`
}
const messageLink = `https://discord.com/channels/${quoteGuild.id}/${quoteChannel.id}/${quoteMessage.id}/`
description += `${msgData.author} ${msgData.content}\r\n\r\n${messageLink}`
let timestamp = new Date(message.createdTimestamp)
let footer = timestamp.toDateString().toString()
const embed = new EmbedBuilder()
.setThumbnail(msgData.author.displayAvatarURL())
.setURL(messageLink)
.setTitle(`- Quote Added! -`)
.setDescription(description)
.setFooter({ text: (footer + ' #' + quoteMessage.id) })
await message.reply({ embeds: [embed] })
}
}
@@ -1,5 +1,5 @@
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js')
const { mClient } = require('../..')
const { SlashCommandBuilder, EmbedBuilder, MessageFlags } = require('discord.js')
const { mClient } = require('../../../index')
const { configDotenv } = require('dotenv')
configDotenv()
@@ -7,7 +7,7 @@ function isValidDate(day, month) {
// Define the number of days in each month
const daysInMonth = {
1: 31, // January
2: 28, // February (ignore leap years)
2: 28, // February (fuck leap years, me an' the homies hate that)
3: 31, // March
4: 30, // April
5: 31, // May
@@ -32,23 +32,37 @@ function isValidDate(day, month) {
return true;
}
function getNextBirthdayTimestamp(day, month) {
const now = new Date();
now.setHours(0, 0, 0, 0);
async function birthdayAdd(interaction) {
const currentYear = now.getFullYear();
let nextBirthday = new Date(currentYear, month - 1, day);
// If birthday already passed this year → next year
if (nextBirthday < now) {
nextBirthday.setFullYear(currentYear + 1);
}
return Math.floor(nextBirthday.getTime() / 1000); // Unix timestamp
}
async function birthdaySet(interaction) {
let target = await interaction.options.getUser('user')
let day = await interaction.options.getNumber('day')
let month = await interaction.options.getNumber('month')
if (!isValidDate(day, month)) {
return interaction.reply({ content: "Invalid Date", ephemeral: true })
return interaction.reply({ content: "Invalid Date", flags: MessageFlags.Ephemeral })
}
const db = mClient.db(process.env.M_DB)
const bdayColl = db.collection('birthdays')
const bdayColl = db.collection('items_birthdays')
const found = await bdayColl.findOne({ userID: target.id })
if (found) {
return interaction.reply({ content: "Already in Database", ephemeral: true })
return interaction.reply({ content: "Already in Database", flags: MessageFlags.Ephemeral })
}
const data = {
@@ -77,11 +91,11 @@ async function birthdayDelete(interaction) {
}
const db = mClient.db(process.env.M_DB)
const bdayColl = db.collection('birthdays')
const bdayColl = db.collection('items_birthdays')
const found = await bdayColl.findOne({ userID: target.id })
if (!found) {
return interaction.reply({ content: "Not yet in Database", ephemeral: true })
return interaction.reply({ content: "Not yet in Database", flags: MessageFlags.Ephemeral })
}
const res = await bdayColl.deleteOne({ userID: target.id })
@@ -91,81 +105,39 @@ async function birthdayDelete(interaction) {
return interaction.reply({ content: "There was an issue!" })
}
}
async function birthdayEdit(interaction) {
let target = await interaction.options.getUser('user')
let day = await interaction.options.getNumber('day')
let month = await interaction.options.getNumber('month')
if (!isValidDate(day, month)) {
return interaction.reply({ content: "Invalid Date", ephemeral: true })
}
const db = mClient.db(process.env.M_DB)
const bdayColl = db.collection('birthdays')
const found = await bdayColl.findOne({ userID: target.id })
if (!found) {
return interaction.reply({ content: "Not yet in Database", ephemeral: true })
}
const data = {
guildID: interaction.guild.id,
userID: target.id,
day: day,
month: month
}
const res = await bdayColl.findOneAndUpdate({ userID: target.id }, { $set: data }, { upsert: true })
return interaction.reply({ content: "Birthday edited successfully!" })
}
async function isDateInPast(day, month) {
const currentYear = new Date().getFullYear();
const inputDate = new Date(currentYear, month - 1, day);
const now = new Date();
return inputDate < now;
}
async function makeTimestamp(day, month, year) {
const date = new Date(year, month - 1, day);
const unixTimestamp = Math.floor(date.getTime() / 1000);
return unixTimestamp
}
function isToday(day, month) {
const currentYear = new Date().getFullYear();
const inputDate = new Date(currentYear, month - 1, day);
const today = new Date();
return (
inputDate.getDate() === today.getDate() &&
inputDate.getMonth() === today.getMonth() &&
inputDate.getFullYear() === today.getFullYear()
);
}
async function birthdayGet(interaction) {
let target = await interaction.options.getUser('user')
const db = mClient.db(process.env.M_DB)
const bdayColl = db.collection('birthdays')
const target = await interaction.options.getUser('user');
const db = mClient.db(process.env.M_DB);
const bdayColl = db.collection('items_birthdays');
const found = await bdayColl.findOne({ userID: target.id })
const found = await bdayColl.findOne({ userID: target.id });
if (!found) {
return interaction.reply({ content: "Not in Database!", ephemeral: true })
return interaction.reply({
content: "Date not in Database!",
flags: MessageFlags.Ephemeral
});
}
let unix
if(isDateInPast(found.day,found.month)){
let nextYear = new Date().getFullYear() + 1
unix = await makeTimestamp(found.day,found.month, nextYear)
const now = new Date();
const isToday =
now.getDate() === found.day &&
now.getMonth() === (found.month - 1);
let description;
if (isToday) {
description = `IS TODAY! 🥳🎉`;
} else {
let thisYear = new Date().getFullYear()
unix = await makeTimestamp(found.day,found.month, thisYear)
}
let description = `is on the <t:${unix}:d>\r\n<t:${unix}:R>`
if(isToday(found.day, found.month)){
description = `IS TODAY!🥳🎉`
const unix = getNextBirthdayTimestamp(found.day, found.month);
description = `is on the <t:${unix}:d>\n<t:${unix}:R>`;
}
const embed = new EmbedBuilder()
.setThumbnail(target.displayAvatarURL())
.setTitle(`${target.globalName ? target.globalName: target.username}'s Birthday!`)
.setDescription(description)
await interaction.reply({ embeds: [embed] })
.setTitle(`${target.globalName ?? target.username}'s Birthday...`)
.setDescription(description);
await interaction.reply({ embeds: [embed] });
}
module.exports = {
@@ -174,8 +146,8 @@ module.exports = {
.setDescription('manage birthdays')
.addSubcommand(s =>
s
.setName('add')
.setDescription('adds a birthday')
.setName('set')
.setDescription('set date to birthday')
.addUserOption((option) =>
option
.setName('user')
@@ -204,16 +176,6 @@ module.exports = {
option.setName('user').setDescription('user'))
.addStringOption((option) =>
option.setName('id').setDescription('ID')))
.addSubcommand(s =>
s
.setName('edit')
.setDescription('edits a birthday')
.addUserOption((option) =>
option.setName('user').setDescription('user').setRequired(true))
.addNumberOption((option) =>
option.setName('day').setDescription('day').setRequired(true))
.addNumberOption((option) =>
option.setName('month').setDescription('month').setRequired(true)))
.addSubcommand(s =>
s
.setName('get')
@@ -222,33 +184,24 @@ module.exports = {
option.setName('user').setDescription('user').setRequired(true))),
async execute(interaction) {
switch (interaction.options._subcommand) {
case 'add':
case 'set':
if (!interaction.member.permissions.has("ADMINISTRATOR")) {
return await interaction.reply({
content: "Unprivileged Access!",
ephemeral: true
flags: MessageFlags.Ephemeral
})
}
birthdayAdd(interaction)
birthdaySet(interaction)
break;
case 'delete':
if (!interaction.member.permissions.has("ADMINISTRATOR")) {
return await interaction.reply({
content: "Unprivileged Access!",
ephemeral: true
flags: MessageFlags.Ephemeral
})
}
birthdayDelete(interaction)
break;
case 'edit':
if (!interaction.member.permissions.has("ADMINISTRATOR")) {
return await interaction.reply({
content: "Unprivileged Access!",
ephemeral: true
})
}
birthdayEdit(interaction)
break;
case 'get':
birthdayGet(interaction)
break;
+171
View File
@@ -0,0 +1,171 @@
const { SlashCommandBuilder, Events, MessageFlags } = require('discord.js')
const { mClient } = require('../../../index')
require('dotenv').config()
async function channelSet(interaction) {
const channel = interaction.options.getChannel('channel')
const purpose = interaction.options.getString('purpose')
const db = mClient.db(process.env.M_DB)
const channelColl = db.collection('config_channels')
await channelColl.findOneAndUpdate({
$and: [{ guildID: channel.guild.id }, { purpose: purpose }]
}, {
$set: {
guildID: channel.guild.id,
purpose: purpose,
channelID: channel.id
}
}, {
upsert: true
})
return await interaction.editReply({
content: `Set <#${channel.id}> as ${purpose} channel!`, flags: MessageFlags.Ephemeral
})
}
async function channelSimulate(interaction) {
const purpose = interaction.options.getString('purpose')
switch (purpose) {
case 'birthday':
await interaction.client.emit('Birthday', interaction.member)
break;
case 'wge':
// For Future WGE Use
break;
case 'welcome':
await interaction.client.emit(Events.GuildMemberAdd, interaction.member)
break;
case 'logs':
// For Future Log Use
break;
default:
break;
}
return interaction.reply({ content: 'Done.', flags: MessageFlags.Ephemeral })
}
async function roleSet(interaction) {
const guild = interaction.guild
const purpose = interaction.options.getString('purpose')
const role = interaction.options.getRole('role')
const db = mClient.db(process.env.M_DB)
const roleColl = db.collection('config_roles')
switch (purpose) {
case 'birthday':
await roleColl.findOneAndUpdate({
$and: [{ guildID: guild.id }, { purpose: purpose }]
}, {
$set: {
guildID: guild.id,
purpose: purpose,
roleID: role.id
}
}, {
upsert: true
})
break;
default:
break;
}
return await interaction.editReply({
content: `Set ${role} as default role for ${purpose} in ${guild} `
})
}
module.exports = {
data: new SlashCommandBuilder()
.setName('config')
.setDescription('configurations for admins')
.addSubcommandGroup(sg =>
sg
.setName('channels')
.setDescription('configure channels for certain events')
.addSubcommand(s =>
s.setName('set')
.setDescription('sets channel')
.addStringOption(o =>
o.setName('purpose').setDescription('set the purpose').setRequired(true).addChoices({
name: 'birthday',
value: 'birthday'
}, {
name: 'welcome',
value: 'welcome'
}, {
name: 'logs',
value: 'logs'
}, {
name: 'wge',
value: 'wge'
}))
.addChannelOption(c =>
c.setName('channel').setDescription('choose a channel').setRequired(true)
)
)
.addSubcommand(s =>
s
.setName('simulate')
.setDescription('simulate a specific channel event')
.addStringOption(o =>
o.setName('purpose').setDescription('set the purpose').setRequired(true).addChoices({
name: 'birthday',
value: 'birthday'
}, {
name: 'welcome',
value: 'welcome'
}, {
name: 'logs',
value: 'logs'
}, {
name: 'wge',
value: 'wge'
}))
)
)
.addSubcommandGroup(sg =>
sg.setName('roles')
.setDescription('configure roles for certain events')
.addSubcommand(s =>
s.setName('set')
.setDescription('sets roles')
.addStringOption(o =>
o.setName('purpose').setDescription('set the purpose').setRequired(true).addChoices({
name: 'birthday',
value: 'birthday'
}))
.addRoleOption(c =>
c.setName('role').setDescription('choose a role').setRequired(true)
)
)
),
async execute(interaction) {
switch (interaction.options._group) {
case 'channels':
switch (interaction.options._subcommand) {
case 'set':
await interaction.deferReply()
channelSet(interaction)
break;
case 'simulate':
channelSimulate(interaction)
break;
default:
break;
}
case 'roles':
switch (interaction.options._subcommand) {
case 'set':
await interaction.deferReply()
roleSet(interaction)
break;
default:
break;
}
default:
break;
}
}
}
+11
View File
@@ -0,0 +1,11 @@
const { SlashCommandBuilder } = require("discord.js");
const ping = require("../../../src/ping");
module.exports = {
data: new SlashCommandBuilder()
.setName('ping')
.setDescription('dev tool'),
async execute(interaction) {
return ping(interaction, null, 'slash')
}
}
@@ -1,11 +1,11 @@
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, UserSelectMenuBuilder } = require('discord.js')
const { mClient } = require('../..')
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, UserSelectMenuBuilder, MessageFlags } = require('discord.js')
const { mClient } = require('../../../index')
require('dotenv').config()
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
async function honorHoner(interaction) {
const db = mClient.db(process.env.M_DB)
const honorsColl = db.collection('honors')
const honorsColl = db.collection('items_honors')
const target = await interaction.options.getUser('target')
const reason = `[+] ${await interaction.options.getString('reason') ?? 'No reason provided'}`
@@ -35,12 +35,12 @@ async function honorHoner(interaction) {
await interaction.reply({
embeds: [embed],
components: [row],
ephemeral: true
flags: MessageFlags.Ephemeral
})
}
async function honerDishonor(interaction) {
const db = mClient.db(process.env.M_DB)
const honorsColl = db.collection('honors')
const honorsColl = db.collection('items_honors')
const target = await interaction.options.getUser('target')
const reason = `[-] ${await interaction.options.getString('reason') ?? 'No reason provided'}`
@@ -69,7 +69,7 @@ async function honerDishonor(interaction) {
await interaction.reply({
embeds: [embed],
components: [row],
ephemeral: true
flags: MessageFlags.Ephemeral
})
}
async function honorLeaderboard(interaction) {
@@ -93,7 +93,7 @@ async function honorLeaderboard(interaction) {
.setCustomId('honors_leaderboard_right')
)
const db = mClient.db(process.env.M_DB)
const honorsColl = db.collection('honors')
const honorsColl = db.collection('items_honors')
let skip = 0
const honorsData = await honorsColl.find({}).sort({ honors: -1 }).skip(skip).limit(5).toArray()
let fields
@@ -103,7 +103,7 @@ async function honorLeaderboard(interaction) {
})
const embed = new EmbedBuilder()
.setTitle('- Honors Leaderboard -')
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152940755539722240/pngwing.com.png')
.setThumbnail(guild.iconURL({ dynamic: true}))
.setDescription(fields.toString())
.setColor('#5865F2') // Discord's blurple color
.setFooter({ text: 'Use ◄ ► to navigate' });
@@ -116,7 +116,7 @@ async function honorHistory(interaction) {
var target = interaction.options.getUser('target')
if (!target) { target = interaction.user }
const db = mClient.db(process.env.M_DB)
const reasonsColl = db.collection('honor-reasons')
const reasonsColl = db.collection('history_honors')
var history = await reasonsColl.findOne({ userID: target.id })
const embed = new EmbedBuilder()
@@ -136,7 +136,7 @@ async function honorCheck(interaction) {
var target = interaction.options.getUser('target')
if (!target) { target = interaction.user }
const db = mClient.db(process.env.M_DB)
const honorsColl = db.collection('honors')
const honorsColl = db.collection('items_honors')
var honors = await honorsColl.findOne({ userID: target.id })
honors = honors?.honors ?? 0
@@ -171,21 +171,24 @@ async function honorMenu(interaction) {
const row = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setLabel('Honor')
.setEmoji(`<:honorhigh:748176295535443968>`)
.setCustomId('honor_menu_honor')
.setStyle(ButtonStyle.Primary)
.setStyle(ButtonStyle.Success)
)
.addComponents(
new ButtonBuilder()
.setLabel('Dishonor')
.setEmoji(`<:honorlow:748176295132790786>`)
.setCustomId('honor_menu_dishonor')
.setStyle(ButtonStyle.Primary)
.setStyle(ButtonStyle.Danger)
)
.addComponents(
new ButtonBuilder()
.setEmoji(``)
.setCustomId('abort')
.setStyle(ButtonStyle.Secondary)
)
.addComponents(
new ButtonBuilder()
.setLabel('History')
.setEmoji('📜')
.setCustomId('honor_menu_history')
.setStyle(ButtonStyle.Secondary)
@@ -201,7 +204,7 @@ async function honorMenu(interaction) {
await interaction.reply({
embeds: [embed],
components: [select, row],
ephemeral: true
flags: MessageFlags.Ephemeral
})
}
module.exports = {
@@ -1,7 +1,11 @@
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js')
const { mClient } = require('../..')
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, MessageFlags, AttachmentBuilder } = require('discord.js')
const { mClient } = require('../../../index')
require('dotenv').config()
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
const asset_path = './assets/Command_Nuts/'
async function nutsGive(interaction) {
async function tradeWindow(buttonID1, buttonID2) {
const embed = new EmbedBuilder()
@@ -14,7 +18,8 @@ async function nutsGive(interaction) {
{ name: `Their Current Balance`, value: `${theirBalance.nuts} (**+${amount}**)`, inline: true },
{ name: `Their New Balance`, value: `${theirBalance.nuts + amount}`, inline: true }
)
.setThumbnail(to.displayAvatarURL())
.setThumbnail('attachment://nuts_main.png')
const row = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
@@ -28,35 +33,42 @@ async function nutsGive(interaction) {
.setCustomId(buttonID2)
.setStyle(ButtonStyle.Danger)
)
await interaction.reply({
embeds: [embed],
components: [row],
ephemeral: true
flags: MessageFlags.Ephemeral
})
}
const from = interaction.user
const to = await interaction.options.getUser('target')
var amount = await interaction.options.getNumber('amount')
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const nutsColl = db.collection('items_nuts')
const yourBalance = await nutsColl.findOne({ userID: from.id })
const theirBalance = await nutsColl.findOne({ userID: to.id })
if (amount <= 0) {
amount = yourBalance.nuts
return tradeWindow('nuts_give_fake', 'abort')
}
if (yourBalance.nuts < amount) {
return await interaction.reply({
content: 'Du kannst nicht mehr geben als du hast!',
ephemeral: true
flags: MessageFlags.Ephemeral
})
}
return tradeWindow('nuts_give_confirm', 'abort')
}
async function nutsCheck(interaction) {
let target = interaction.options.getUser('target')
let addressing
if (!target) {
target = interaction.user
addressing = `Du hast`
@@ -69,7 +81,7 @@ async function nutsCheck(interaction) {
}
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const nutsColl = db.collection('items_nuts')
const nutsData = await nutsColl.findOne({ userID: target.id })
let content
@@ -81,6 +93,7 @@ async function nutsCheck(interaction) {
let title = 'Zähle Nüsse'
const embed = new EmbedBuilder()
for (let i = 0; i < 4; i++) {
embed.setTitle(title)
await interaction.editReply({
@@ -89,14 +102,17 @@ async function nutsCheck(interaction) {
title = title + ' .'
await delay(500);
}
embed
.setTitle(content)
.setThumbnail('https://cdn-icons-png.flaticon.com/512/628/628206.png')
.setThumbnail('attachment://nuts_main.png')
await interaction.editReply({
embeds: [embed]
embeds: [embed],
files: [`${asset_path}nuts_main.png`]
})
}
async function nutsLeaderboard(interaction) {
const row = new ActionRowBuilder()
.addComponents(
@@ -117,88 +133,120 @@ async function nutsLeaderboard(interaction) {
.setStyle(ButtonStyle.Primary)
.setCustomId('nuts_leaderboard_right')
)
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const nutsColl = db.collection('items_nuts')
let skip = 0
const nutsData = await nutsColl.find({ nuts: { $gt: 0 } }).sort({ nuts: -1 }).skip(skip).limit(5).toArray()
let fields
let placements = skip + 1
nutsData.forEach((data) => {
fields = (fields ? fields : '') + (`${placements}. <@${data.userID}> : ${data.nuts} Nuts\r\n`)
placements++
})
const embed = new EmbedBuilder()
.setTitle('Nuts Leaderboard')
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152940755539722240/pngwing.com.png')
.setThumbnail('attachment://nuts_main.png')
.setDescription(fields.toString())
.setColor('#5865F2') // Discord's blurple color
.setFooter({ text: 'Use ◄ ► to navigate' });
.setColor('#5865F2')
.setFooter({ text: 'Use ◄ ► to navigate' })
await interaction.editReply({
embeds: [embed],
components: [row]
components: [row],
files: [`${asset_path}nuts_main.png`]
})
}
async function nutsStats(interaction) {
const db = mClient.db(process.env.M_DB)
const nStatsColl = db.collection('nut-stats')
const stats = await nStatsColl.find({}).sort({ amount: 1 }).toArray()
let nutMin = {
count: 0,
amount: 0
const db = mClient.db(process.env.M_DB);
const nStatsColl = db.collection('stats_nuts');
var type = interaction?.options?.getString('type') || 'lookup'
var target = interaction?.options?.getUser('lookup') || {}
if (type == 'global') {
target.id = '__global'
} else if (!target?.id) {
target = interaction.user
}
let nutMax = {
count: 0,
amount: 0
const statsDoc = await nStatsColl.findOne({ userID: target.id });
const stat = statsDoc?.stat || {};
const totalCount = Object.values(stat).reduce((a, b) => a + b, 0);
const totalNuts = Object.entries(stat).reduce(
(sum, [num, count]) => sum + Number(num) * count,
0
);
const rolledNumbers = Object.entries(stat).filter(([_, count]) => count > 0);
let nutMin = { number: 0, count: 0 };
let nutMax = { number: 0, count: 0 };
if (rolledNumbers.length > 0) {
nutMin = nutMax = { number: Number(rolledNumbers[0][0]), count: rolledNumbers[0][1] };
for (const [numStr, count] of rolledNumbers) {
const num = Number(numStr);
if (count > nutMax.count || (count === nutMax.count && num > nutMax.number)) {
nutMax = { number: num, count };
}
if (count < nutMin.count || (count === nutMin.count && num < nutMin.number)) {
nutMin = { number: num, count };
}
}
}
let totalNuts = 0
let totalCount = 0
stats.forEach(stat => {
totalCount += stat.count
totalNuts += (stat.count * stat.amount)
if (nutMin.count > stat.count) { nutMin = stat }
if (nutMax.count < stat.count) { nutMax = stat }
})
let nutAvg = totalNuts / totalCount
const nutAvg = totalCount ? totalNuts / totalCount : 0;
const fields = Array.from({ length: 11 }, (_, i) => ({
name: `[${i}]`,
value: `x${stat[i] ?? 0}`,
inline: true
}));
const embed = new EmbedBuilder()
.setTitle("Nut Statistic")
.setDescription(
`Total Nut Actions: **${totalCount}**\r\n
Total Nuts nutted: **${totalNuts}**\r\n
Nut Average: **${nutAvg.toFixed(3)}**\r\n
Best Nut: **${nutMax.amount}**\r\n
Worst Nut: **${nutMin.amount}**`
)
.addFields(
{ name: '[0]', value: `x${stats[0].count}`, inline: true },
{ name: '[1]', value: `x${stats[1].count}`, inline: true },
{ name: '[2]', value: `x${stats[2].count}`, inline: true },
{ name: '[3]', value: `x${stats[3].count}`, inline: true },
{ name: '[4]', value: `x${stats[4].count}`, inline: true },
{ name: '[5]', value: `x${stats[5].count}`, inline: true },
{ name: '[6]', value: `x${stats[6].count}`, inline: true },
{ name: '[7]', value: `x${stats[7].count}`, inline: true },
{ name: '[8]', value: `x${stats[8].count}`, inline: true },
{ name: '[9]', value: `x${stats[9].count}`, inline: true }
`Total Nut Actions: **${totalCount}**\r\n` +
`Total Nuts nutted: **${totalNuts}**\r\n` +
`Nut Average: **${nutAvg.toFixed(3)}**\r\n` +
`Most Common Nut: **${nutMax.number} (x${nutMax.count})**\r\n` +
`Least Common Nut: **${nutMin.number} (x${nutMin.count})**`
)
.addFields(fields)
.setColor(0x51267)
.setTimestamp()
.setThumbnail(interaction.guild.iconURL())
.setThumbnail('attachment://nuts_main.png')
await interaction.editReply({
embeds: [embed]
})
embeds: [embed],
files: [`${asset_path}nuts_main.png`]
});
}
async function nutsCooldown(interaction) {
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('cooldown')
const nutsColl = db.collection('items_cooldowns')
const cooldown = await nutsColl.findOne({ userID: interaction.user.id })
let content = `Du kannst wieder nussen! :)`
let thumbnail = 'https://cdn-icons-png.flaticon.com/512/7451/7451659.png'
let thumbnail = 'attachment://nuts_main.png'
let file = `${asset_path}nuts_main.png`
let title = 'Go Nuts!'
let date = (Date.now() / 1000)
if (cooldown.cooldown > date) {
content = `<t:${cooldown.cooldown}:R> kannst du wieder nussen! ;)`
thumbnail = 'https://cdn.discordapp.com/attachments/1152723542836772914/1152987472788193361/No-nuts-PhotoRoom.png-PhotoRoom.png'
thumbnail = 'attachment://nuts_onCD.avif'
file = `${asset_path}nuts_onCD.avif`
title = 'To Nut or Not to Nut...'
}
@@ -208,85 +256,112 @@ async function nutsCooldown(interaction) {
.setDescription(content)
await interaction.editReply({
embeds: [embed]
embeds: [embed],
files: [file]
})
}
async function nutsNut(interaction) {
async function nutsNut(interaction, quickMode) {
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const cdColl = db.collection('cooldown')
const nutsColl = db.collection('items_nuts')
const cdColl = db.collection('items_cooldowns')
const nutsStatsColl = db.collection('stats_nuts')
const cdData = await cdColl.findOne({ userID: interaction.user.id })
const embed = new EmbedBuilder()
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152991361113538621/png-transparent-subscription-box-label-bag-mysterious-miscellaneous-purple-blue-thumbnail-PhotoRoom.png-PhotoRoom.png')
let content
const images = {
"high": "https://as2.ftcdn.net/v2/jpg/02/24/65/39/1000_F_224653943_r3xltiwJsK6am0mGZE5DTWk1yocUwHLd.jpg",
"normal": 'https://c8.alamy.com/comp/PPPBXK/surprised-pecan-nuts-pile-on-plate-cartoon-PPPBXK.jpg',
"low": 'https://as2.ftcdn.net/v2/jpg/02/24/65/37/1000_F_224653769_ceJk0tq9UT1hSu5FIVUi7BeaN4ucSZGv.jpg',
"none": 'https://cdn4.vectorstock.com/i/1000x1000/87/08/afraid-pecan-nuts-pile-on-plate-cartoon-vector-22028708.jpg',
"onCD": 'https://cdn.discordapp.com/attachments/1152723542836772914/1152987472788193361/No-nuts-PhotoRoom.png-PhotoRoom.png'
const assets = {
high: 'attachment://nuts_high.jpg',
normal: 'attachment://nuts_normal.jpg',
low: 'attachment://nuts_low.jpg',
none: 'attachment://nuts_none.avif',
onCD: 'attachment://nuts_onCD.avif',
box: 'attachment://nuts_box.png',
explosion: 'attachment://nuts_explosion.gif'
}
let image
if (!cdData || cdData.cooldown < (Date.now() / 1000)) {
let cd = Math.floor((Date.now() + 3600000) / 1000)
await cdColl.findOneAndUpdate({
userID: interaction.user.id
}, {
$set: { cooldown: cd }
}, {
upsert: true
// Helper for singular/plural
const formatNut = (amount) => `${amount} ${amount === 1 ? 'Nuss' : 'Nüsse'}`
// check cooldown
if (cdData?.cooldown > Date.now() / 1000) {
// on cooldown
embed.setTitle('To Nut or Not to Nut...')
embed.setDescription(`<t:${Math.floor(cdData.cooldown)}:R> kannst du wieder nussen! ;)`)
embed.setThumbnail(assets.onCD)
return interaction.editReply({
embeds: [embed],
files: [`${asset_path}nuts_onCD.avif`]
})
const amount = Math.floor(Math.random() * 10)
await nutsColl.findOneAndUpdate({
userID: interaction.user.id
}, {
$inc: { nuts: amount }
}, {
upsert: true
})
if (amount) {
content = `Du hast **${amount}** Nüsse bekommen!`
if (amount > 8) {
image = images["high"]
} else if (amount > 4) {
image = images["normal"]
} else {
image = images["low"]
}
} else {
content = `Du hast leider keine Nüsse bekommen :(`
image = images["none"]
}
// set 1 hour cooldown
const cd = Math.floor((Date.now() + 3600000) / 1000)
await cdColl.findOneAndUpdate({
userID: interaction.user.id
}, {
$set: {
cooldown: cd,
application: 'nuts'
}
} else {
content = `Du kannst erst <t:${Math.floor(cdData?.cooldown)}:R> wieder nussen :(`
image = images["onCD"]
await delay(1000)
embed.setDescription(content)
embed.setThumbnail(image)
return await interaction.editReply({
embeds: [embed]
})
}, {
upsert: true
})
// generate nut amount
const amount = Math.floor(Math.random() * 10)
// update nuts and stats
await nutsColl.findOneAndUpdate(
{ userID: interaction.user.id },
{ $inc: { nuts: amount } },
{ upsert: true }
)
await nutsStatsColl.findOneAndUpdate(
{ userID: interaction.user.id },
{ $inc: { [`stat.${amount}`]: 1 } },
{ upsert: true }
)
await nutsStatsColl.findOneAndUpdate(
{ userID: "__global" },
{ $inc: { [`stat.${amount}`]: 1 } },
{ upsert: true }
)
if (quickMode) {
return interaction.editReply({ content: `Du hast ${formatNut(amount)} bekommen! :chestnut:` })
}
// pseudo animation
embed.setImage(assets.box)
await interaction.editReply({
embeds: [embed]
embeds: [embed],
files: [`${asset_path}nuts_box.png`]
})
await delay(1000)
embed.setThumbnail('https://i.pinimg.com/originals/9d/58/37/9d5837c6f0cb8b18be6ddd1e2742472a.gif')
await delay(1337)
embed.setImage(assets.explosion)
await interaction.editReply({
embeds: [embed]
embeds: [embed],
files: [`${asset_path}nuts_explosion.gif`]
})
await delay(1337)
await delay(1000)
embed.setDescription(content)
embed.setThumbnail(image)
await interaction.editReply({
embeds: [embed]
let assetFile
if (amount === 0) assetFile = assets.none
else if (amount > 8) assetFile = assets.high
else if (amount > 4) assetFile = assets.normal
else assetFile = assets.low
embed.setTitle(`Du hast ${formatNut(amount)} bekommen!`)
embed.setThumbnail(assetFile)
embed.setImage(null)
return interaction.editReply({
embeds: [embed],
files: [`${asset_path}${assetFile.split('://')[1]}`]
})
@@ -313,7 +388,20 @@ module.exports = {
.addSubcommand(s =>
s
.setName('stats')
.setDescription('wie viele Nüsse wurden genusst, Genosse?'))
.setDescription('wie viele Nüsse wurden genusst, Genosse?')
.addStringOption(o =>
o.setName('type')
.setDescription('set type to global or user')
.addChoices(
{ name: 'global', value: 'global' },
{ name: 'user', value: 'user' }
),)
.addUserOption(o =>
o.setName('lookup')
.setDescription('look up specific user nut statistic')
)
)
.addSubcommand(s =>
s
.setName('cooldown')
@@ -321,7 +409,12 @@ module.exports = {
.addSubcommand(s =>
s
.setName('nut')
.setDescription('willst du nuss?')),
.setDescription('willst du nuss?'))
.addSubcommand(s =>
s.setName('quick')
.setDescription('A quick nut, mlord?')
),
async execute(interaction) {
switch (interaction.options._subcommand) {
case 'give':
@@ -345,7 +438,11 @@ module.exports = {
break;
case 'nut':
await interaction.deferReply()
nutsNut(interaction)
nutsNut(interaction, false)
break;
case 'quick':
await interaction.deferReply()
nutsNut(interaction, true)
break;
default:
break;
@@ -2,12 +2,13 @@
Random By Year?
Counter (Leaderboard)
*/
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, UserSelectMenuBuilder } = require('discord.js')
const { mClient } = require('../..')
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, UserSelectMenuBuilder, MessageFlags } = require('discord.js')
const { mClient } = require('../../../index')
require('dotenv').config()
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
async function quotesAdd(interaction) {
const messageLink = await interaction.options.getString('link')
//regex for message link
const regex = /^https:\/\/discord\.com\/channels\/\d+\/\d+\/\d+$/
@@ -15,7 +16,7 @@ async function quotesAdd(interaction) {
if (!messageLink.match(regex)) {
return await interaction.editReply({
content: `Invalid URL`,
ephemeral: true
flags: MessageFlags.Ephemeral
})
}
@@ -48,15 +49,15 @@ async function quotesAdd(interaction) {
}
const db = mClient.db(process.env.M_DB)
const quotesColl = db.collection('quotes')
const quotesColl = db.collection('items_quotes')
const found = await quotesColl.findOne({ messageID: messageID })
if (found) { return await interaction.editReply({ content: 'Quote Already in Database', ephemeral: true }) }
if (found) { return await interaction.editReply({ content: 'Quote Already in Database', flags: MessageFlags.Ephemeral }) }
await quotesColl.findOneAndUpdate({ messageID: messageID }, {
$set: {
messageID: messageID,
channelID: channelID,
guildID: guildID,
by: msgData.author.id,
userID: msgData.author.id,
count: 0
}
}, { upsert: true })
@@ -87,20 +88,20 @@ async function quotesRemove(interaction) {
const id = await interaction.options.getString('id')
const db = mClient.db(process.env.M_DB)
const quotesColl = db.collection('quotes')
const quotesColl = db.collection('items_quotes')
const found = await quotesColl.findOne({ messageID: id })
if (!found) { return await interaction.reply({ content: 'ID not found!', ephemeral: true }) }
if (!found) { return await interaction.reply({ content: 'ID not found!', flags: MessageFlags.Ephemeral }) }
await quotesColl.deleteOne({ messageID: id })
return interaction.reply({ content: 'Quote successfully removed!', ephemeral: true })
return interaction.reply({ content: 'Quote successfully removed!', flags: MessageFlags.Ephemeral })
}
async function quotesSearch(interaction) {
const id = interaction.options.getString("id")
const db = mClient.db(process.env.M_DB)
const quotesColl = db.collection('quotes')
const quotesColl = db.collection('items_quotes')
const found = await quotesColl.findOne({ messageID: id })
if (!found) { return await interaction.reply({ content: 'ID not found!', ephemeral: true }) }
if (!found) { return await interaction.reply({ content: 'ID not found!', flags: MessageFlags.Ephemeral }) }
const guild = await interaction.client.guilds.fetch(found.guildID)
@@ -158,12 +159,12 @@ async function quotesSearch(interaction) {
async function quotesRandom(interaction) {
var user = interaction.options.getUser("by")
const db = mClient.db(process.env.M_DB)
const quotesColl = db.collection('quotes')
const quotesColl = db.collection('items_quotes')
var rdm
if (user) {
rdm = await quotesColl.aggregate([
{
$match: { by: user.id },
$match: { userID: user.id },
}, {
$sample: { size: 1 }
}
@@ -176,7 +177,7 @@ async function quotesRandom(interaction) {
]).toArray()
}
const found = rdm[0]
if (!found) { return await interaction.reply({ content: 'Database Empty', ephemeral: true }) }
if (!found) { return await interaction.reply({ content: 'No Entry Found.', flags: MessageFlags.Ephemeral }) }
const guild = await interaction.client.guilds.fetch(found.guildID)
const channel = await guild.channels.fetch(found.channelID)
const message = await channel.messages.fetch(found.messageID)
@@ -263,75 +264,91 @@ async function quotesList(interaction) {
await interaction.reply({
embeds: [embed],
components: [select, row],
ephemeral: true
flags: MessageFlags.Ephemeral
})
}
async function quotesLeaderboard(interaction) {
const db = mClient.db(process.env.M_DB)
const quotesColl = db.collection('quotes')
let skip = 0
const minValue = 0
const maxValue = await quotesColl.countDocuments({ $and: [{ guildID: interaction.guild.id }, { count: { $gt: 0 } }] })
async function quotesLeaderboard(interaction, page = 1, limit = 5) {
const db = mClient.db(process.env.M_DB);
const quotesColl = db.collection('items_quotes');
const quotesData = await quotesColl.find({}).sort({ count: -1, messageID: -1 }).skip(skip).limit(5).toArray()
const fields = []
// Total quotes in the guild
const totalQuotes = await quotesColl.countDocuments({ guildID: interaction.guild.id, count: { $gte: 0 } });
const totalPages = Math.ceil(totalQuotes / limit);
const guild = await interaction.client.guilds.fetch(interaction.guild.id)
quotesData.forEach(async (data, index) => {
// Clamp page
if (page < 1) page = 1;
if (page > totalPages) page = totalPages;
let channel = await guild.channels.fetch(data.channelID)
let message = await channel.messages.fetch(data.messageID)
const skip = (page - 1) * limit;
await delay(500)
let timestamp = new Date(message.createdTimestamp)
fields.push({
name: `${index + 1}.`,//`\u200b` ,
value: `[#${data.messageID}](https://discord.com/channels/${data.guildID}/${data.channelID}/${data.messageID})\r\n**by** <@${data.by}> • ⭐ ${data.count}\r\n_Posted on **${timestamp}**_\r\n${message.content}`
// Fetch quotes for this page
const quotesData = await quotesColl
.find({ guildID: interaction.guild.id, count: { $gte: 0 } })
.sort({ count: -1, messageID: -1 })
.skip(skip)
.limit(limit)
.toArray();
// Fallback if no quotes exist
if (!quotesData.length) {
return interaction.editReply({ content: 'No quotes found for this server yet!', components: [] });
}
const guild = await interaction.client.guilds.fetch(interaction.guild.id);
// Fetch all messages concurrently
const fields = await Promise.all(
quotesData.map(async (data, index) => {
try {
const channel = await guild.channels.fetch(data.channelID);
const message = await channel.messages.fetch(data.messageID);
const timestamp = new Date(message.createdTimestamp).toLocaleString('en-US', {
dateStyle: 'medium',
timeStyle: 'short'
});
return {
name: `${skip + index + 1}.`,
value: `[#${data.messageID}](https://discord.com/channels/${data.guildID}/${data.channelID}/${data.messageID})\n**by** <@${data.userID}> • ⭐ ${data.count}\n_Posted on **${timestamp}**_\n${message.content}`
};
} catch {
return {
name: `${skip + index + 1}.`,
value: 'Message unavailable.'
};
}
})
);
})
await delay(5000)
console.log(fields)
quotesData.sort((a,b) => {
const numA = parseInt(a.name);
const numB = parseInt(b.name);
return numA - numB;
})
console.log(fields)
// Build embed
const embed = new EmbedBuilder()
.setTitle('- Quotes Leaderboard -')
.setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152940755539722240/pngwing.com.png')
.setThumbnail(guild.iconURL({ dynamic: true }))
.setFields(fields)
.setColor('#5865F2') // Discord's blurple color
.setFooter({ text: `Use ◄ ► to navigate\r\n${skip}` });
.setColor('#5865F2')
.setFooter({ text: `Use ◄ ► to navigate • Page ${page} of ${totalPages}` });
// Build buttons
const row = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setLabel('◄')
.setStyle(ButtonStyle.Primary)
.setCustomId('quotes_leaderboard_left')
)
.addComponents(
.setDisabled(page === 1),
new ButtonBuilder()
.setLabel('X')
.setStyle(ButtonStyle.Danger)
.setCustomId('abort')
)
.addComponents(
.setCustomId('abort'),
new ButtonBuilder()
.setLabel('►')
.setStyle(ButtonStyle.Primary)
.setCustomId('quotes_leaderboard_right')
)
await interaction.editReply({
embeds: [embed],
components: [row]
})
.setDisabled(page === totalPages)
);
await interaction.editReply({ embeds: [embed], components: [row] });
}
module.exports = {
@@ -341,7 +358,7 @@ module.exports = {
.addSubcommand(s =>
s
.setName('add')
.setDescription('add a new quote')
.setDescription('add a new quote either by replying to a message or inserting the message link')
.addStringOption(o => o.setName('link').setDescription('insert message link').setRequired(true)))
.addSubcommand(s =>
s
@@ -392,4 +409,6 @@ module.exports = {
break;
}
}
}
},
module.exports.quotesLeaderboard = quotesLeaderboard
+48
View File
@@ -0,0 +1,48 @@
const { SlashCommandBuilder } = require("discord.js");
function askMyBalls() {
var answers = [
'Absolut, so wie die Authorität unserer Göttin!',
'Unterschätze es nicht, genauso wie Roberts sexual frustration',
'Ich zedaz so',
'Ohne Zweifel',
'Definitiv, Alter',
'Microsoft Outlook gut',
'Das Sternzeichen von Yeesh leuchtet heute stark dafür',
'Mit "Support-Desk am Freitagabend" - Wahrscheinlichkeit',
'Ist die Nase von Julius wunderschön und lang?',
'So wahr wie Laviis Zeichnkünste',
'nein...ja... vielleicht?',
'Frag mich nachher nochmal',
'Die Kalkulationen sind leicht off, ich aber nicht ;)',
'Ich sag es dir ein ander Mal',
'Ohne schwere Zeiten, würden wir die guten Zeiten nie schätzen',
'Genauso schlecht wie eine Ketzerei gegen den Olymp',
'Hat der Fuchs uns jemals verraten?...**hust**',
'Mein Outlook ist abgeschmiert, mist',
'Ich bezweifle es. A propos, zweifel nicht an den Götter und ihren Priester!',
'Meine Quellen sagen.... WARNUNG! Artikel 17: Die betroffene Person hat das Recht, von dem Verantwortlichen zu verlangen, dass sie betreffende personenbezogene Daten unverzüglich gelöscht werden, und der Verantwortliche ist verpflichtet, personenbezogene Daten unverzüglich zu löschen, sofern einer der folgenden Gründe zutrifft **ERROR ERROR ERROR**?'
]
const r = Math.floor(Math.random() * answers.length)
return answers[r]
}
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
module.exports = {
data: new SlashCommandBuilder()
.setName('8ball')
.setDescription('dont ask me anything')
.addSubcommand(s =>
s.setName('ask')
.setDescription('what do you want to know?')
.addStringOption(
o => o.setName('question').setDescription('ask away!').setRequired(true))
),
async execute(interaction) {
await interaction.deferReply()
await delay(2000)
await interaction.editReply(askMyBalls())
}
}
+83
View File
@@ -0,0 +1,83 @@
const { SlashCommandBuilder, EmbedBuilder, AttachmentBuilder } = require("discord.js");
async function doggoPet(interaction) {
const responses = [
'*loving growl*',
'Danke, das habe ich gebraucht.',
'Ein bisschen tiefer.',
'Ja, genau dort!'
]
var r = Math.floor(Math.random() * responses.length)
const filePath = `assets/Command_Doggo/doggo.jpg`;
const attachment = new AttachmentBuilder(filePath);
const embed = new EmbedBuilder()
.setDescription(responses[r])
.setColor(0x51267)
.setTimestamp()
.setImage(`attachment://doggo.jpg`);
await interaction.editReply({
embeds: [embed],
files: [attachment]
})
}
async function doggoFeed(interaction) {
await interaction.editReply({
content: 'WIP placeholder'
})
}
async function doggoWalk(interaction) {
await interaction.editReply({
content: 'WIP placeholder'
})
}
async function doggoPlay(interaction) {
await interaction.editReply({
content: 'WIP placeholder'
})
}
module.exports = {
data: new SlashCommandBuilder()
.setName('doggo')
.setDescription('who is a good boi?')
.addSubcommand(s =>
s.setName('pet')
.setDescription('beeg scratch')
)
.addSubcommand(s =>
s.setName('feed')
.setDescription('tastge')
)
.addSubcommand(s =>
s.setName('walk')
.setDescription('walkies')
)
.addSubcommand(s =>
s.setName('play')
.setDescription('fun time')
),
async execute(interaction) {
await interaction.deferReply()
switch (interaction.options._subcommand) {
case 'pet':
doggoPet(interaction)
break;
case 'feed':
doggoFeed(interaction)
break;
case 'walk':
doggoWalk(interaction)
break;
case 'play':
doggoPlay(interaction)
break;
default:
break;
}
}
}
+72
View File
@@ -0,0 +1,72 @@
const { SlashCommandBuilder, AttachmentBuilder, EmbedBuilder } = require('discord.js');
const fs = require('fs/promises');
const path = require('path');
async function makeDay() {
const date = new Date();
const tage = [
'sonntag',
'montag',
'dienstag',
'mittwoch',
'donnerstag',
'freitag',
'samstag'
];
const text = {
montag: 'Es ist Montag meine Münmler!',
mittwoch: 'Es ist Mittwoch meine Kerle!',
donnerstag: 'Es ist nicht mehr Mittwoch meine Kerle!',
freitag: 'Es ist Freitag meine Kerl*innen!',
default: 'Es ist nicht Mittwoch, meine Kerle...'
};
const today = tage[date.getDay()];
let files;
try {
files = await fs.readdir('assets/Command_Mittwoch');
} catch (err) {
console.error(err);
return { filename: 'nicht_mittwoch', content: text.default };
}
const available = files.map(f => path.parse(f).name);
if (available.includes(today)) {
return {
filename: today,
content: text[today] || text.default
};
}
return {
filename: 'nicht_mittwoch',
content: text.default
};
}
module.exports = {
data: new SlashCommandBuilder()
.setName('mittwoch')
.setDescription('mittwoch vibes'),
async execute(interaction) {
const { filename, content } = await makeDay();
const filePath = `assets/Command_Mittwoch/${filename}.jpg`;
const attachment = new AttachmentBuilder(filePath);
const embed = new EmbedBuilder()
.setTitle(content)
.setColor(0x51267)
.setTimestamp()
.setImage(`attachment://${filename}.jpg`);
await interaction.reply({
embeds: [embed],
files: [attachment]
});
}
};
+12 -10
View File
@@ -8,11 +8,11 @@ module.exports = {
once: false,
async execute(member, client) {
console.log(`${member.user.username} hat Geburtstag!`)
let found = null
const db = mClient.db(process.env.DB)
const channelsColl = db.collection('channels')
const found = await channelsColl.find(
const db = mClient.db(process.env.M_DB)
const channelsColl = db.collection('config_channels')
found = await channelsColl.find(
{
$and: [
{ guildID: member.guild.id },
@@ -25,12 +25,13 @@ module.exports = {
return console.log('Channel not yet set for birthday!')
}
const guild = client.guilds.cache.get(found[0].guildID);
const channel = guild.channels.cache.get(found[0].channelID);
const roleColl = db.collection('config_roles')
const roleID = '702877228857557002'
const role = guild.roles.cache.get(roleID)
// Bot Role MUST BE above birthday Role, Birthday Role MUST BE above user roles
found = await roleColl.findOne({guildID: member.guild.id})
const role = guild.roles.cache.get(found.roleID)
try {
await member.roles.add(role)
@@ -45,7 +46,7 @@ module.exports = {
// Draw Initial Image
const background = await loadImage(
path.join(__dirname, '../assets/bdbanner.png')
path.join(__dirname, '../assets/Event_Birthday/bdbanner.png')
);
let x = 0;
let y = 0;
@@ -79,8 +80,9 @@ module.exports = {
ctx.strokeText(text, textX, 60 + pfp.height);
ctx.fillText(text, textX, 60 + pfp.height);
ctx.font = '30px sans-serif';
text = `🥳 ${member.user.globalName ? member.user.globalName : member.user.username} 🎉`;
// requires apt-get install ttf-ancient-fonts
ctx.font = '30px "Noto Emoji", "Segoe UI Emoji", "Apple Color Emoji", sans-serif';
text = `🎉 ${member.user.globalName ? member.user.globalName : member.user.username} 🎉`;
textWidth = ctx.measureText(text).width;
textX = canvas.width / 2 - textWidth / 2;
textHeight = 30; // Approximate height of the text
+51 -31
View File
@@ -5,7 +5,9 @@ module.exports = {
name: Events.ClientReady,
once: true,
async execute(client) {
console.log(`Ready! Logged in as ${client.user.tag}`)
console.log(`Ready! Logged in as ${client.user.tag}`);
// Set presence
client.user.setPresence({
activities: [{
name: 'Red Dead Depression',
@@ -13,40 +15,58 @@ module.exports = {
url: 'https://twitch.tv/desq_blocki'
}],
status: 'online'
})
});
// if today is birthday
function isToday(day, month) {
const currentYear = new Date().getFullYear();
const inputDate = new Date(currentYear, month - 1, day);
// Check if a date matches today
const isToday = (day, month) => {
const today = new Date();
return (
inputDate.getDate() === today.getDate() &&
inputDate.getMonth() === today.getMonth() &&
inputDate.getFullYear() === today.getFullYear()
);
}
async function isBirthday() {
const db = mClient.db(process.env.M_DB)
const bdayColl = db.collection('birthdays')
const allBirthdays = await bdayColl.find().toArray()
for (let index = 0; index < allBirthdays.length; index++) {
if (isToday(allBirthdays[index].day, allBirthdays[index].month)) {
let guild = client.guilds.cache.get(process.env.D_GuildID)
let member = guild.members.cache.get(allBirthdays[index].userID)
client.emit('Birthday', member)
return today.getDate() === day && today.getMonth() === month - 1;
};
// Handle birthdays
const handleBirthdays = async () => {
const guild = await client.guilds.fetch(process.env.D_GuildID);
const db = mClient.db(process.env.M_DB);
const bdayColl = db.collection('items_birthdays');
const allBirthdays = await bdayColl.find().toArray();
const bdayMap = new Map(allBirthdays.map(b => [b.userID, b]));
// Fetch birthday role
const bdayRoleColl = db.collection('config_roles');
const bdayRoleEntry = await bdayRoleColl.findOne({ guildID: guild.id });
const birthdayRoleID = bdayRoleEntry?.roleID;
if (!birthdayRoleID) {
console.warn("No birthday role configured in DB");
return;
}
// Fetch all guild members
const members = await guild.members.fetch();
for (const member of members.values()) {
const dbEntry = bdayMap.get(member.id);
if (dbEntry && isToday(dbEntry.day, dbEntry.month)) {
// Today is their birthday
await member.roles.add(birthdayRoleID).catch(err =>
console.error(`Failed to add birthday role to ${member.user.tag}:`, err)
);
console.log(`Added birthday role to ${member.user.tag}`);
//client.emit('Birthday', member);
} else {
// remove any residual birthday roles
try {
let guild = client.guilds.cache.get(process.env.D_GuildID)
let member = guild.members.cache.get(allBirthdays[index].userID)
await member.roles.remove('702877228857557002')
} catch (error) {
console.error('Could not remove role', error)
// Default fallback: remove birthday role if present
if (member.roles.cache.has(birthdayRoleID)) {
await member.roles.remove(birthdayRoleID).catch(err =>
console.error(`Failed to remove birthday role from ${member.user.tag}:`, err)
);
console.log(`Removed birthday role from ${member.user.tag} (not today or not in DB)`);
}
}
}
}
isBirthday()
};
await handleBirthdays();
}
}
};
+4 -3
View File
@@ -9,8 +9,8 @@ module.exports = {
once: false,
async execute(member, client) {
console.log(`${member.user.username} joined the Server`);
const db = mClient.db(process.env.DB)
const channelsColl = db.collection('channels')
const db = mClient.db(process.env.M_DB)
const channelsColl = db.collection('config_channels')
const found = await channelsColl.find(
{
$and: [
@@ -36,7 +36,7 @@ module.exports = {
// Draw Initial Image
const background = await loadImage(
path.join(__dirname, '../assets/background.png')
path.join(__dirname, '../assets/Event_MemberJoin/background.png')
);
let x = 0;
let y = 0;
@@ -79,6 +79,7 @@ module.exports = {
// Draw the second line of text with black outline
ctx.strokeText(text, textX, 100 + pfp.height);
ctx.fillText(text, textX, 100 + pfp.height);
const banner = canvas.toBuffer();
channel.send({
content: `Bitte guck einmal in die <#455023824791011338> ${member}`,
+7 -7
View File
@@ -1,4 +1,4 @@
const { Events } = require('discord.js')
const { Events, MessageFlags } = require('discord.js')
module.exports = {
name: Events.InteractionCreate,
@@ -22,9 +22,9 @@ async function commandHandler(interaction) {
} catch (error) {
console.error(error);
if (interaction.replied || interaction.deferred) {
await interaction.followUp({ content: 'There was an error while executing this command!', ephemeral: true });
await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral });
} else {
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral });
}
}
}
@@ -36,9 +36,9 @@ async function buttonHandler(interaction) {
} catch (error) {
console.error(error);
if (interaction.replied || interaction.deferred) {
await interaction.followUp({ content: 'There was an error while executing this command!', ephemeral: true });
await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral });
} else {
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral });
}
}
}
@@ -50,9 +50,9 @@ async function selectMenuHandler(interaction) {
} catch (error) {
console.error(error);
if (interaction.replied || interaction.deferred) {
await interaction.followUp({ content: 'There was an error while executing this command!', ephemeral: true });
await interaction.followUp({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral });
} else {
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
await interaction.reply({ content: 'There was an error while executing this command!', flags: MessageFlags.Ephemeral });
}
}
}
+28
View File
@@ -0,0 +1,28 @@
const fs = require('node:fs')
const path = require('node:path')
module.exports = (client) => {
const legacyFoldersPath = path.join(__dirname, '../commands/legacy');
const legacyCommandFolders = fs.readdirSync(legacyFoldersPath);
let legacyCount = 0
let aliasCount = 0
for (const folder of legacyCommandFolders) {
const commandsPath = path.join(legacyFoldersPath, folder);
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
legacyCount++
const filePath = path.join(commandsPath, file);
const command = require(filePath);
if ('execute' in command) {
client.legacyCommands.set(command.name, command);
}
if (command.aliases && Array.isArray(command.aliases)) {
command.aliases.forEach(alias => {
aliasCount++
client.aliases.set(alias, command.name)
})
}
}
}
console.log(`[${aliasCount}] Aliase(s) initialized`)
console.log(`[${legacyCount}] Legacy Command(s) initialized`)
}
@@ -5,7 +5,7 @@ const path = require('node:path')
module.exports = (client) => {
let commands = [] // only used for REST API
const foldersPath = path.join(__dirname, '../commands');
const foldersPath = path.join(__dirname, '../commands/slash');
const commandFolders = fs.readdirSync(foldersPath);
for (const folder of commandFolders) {
// Grab all the command files from the commands directory you created earlier
-29
View File
@@ -1,29 +0,0 @@
const fs = require('node:fs')
const path = require('node:path')
module.exports = (client) => {
// const legacyFoldersPath = path.join(__dirname, '../legacyCommands');
// const legacyCommandFolders = fs.readdirSync(legacyFoldersPath);
// let legacyCount = 0
// let aliasCount = 0
// for (const folder of legacyCommandFolders) {
// const commandsPath = path.join(legacyFoldersPath, folder);
// const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
// for (const file of commandFiles) {
// legacyCount++
// const filePath = path.join(commandsPath, file);
// const command = require(filePath);
// if ('execute' in command) {
// client.legacyCommands.set(command.name, command);
// }
// if (command.aliases && Array.isArray(command.aliases)) {
// command.aliases.forEach(alias => {
// aliasCount++
// client.aliases.set(alias, command.name)
// })
// }
// }
// }
// console.log(`[${aliasCount}] Aliase(s) initialized`)
// console.log(`[${legacyCount}] Legacy Command(s) initialized`)
}
-47
View File
@@ -1,47 +0,0 @@
const { mClient } = require('../../index')
require('dotenv').config()
module.exports = {
name: 'nuts',
description: 'get nuts',
aliases: ['n', 'nget', 'nutsget'],
async execute(message, args) {
const db = mClient.db(process.env.M_DB)
const nutsColl = db.collection('nuts')
const cdColl = db.collection('cooldown')
const cdData = await cdColl.findOne({ userID: message.author.id })
if (!cdData || cdData.cooldown < Date.now() / 1000) {
let cd = Math.floor((Date.now() + 3600000) / 1000)
await cdColl.findOneAndUpdate({
userID: message.author.id
}, {
$set: { cooldown: cd }
}, {
upsert: true
})
const amount = Math.floor(Math.random() * 10)
await nutsColl.findOneAndUpdate({
userID: message.author.id
}, {
$inc: { nuts: amount }
}, {
upsert: true
})
let content = `Du hast ${amount} Nüsse bekommen! :chestnut:`
if (!amount) {
content = `Du hast leider keine Nüsse bekommen :(`
}
return await message.reply({
content: content
})
} else {
return await message.reply({
content: `Du kannst erst <t:${Math.floor(cdData?.cooldown / 1000)}:R> wieder nussen :(`,
})
}
},
};
-58
View File
@@ -1,58 +0,0 @@
const { EmbedBuilder } = require('discord.js')
const { mClient } = require('../../index')
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
require('dotenv').config()
module.exports = {
name: 'nutsstats',
description: 'shows nuts statistic',
aliases: ['nstat', 'ns'],
async execute(message, args) {
const db = mClient.db(process.env.M_DB)
const nStatsColl = db.collection('nut-stats')
const stats = await nStatsColl.find({}).sort({ amount: 1 }).toArray()
let nutMin = {
count: 0,
amount: 0
}
let nutMax = {
count: 0,
amount: 0
}
let totalNuts = 0
let totalCount = 0
stats.forEach(stat => {
totalCount += stat.count
totalNuts += (stat.count * stat.amount)
if (nutMin.count > stat.count) { nutMin = stat }
if (nutMax.count < stat.count) { nutMax = stat }
})
let nutAvg = totalNuts / totalCount
const embed = new EmbedBuilder()
.setTitle("Nut Statistic")
.setDescription(
`Total Nut Actions: **${totalCount}**\r\n
Total Nuts nutted: **${totalNuts}**\r\n
Nut Average: **${nutAvg.toFixed(3)}**\r\n
Best Nut: **${nutMax.amount}**\r\n
Worst Nut: **${nutMin.amount}**`
)
.addFields(
{ name: '[0]', value: `x${stats[0].count}`, inline: true },
{ name: '[1]', value: `x${stats[1].count}`, inline: true },
{ name: '[2]', value: `x${stats[2].count}`, inline: true },
{ name: '[3]', value: `x${stats[3].count}`, inline: true },
{ name: '[4]', value: `x${stats[4].count}`, inline: true },
{ name: '[5]', value: `x${stats[5].count}`, inline: true },
{ name: '[6]', value: `x${stats[6].count}`, inline: true },
{ name: '[7]', value: `x${stats[7].count}`, inline: true },
{ name: '[8]', value: `x${stats[8].count}`, inline: true },
{ name: '[9]', value: `x${stats[9].count}`, inline: true }
)
.setColor(0x51267)
.setTimestamp()
.setThumbnail(message.guild.iconURL())
await message.reply({
embeds: [embed]
})
}
}
-8
View File
@@ -1,8 +0,0 @@
module.exports = {
name: 'ping',
description: 'returns pong!',
aliases: [''],
async execute(message, args) {
message.reply('pong!')
}
}
+1 -1
View File
@@ -15,7 +15,7 @@ module.exports = {
} else {
var target = await interaction.guild.members.fetch(interaction.members.keys().next().value)
var db = mClient.db(process.env.M_DB)
var honorsColl = db.collection('honors')
var honorsColl = db.collection('items_honors')
var theirHonorLevel = await honorsColl.findOne({ userID: target.id })
const member = interaction.message.guild.members.cache.get(target.user.id)
@@ -15,8 +15,8 @@ module.exports = {
} else {
const target = await interaction.guild.members.fetch(interaction.members.keys().next().value)
const db = mClient.db(process.env.M_DB)
const quotesColl = db.collection('quotes')
const quotes = await quotesColl.find({ by: target.id }).toArray()
const quotesColl = db.collection('items_quotes')
const quotes = await quotesColl.find({ userID: target.id }).toArray()
const member = interaction.message.guild.members.cache.get(target.user.id)
const memberRoles = member.roles.cache
.filter((roles) => roles.id !== interaction.message.guild.id)
+9
View File
@@ -0,0 +1,9 @@
module.exports =
function ping(interface, args, type){
if (type = 'legacy'){
// type = legacy
interface.reply('pang!')
} else {
interface.reply('pong!')
}
}