Compare commits

..

No commits in common. "30f3a97cc3ba402aa967c420c549113beb19f7ea" and "4bd3e83add143870eaad9140a6e0db1e89916d7e" have entirely different histories.

21 changed files with 214 additions and 228 deletions

View File

@ -4,7 +4,7 @@ import {
SlashCommandBuilder, SlashCommandBuilder,
ChatInputCommandInteraction ChatInputCommandInteraction
} from 'discord.js'; } from 'discord.js';
import { Guilds, VoiceChannels } from '../../../database.js'; import { Guild, VoiceChannel } from '../../../database.js';
export const data = new SlashCommandBuilder() export const data = new SlashCommandBuilder()
.setName('custom_vc') .setName('custom_vc')
@ -68,12 +68,12 @@ export async function execute(interaction) {
step = 'save'; step = 'save';
// Create guild if not exists // Create guild if not exists
await Guilds.findOrCreate({ await Guild.findOrCreate({
where: guildData, where: guildData,
defaults: guildData defaults: guildData
}); });
// Save channel data // Save channel data
await VoiceChannels.create({ await VoiceChannel.create({
id: channel.id, id: channel.id,
guild: guild.id, guild: guild.id,
create: true create: true
@ -94,12 +94,12 @@ export async function execute(interaction) {
step = 'save'; step = 'save';
// Create guild if not exists // Create guild if not exists
await Guilds.findOrCreate({ await Guild.findOrCreate({
where: guildData, where: guildData,
defaults: guildData defaults: guildData
}); });
// Save channel data // Save channel data
await VoiceChannels.create({ await VoiceChannel.create({
id, id,
guild: guild.id, guild: guild.id,
create: true create: true
@ -120,7 +120,7 @@ export async function execute(interaction) {
// Remove channel from guild // Remove channel from guild
step = 'remove'; step = 'remove';
const count = await VoiceChannels.destroy({ const count = await VoiceChannel.destroy({
where: { where: {
id, id,
create: true create: true

View File

@ -1,20 +1,20 @@
import { SlashCommandBuilder, PermissionFlagsBits, ChatInputCommandInteraction } from 'discord.js'; import { SlashCommandBuilder, PermissionFlagsBits, ChatInputCommandInteraction } from 'discord.js';
import { Roles, Guilds } from '../../../database.js'; import { Role, Guild } from '../../../database.js';
/** /**
* @param {Guilds} guild * @param {Guild} guild
* @param {Roles} role * @param {Role} role
*/ */
const registerRole = async (guild, role) => { const registerRole = async (guild, role) => {
// Check if guild exists in database, otherwise create it // Check if guild exists in database, otherwise create it
const guildData = { id: guild.id }; const guildData = { id: guild.id };
await Guilds.findOrCreate({ await Guild.findOrCreate({
where: guildData, where: guildData,
defaults: guildData defaults: guildData
}); });
// Register role in database // Register role in database
await Roles.create({ await Role.create({
guild: guild.id, guild: guild.id,
id: role.id, id: role.id,
assign: true assign: true
@ -57,20 +57,18 @@ export async function execute(interaction) {
switch (options.getSubcommand()) { switch (options.getSubcommand()) {
case 'add': { case 'add': {
// Search for role in database // Search for role in database
/** @type {import('../../../models/roles.js').Role|null} */ const found = await Role.findOne({
const found = await Roles.findOne({
where: { where: {
id: role.id id: role.id
} }
}); });
// Toggle role assignment if found // Toggle role assignment if found
if (found !== null) { if (found) {
found.assign = true; found.assign = true;
await found.save(); await found.save();
// Otherwise create new database entry // Otherwise create new database entry
} else await registerRole(interaction.guild, role); } else await registerRole(interaction.guild, role);
// Reply successfully to acknowledge command // Reply successfully to acknowledge command
await interaction.reply({ await interaction.reply({
content: 'Successfully registered role.', content: 'Successfully registered role.',
@ -82,7 +80,7 @@ export async function execute(interaction) {
} }
case 'remove': { case 'remove': {
// Remove role from database // Remove role from database
const count = await Roles.destroy({ const count = await Role.destroy({
where: { where: {
id: role.id, id: role.id,
assign: true assign: true

View File

@ -4,7 +4,7 @@ import {
PermissionFlagsBits, PermissionFlagsBits,
ContextMenuCommandInteraction ContextMenuCommandInteraction
} from 'discord.js'; } from 'discord.js';
import { Messages } from '../../../../database.js'; import { Message } from '../../../../database.js';
export const data = new ContextMenuCommandBuilder() export const data = new ContextMenuCommandBuilder()
.setDMPermission(false) .setDMPermission(false)
@ -17,7 +17,7 @@ export async function execute(interaction) {
try { try {
// Create database entry // Create database entry
await Messages.create({ id }); await Message.create({ id });
// Reply successfully to acknowledge command // Reply successfully to acknowledge command
await interaction.reply({ await interaction.reply({

View File

@ -1,6 +1,6 @@
import { PermissionFlagsBits, SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'; import { PermissionFlagsBits, SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js';
import { addSelfRoles, removeSelfRoles } from '../../../shared.js'; import { addSelfRoles, removeSelfRoles } from '../../../shared.js';
import { Guilds, Messages } from '../../../database.js'; import { Guild, Message } from '../../../database.js';
/** /**
* Sends a `Message` in the current channel and registers for self roles. * Sends a `Message` in the current channel and registers for self roles.
@ -48,12 +48,11 @@ const registerSelfRoles = async (interaction) => {
await channel.messages.fetch(id); await channel.messages.fetch(id);
// Check if message is already registered // Check if message is already registered
/** @type {import('../../../models/messages.js').Message|null} */ const found = await Message.findOne({
const found = await Messages.findOne({
where: { id } where: { id }
}); });
if (found !== null) throw new Error('Messages already registered!'); if (found) throw new Error('Message already registered!');
// Reply successfully to acknowledge command // Reply successfully to acknowledge command
await interaction.reply({ await interaction.reply({
@ -197,13 +196,13 @@ export async function execute(interaction) {
try { try {
// Create guild if not exists // Create guild if not exists
const guildData = { id: interaction.guild.id }; const guildData = { id: interaction.guild.id };
await Guilds.findOrCreate({ await Guild.findOrCreate({
where: guildData, where: guildData,
defaults: guildData defaults: guildData
}); });
// Create database entry // Create database entry
await Messages.create({ await Message.create({
id, id,
guild: interaction.guild.id guild: interaction.guild.id
}); });

View File

@ -18,26 +18,26 @@ const sequelize = new Sequelize({
logging: false logging: false
}); });
const Responses = defineResponse(sequelize); const Response = defineResponse(sequelize);
const Keywords = defineKeyword(sequelize); const Keyword = defineKeyword(sequelize);
Keywords.hasMany(Responses, { foreignKey: 'keyword', onDelete: 'CASCADE' }); Keyword.hasMany(Response, { foreignKey: 'keyword', onDelete: 'CASCADE' });
const RoleEmojiPairs = defineRoleEmojiPair(sequelize); const RoleEmojiPair = defineRoleEmojiPair(sequelize);
const VoiceChannels = defineVoiceChannel(sequelize); const VoiceChannel = defineVoiceChannel(sequelize);
const Messages = defineMessage(sequelize); const Message = defineMessage(sequelize);
Messages.hasMany(RoleEmojiPairs, { foreignKey: 'message', onDelete: 'CASCADE' }); Message.hasMany(RoleEmojiPair, { foreignKey: 'message', onDelete: 'CASCADE' });
const Roles = defineRole(sequelize); const Role = defineRole(sequelize);
Roles.hasMany(RoleEmojiPairs, { foreignKey: 'role', onDelete: 'CASCADE' }); Role.hasMany(RoleEmojiPair, { foreignKey: 'role', onDelete: 'CASCADE' });
const Guilds = defineGuild(sequelize); const Guild = defineGuild(sequelize);
Guilds.hasMany(Keywords, { foreignKey: 'guild', onDelete: 'CASCADE' }); Guild.hasMany(Keyword, { foreignKey: 'guild', onDelete: 'CASCADE' });
Guilds.hasMany(VoiceChannels, { foreignKey: 'guild', onDelete: 'CASCADE' }); Guild.hasMany(VoiceChannel, { foreignKey: 'guild', onDelete: 'CASCADE' });
Guilds.hasMany(Messages, { foreignKey: 'guild', onDelete: 'CASCADE' }); Guild.hasMany(Message, { foreignKey: 'guild', onDelete: 'CASCADE' });
Guilds.hasMany(Roles, { foreignKey: 'guild', onDelete: 'CASCADE' }); Guild.hasMany(Role, { foreignKey: 'guild', onDelete: 'CASCADE' });
sequelize.sync(); sequelize.sync();
export { sequelize, Guilds, Roles, Messages, VoiceChannels, RoleEmojiPairs, Keywords, Responses }; export { sequelize, Guild, Role, RoleEmojiPair, VoiceChannel, Message };

View File

@ -1,5 +1,5 @@
import { ChannelType, Events, GuildChannel } from 'discord.js'; import { ChannelType, Events, GuildChannel } from 'discord.js';
import { VoiceChannels } from '../../database.js'; import { VoiceChannel } from '../../database.js';
export const name = Events.ChannelDelete; export const name = Events.ChannelDelete;
/** @param {GuildChannel} channel */ /** @param {GuildChannel} channel */
@ -7,7 +7,7 @@ export async function execute(channel) {
if (channel.type !== ChannelType.GuildVoice) return; if (channel.type !== ChannelType.GuildVoice) return;
// Delete channel entry once channel is deleted itself // Delete channel entry once channel is deleted itself
const count = await VoiceChannels.destroy({ const count = await VoiceChannel.destroy({
where: { where: {
id: channel.id id: channel.id
} }

View File

@ -7,7 +7,7 @@ import {
VoiceState, VoiceState,
PermissionsBitField PermissionsBitField
} from 'discord.js'; } from 'discord.js';
import { VoiceChannels } from '../../database.js'; import { VoiceChannel } from '../../database.js';
/** /**
* Function that either creates a new custom channel or gets an existing one registered in the database. * Function that either creates a new custom channel or gets an existing one registered in the database.
@ -18,8 +18,7 @@ import { VoiceChannels } from '../../database.js';
*/ */
const getChannel = async (member, guildChs, channel) => { const getChannel = async (member, guildChs, channel) => {
// Check database for existing channel // Check database for existing channel
/** @type {import('../../models/voiceChannels.js').VoiceChannel|null} */ const ownCh = await VoiceChannel.findOne({
const ownCh = await VoiceChannels.findOne({
where: { where: {
owner: member.id owner: member.id
} }
@ -36,7 +35,7 @@ const getChannel = async (member, guildChs, channel) => {
}); });
// Save newly created channel // Save newly created channel
await VoiceChannels.create({ await VoiceChannel.create({
id: privCh.id, id: privCh.id,
owner: member.id owner: member.id
}); });
@ -59,8 +58,7 @@ const leftVoiceChat = async (state) => {
if (members.length > 0) return; if (members.length > 0) return;
// Find channel by id, return if not registered as custom // Find channel by id, return if not registered as custom
/** @type {import('../../models/voiceChannels.js').VoiceChannel|null} */ const custom = await VoiceChannel.findOne({
const custom = await VoiceChannels.findOne({
where: { where: {
id: channel.id, id: channel.id,
create: false create: false
@ -86,8 +84,7 @@ export async function execute(oldState, newState) {
if (!channel) return; if (!channel) return;
// Find channel by id, return if not registered for customs // Find channel by id, return if not registered for customs
/** @type {import('../../models/voiceChannels.js').VoiceChannel|null} */ const createCh = await VoiceChannel.findOne({
const createCh = await VoiceChannels.findOne({
where: { where: {
id: channel.id, id: channel.id,
create: true create: true

View File

@ -1,12 +1,11 @@
import { Events, GuildMember } from 'discord.js'; import { Events, GuildMember } from 'discord.js';
import { Roles } from '../../database.js'; import { Role } from '../../database.js';
export const name = Events.GuildMemberAdd; export const name = Events.GuildMemberAdd;
/** @param {GuildMember} member */ /** @param {GuildMember} member */
export async function execute(member) { export async function execute(member) {
// Find roles to be assigned in guild from database // Find roles to be assigned in guild from database
/** @type {import('../../models/roles.js').Role[]} */ const roles = await Role.findAll({
const roles = await Roles.findAll({
where: { where: {
guild: member.guild.id, guild: member.guild.id,
assign: true assign: true

View File

@ -1,11 +1,11 @@
import { Messages } from '../../database.js'; import { Message } from '../../database.js';
import { Events } from 'discord.js'; import { Events } from 'discord.js';
export const name = Events.MessageDelete; export const name = Events.MessageDelete;
/** @param {import('discord.js').Message} message */ /** @param {import('discord.js').Message} message */
export async function execute(message) { export async function execute(message) {
// Delete message entry once message is deleted itself // Delete message entry once message is deleted itself
const count = await Messages.destroy({ const count = await Message.destroy({
where: { where: {
id: message.id id: message.id
} }

View File

@ -1,5 +1,5 @@
import { Events, MessageReaction, User } from 'discord.js'; import { Events, MessageReaction, User } from 'discord.js';
import { Messages, RoleEmojiPairs } from '../../database.js'; import { Message, RoleEmojiPair } from '../../database.js';
import { config } from 'dotenv'; import { config } from 'dotenv';
config(); config();
@ -14,8 +14,7 @@ export async function execute(reaction, user) {
// Get message // Get message
const msgID = reaction.message.id; const msgID = reaction.message.id;
/** @type {import('../../models/messages.js').Message|null} */ const message = await Message.findOne({
const message = await Messages.findOne({
where: { where: {
id: msgID id: msgID
} }
@ -25,8 +24,7 @@ export async function execute(reaction, user) {
// Get emoji // Get emoji
const emoji = reaction.emoji.toString(); const emoji = reaction.emoji.toString();
/** @type {import('../../models/roleEmojiPairs.js').RoleEmojiPair|null} */ const rep = await RoleEmojiPair.findOne({
const rep = await RoleEmojiPairs.findOne({
where: { where: {
message: msgID, message: msgID,
emoji emoji
@ -36,7 +34,7 @@ export async function execute(reaction, user) {
if (rep === null) { if (rep === null) {
// Remove reaction and quit // Remove reaction and quit
try { try {
await reaction.remove(); reaction.remove();
} catch (error) { } catch (error) {
// Missing permissions // Missing permissions
console.error(error); console.error(error);

View File

@ -1,5 +1,5 @@
import { Events, MessageReaction, User } from 'discord.js'; import { Events, MessageReaction, User } from 'discord.js';
import { Messages, RoleEmojiPairs } from '../../database.js'; import { Message, RoleEmojiPair } from '../../database.js';
import { config } from 'dotenv'; import { config } from 'dotenv';
config(); config();
@ -14,8 +14,7 @@ export async function execute(reaction, user) {
// Get message // Get message
const msgID = reaction.message.id; const msgID = reaction.message.id;
/** @type {import('../../models/messages.js').Message|null} */ const message = await Message.findOne({
const message = await Messages.findOne({
where: { where: {
id: msgID id: msgID
} }
@ -25,8 +24,7 @@ export async function execute(reaction, user) {
// Get emoji // Get emoji
const emoji = reaction.emoji.toString(); const emoji = reaction.emoji.toString();
/** @type {import('../../models/roleEmojiPairs.js').RoleEmojiPair|null} */ const rep = await RoleEmojiPair.findOne({
const rep = await RoleEmojiPairs.findOne({
where: { where: {
message: msgID, message: msgID,
emoji emoji

View File

@ -6,7 +6,7 @@ import { DataTypes, Sequelize } from 'sequelize';
*/ */
/** /**
* The definition of the `Guilds` table in the database. * The definition of the `Guild` table in the database.
* @param {Sequelize} sequelize * @param {Sequelize} sequelize
*/ */
export default function (sequelize) { export default function (sequelize) {

View File

@ -7,7 +7,7 @@ import { DataTypes, Deferrable, Sequelize } from 'sequelize';
*/ */
/** /**
* The definition of the `Messages` table in the database. * The definition of the `Message` table in the database.
* @param {Sequelize} sequelize * @param {Sequelize} sequelize
*/ */
export default function (sequelize) { export default function (sequelize) {

View File

@ -9,7 +9,7 @@ import { DataTypes, Deferrable, Sequelize } from 'sequelize';
*/ */
/** /**
* The definition of the `RoleEmojiPairs` table in the database. * The definition of the `RoleEmojiPair` table in the database.
* @param {Sequelize} sequelize * @param {Sequelize} sequelize
*/ */
export default function (sequelize) { export default function (sequelize) {

View File

@ -8,7 +8,7 @@ import { DataTypes, Deferrable, Sequelize } from 'sequelize';
*/ */
/** /**
* The definition of the `Roles` table in the database. * The definition of the `Role` table in the database.
* @param {Sequelize} sequelize * @param {Sequelize} sequelize
*/ */
export default function (sequelize) { export default function (sequelize) {

View File

@ -9,7 +9,7 @@ import { DataTypes, Deferrable, Sequelize } from 'sequelize';
*/ */
/** /**
* The definition of the `VoiceChannels` table in the database. * The definition of the `VoiceChannel` table in the database.
* @param {Sequelize} sequelize * @param {Sequelize} sequelize
*/ */
export default function (sequelize) { export default function (sequelize) {

16
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "discord-bot", "name": "discord-bot",
"version": "0.3.0", "version": "0.2.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "discord-bot", "name": "discord-bot",
"version": "0.3.0", "version": "0.2.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"discord.js": "^14.14.1", "discord.js": "^14.14.1",
@ -1424,12 +1424,6 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
}, },
"node_modules/ip": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz",
"integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==",
"optional": true
},
"node_modules/is-builtin-module": { "node_modules/is-builtin-module": {
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
@ -2482,6 +2476,12 @@
"npm": ">= 3.0.0" "npm": ">= 3.0.0"
} }
}, },
"node_modules/socks/node_modules/ip": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
"integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
"optional": true
},
"node_modules/spdx-exceptions": { "node_modules/spdx-exceptions": {
"version": "2.4.0", "version": "2.4.0",
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz",

View File

@ -1,5 +1,5 @@
import { ChatInputCommandInteraction, ContextMenuCommandInteraction, Role } from 'discord.js'; import { ChatInputCommandInteraction, ContextMenuCommandInteraction, Role } from 'discord.js';
import { Messages, RoleEmojiPairs, Guilds } from './database.js'; import { Message, RoleEmojiPair, Guild } from './database.js';
import { readdir } from 'fs/promises'; import { readdir } from 'fs/promises';
import { config } from 'dotenv'; import { config } from 'dotenv';
import { Op } from 'sequelize'; import { Op } from 'sequelize';
@ -15,7 +15,7 @@ config();
*/ */
export const removeSelfRoles = async (interaction, id) => { export const removeSelfRoles = async (interaction, id) => {
// Try deleting message from database // Try deleting message from database
const count = await Messages.destroy({ const count = await Message.destroy({
where: { where: {
id: id id: id
} }
@ -35,20 +35,18 @@ export const removeSelfRoles = async (interaction, id) => {
}; };
/** /**
* Function to handle saving all the corresponding data for `Messages` and `RoleEmojiPairs` tables. * Function to handle saving all the corresponding data for `Message` and `RoleEmojiPair` tables.
* @param {string} id A Discord message ID. * @param {string} id A Discord message ID.
* @param {Role} role * @param {Role} role
* @param {string} emoji Either a unicode emoji or a string representation in Discord custom emoji format. * @param {string} emoji Either a unicode emoji or a string representation in Discord custom emoji format.
*/ */
const saveMessageData = async (id, role, emoji) => { const saveMessageData = async (id, role, emoji) => {
// Try finding message // Try finding message
/** @type {import('./models/messages.js').Message|null} */ const msg = await Message.findOne({ where: { id } });
const msg = await Messages.findOne({ where: { id } });
if (msg === null) throw new Error(`No message with ID '${id}' could be found!`); if (msg === null) throw new Error(`No message with ID '${id}' could be found!`);
// Try finding existing entry // Try finding existing entry
/** @type {import('./models/roleEmojiPairs.js').RoleEmojiPair|null} */ const rep = await RoleEmojiPair.findOne({
const rep = await RoleEmojiPairs.findOne({
where: { where: {
[Op.or]: [ [Op.or]: [
{ {
@ -69,13 +67,13 @@ const saveMessageData = async (id, role, emoji) => {
// Create guild if not exists // Create guild if not exists
const guildData = { id: role.guild.id }; const guildData = { id: role.guild.id };
await Guilds.findOrCreate({ await Guild.findOrCreate({
where: guildData, where: guildData,
defaults: guildData defaults: guildData
}); });
// Create database entry for pair // Create database entry for pair
await RoleEmojiPairs.create({ await RoleEmojiPair.create({
message: id, message: id,
role: role.id, role: role.id,
guild: guildData.id, guild: guildData.id,
@ -94,8 +92,7 @@ const editMessage = async (message, role, emoji) => {
// Find out whether to pad message or already present // Find out whether to pad message or already present
let padding = '\n'; let padding = '\n';
/** @type {import('./models/roleEmojiPairs.js').RoleEmojiPair[]} */ const reps = await RoleEmojiPair.findAll({ where: { message: message.id } });
const reps = await RoleEmojiPairs.findAll({ where: { message: message.id } });
if (reps.length === 0) padding += '\n'; if (reps.length === 0) padding += '\n';
// Get old and build new content of message // Get old and build new content of message