migrate from pg to sequelize
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,3 +1,6 @@
|
|||||||
.env
|
.env
|
||||||
node_modules/
|
node_modules/
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
src/database/config/
|
||||||
|
src/database/migrations/
|
||||||
|
src/database/seeders/
|
||||||
|
|||||||
59
eslint.config.mjs
Normal file
59
eslint.config.mjs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import globals from 'globals'
|
||||||
|
import pluginJs from '@eslint/js'
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
files: ['eslint.config.mjs'],
|
||||||
|
languageOptions: {
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 2021,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'semi': ['error', 'never'],
|
||||||
|
'quotes': ['error', 'single'],
|
||||||
|
'indent': ['error', 2],
|
||||||
|
'linebreak-style': ['error', 'unix'],
|
||||||
|
'comma-dangle': ['error', 'always-multiline'],
|
||||||
|
'no-unused-vars': ['error', {
|
||||||
|
vars: 'all',
|
||||||
|
args: 'after-used',
|
||||||
|
ignoreRestSiblings: true,
|
||||||
|
caughtErrors: 'none',
|
||||||
|
argsIgnorePattern: '_',
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['**/*.js'],
|
||||||
|
languageOptions: {
|
||||||
|
sourceType: 'commonjs',
|
||||||
|
ecmaVersion: 2021,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'semi': ['error', 'never'],
|
||||||
|
'quotes': ['error', 'single'],
|
||||||
|
'indent': ['error', 2],
|
||||||
|
'linebreak-style': ['error', 'unix'],
|
||||||
|
'comma-dangle': ['error', {
|
||||||
|
arrays: 'always-multiline',
|
||||||
|
objects: 'always-multiline',
|
||||||
|
imports: 'always-multiline',
|
||||||
|
exports: 'always-multiline',
|
||||||
|
functions: 'never',
|
||||||
|
}],
|
||||||
|
'no-unused-vars': ['error', {
|
||||||
|
vars: 'all',
|
||||||
|
args: 'after-used',
|
||||||
|
ignoreRestSiblings: true,
|
||||||
|
caughtErrors: 'none',
|
||||||
|
argsIgnorePattern: '_',
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
languageOptions: {
|
||||||
|
globals: globals.browser,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pluginJs.configs.recommended,
|
||||||
|
]
|
||||||
@@ -9,5 +9,12 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.10.0",
|
||||||
|
"eslint": "^9.10.0",
|
||||||
|
"globals": "^15.9.0",
|
||||||
|
"sequelize-auto": "^0.8.8",
|
||||||
|
"sequelize-cli": "^6.6.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,100 +1,111 @@
|
|||||||
const { getClient } = require('./database')
|
const {
|
||||||
|
birthday: Birthday,
|
||||||
|
discorduser: DiscordUser,
|
||||||
|
} = require('./models')
|
||||||
|
|
||||||
const CreateBirthday = async (user, birthday) => {
|
const CreateBirthday = async (userName, birthdayDate) => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
const [user, _] = await DiscordUser.findOrCreate({
|
||||||
const userResult = await client.query(`
|
where: { name: userName },
|
||||||
SELECT * FROM discorduser
|
defaults: { name: userName },
|
||||||
WHERE name = $1;`,
|
})
|
||||||
[user]
|
|
||||||
)
|
|
||||||
|
|
||||||
if (userResult.rows.length === 0) {
|
const formattedBirthday = new Date(
|
||||||
await client.query(`
|
birthdayDate.split('.').reverse().join('-')
|
||||||
INSERT INTO discorduser (name)
|
).toISOString().slice(0, 10)
|
||||||
VALUES ($1);`,
|
|
||||||
[user]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await client.query(`
|
const birthday = await Birthday.create({
|
||||||
INSERT INTO birthday (date, discorduser)
|
date: formattedBirthday,
|
||||||
VALUES ($1, $2);`,
|
discorduser: user.name,
|
||||||
[new Date(birthday.split('.').reverse().join('-')).toISOString().slice(0, 10), user]
|
})
|
||||||
)
|
|
||||||
|
|
||||||
return res.rowCount > 0
|
return birthday !== null
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error creating birthday entry:', error)
|
console.error('Error creating birthday entry:', error)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReadBirthday = async (user) => {
|
const ReadBirthday = async (userName) => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
if (userName) {
|
||||||
|
const user = await DiscordUser.findOne({
|
||||||
if (user) {
|
where: {
|
||||||
const res = await client.query(`
|
name: userName,
|
||||||
SELECT * FROM birthday
|
},
|
||||||
WHERE discorduser = $1;`,
|
})
|
||||||
[user]
|
if (user) {
|
||||||
)
|
const birthdays = await Birthday.findAll({
|
||||||
return res.rows
|
where: {
|
||||||
} else {
|
discorduser: user.name,
|
||||||
const res = await client.query(`
|
},
|
||||||
SELECT * FROM birthday`,
|
})
|
||||||
)
|
return birthdays
|
||||||
return res.rows
|
} else return []
|
||||||
}
|
} else {
|
||||||
} catch (error) {
|
const birthdays = await Birthday.findAll()
|
||||||
console.error('Error reading birthday table:', error)
|
return birthdays
|
||||||
return []
|
}
|
||||||
}
|
} catch (error) {
|
||||||
|
console.error('Error reading birthday table:', error)
|
||||||
|
return []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const UpdateBirthday = async (user, birthday) => {
|
const UpdateBirthday = async (userName, birthdayDate) => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
const user = await DiscordUser.findOne({
|
||||||
|
where: {
|
||||||
|
name: userName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
if (!birthday) return false
|
if (user) {
|
||||||
|
const [updated] = await Birthday.update(
|
||||||
await client.query(`
|
{
|
||||||
UPDATE birthday
|
date: new Date(
|
||||||
SET birthday = $2
|
birthdayDate.split('.').reverse().join('-')
|
||||||
WHERE discorduser = $1;`,
|
).toISOString().slice(0, 10),
|
||||||
[user, birthday]
|
},
|
||||||
)
|
{
|
||||||
|
where: {
|
||||||
return true
|
discorduser: user.name,
|
||||||
} catch (error) {
|
},
|
||||||
console.error('Error updating birthday table:', error)
|
}
|
||||||
return false
|
)
|
||||||
}
|
return updated > 0
|
||||||
|
} else return false
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error updating birthday table:', error)
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DeleteBirthday = async (user) => {
|
const DeleteBirthday = async (userName) => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
const user = await DiscordUser.findOne({
|
||||||
|
where: {
|
||||||
|
name: userName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
if (!user) return false
|
if (user) {
|
||||||
|
const deleted = await Birthday.destroy({
|
||||||
await client.query(`
|
where: {
|
||||||
DELETE FROM birthday
|
discorduser: user.name,
|
||||||
WHERE discorduser = $1;`,
|
},
|
||||||
[user]
|
})
|
||||||
)
|
return deleted > 0
|
||||||
|
} else return false
|
||||||
return true
|
} catch (error) {
|
||||||
} catch (error) {
|
console.error('Error deleting birthday table:', error)
|
||||||
console.error('Error deleting birthday table:', error)
|
return false
|
||||||
return false
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
CreateBirthday,
|
CreateBirthday,
|
||||||
ReadBirthday,
|
ReadBirthday,
|
||||||
UpdateBirthday,
|
UpdateBirthday,
|
||||||
DeleteBirthday,
|
DeleteBirthday,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,99 +1,99 @@
|
|||||||
const { getClient } = require('./database')
|
const {
|
||||||
|
blacklist: Blacklist,
|
||||||
|
discorduser: DiscordUser,
|
||||||
|
} = require('./models')
|
||||||
|
|
||||||
const CreateBlacklist = async (reportedUser, reason, reportedByUser) => {
|
const CreateBlacklist = async (reportedUser, reason, reportedByUser) => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
const existingBlacklist = await Blacklist.findOne({
|
||||||
|
where: {
|
||||||
|
name: reportedUser,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
const alreadyReportedResult = await client.query(
|
if (existingBlacklist) return existingBlacklist
|
||||||
"SELECT name FROM blacklist WHERE name = $1",
|
|
||||||
[reportedUser]
|
|
||||||
)
|
|
||||||
|
|
||||||
if (alreadyReportedResult.rows.length === 1)
|
const [reportingUser] = await DiscordUser.findOrCreate({
|
||||||
return alreadyReportedResult.rows[0]
|
where: {
|
||||||
|
name: reportedByUser,
|
||||||
|
},
|
||||||
|
defaults: {
|
||||||
|
name: reportedByUser,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
const userResult = await client.query(
|
const blacklistEntry = await Blacklist.create({
|
||||||
"SELECT * FROM discorduser WHERE name = $1",
|
name: reportedUser,
|
||||||
[reportedByUser]
|
reason,
|
||||||
)
|
reportedby: reportingUser.name,
|
||||||
|
})
|
||||||
|
|
||||||
if (userResult.rows.length === 0)
|
return blacklistEntry !== null
|
||||||
await client.query(
|
} catch (error) {
|
||||||
"INSERT INTO discorduser (name) VALUES ($1)",
|
console.error('Error creating blacklist entry:', error)
|
||||||
[reportedByUser]
|
return false
|
||||||
)
|
}
|
||||||
|
|
||||||
await client.query(
|
|
||||||
"INSERT INTO blacklist (name, reason, reportedby) VALUES ($1, $2, $3)",
|
|
||||||
[reportedUser, reason, reportedByUser]
|
|
||||||
)
|
|
||||||
|
|
||||||
return true
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error creating blacklist entry:', error)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReadBlacklist = async (user) => {
|
const ReadBlacklist = async (userName) => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
if (userName) {
|
||||||
|
const blacklistEntry = await Blacklist.findOne({
|
||||||
if (user) {
|
where: {
|
||||||
const res = await client.query(
|
name: userName,
|
||||||
"SELECT * FROM blacklist WHERE name=$1",
|
},
|
||||||
[user]
|
})
|
||||||
)
|
return blacklistEntry || false
|
||||||
return res.rows[0] || false
|
} else {
|
||||||
} else {
|
const allBlacklistEntries = await Blacklist.findAll()
|
||||||
const res = await client.query(
|
return allBlacklistEntries
|
||||||
"SELECT * FROM blacklist"
|
}
|
||||||
)
|
} catch (error) {
|
||||||
return res.rows
|
console.error('Error reading blacklist table:', error)
|
||||||
}
|
return []
|
||||||
} catch (error) {
|
}
|
||||||
console.error('Error reading blacklist table:', error)
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const UpdateBlacklist = async (reportedUser, reason) => {
|
const UpdateBlacklist = async (reportedUser, reason) => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
if (!reportedUser) return false
|
||||||
|
|
||||||
if (!reportedUser) return false
|
const [updated] = await Blacklist.update(
|
||||||
|
{ reason },
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
name: reportedUser,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
await client.query(
|
return updated > 0
|
||||||
"UPDATE blacklist SET reason = $2 WHERE name = $1",
|
} catch (error) {
|
||||||
[reportedUser, reason]
|
console.error('Error updating blacklist table:', error)
|
||||||
)
|
return false
|
||||||
return true
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('Error updating blacklist table:', error)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DeleteBlacklist = async (user) => {
|
const DeleteBlacklist = async (userName) => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
if (!userName) return false
|
||||||
|
|
||||||
if (!user) return false
|
const deleted = await Blacklist.destroy({
|
||||||
|
where: {
|
||||||
|
name: userName,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
await client.query(
|
return deleted > 0
|
||||||
"DELETE FROM blacklist WHERE name = $1",
|
} catch (error) {
|
||||||
[user]
|
console.error('Error deleting blacklist table:', error)
|
||||||
)
|
return false
|
||||||
return true
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('Error deleting blacklist table:', error)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
CreateBlacklist,
|
CreateBlacklist,
|
||||||
ReadBlacklist,
|
ReadBlacklist,
|
||||||
UpdateBlacklist,
|
UpdateBlacklist,
|
||||||
DeleteBlacklist,
|
DeleteBlacklist,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
const { Client } = require('pg')
|
|
||||||
|
|
||||||
|
|
||||||
let client = null
|
|
||||||
|
|
||||||
const createClient = (config) => {
|
|
||||||
client = new Client(config);
|
|
||||||
return client;
|
|
||||||
};
|
|
||||||
|
|
||||||
const connectDatabase = async (client) => {
|
|
||||||
try {
|
|
||||||
await client.connect()
|
|
||||||
console.log('Database connected')
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Database connection error:', error)
|
|
||||||
throw new Error('Connection failed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const getClient = () => {
|
|
||||||
if (!client) {
|
|
||||||
throw new Error('Client has not been initialized. Call createClient first.');
|
|
||||||
}
|
|
||||||
return client;
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
createClient,
|
|
||||||
connectDatabase,
|
|
||||||
getClient,
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
const { getClient } = require('./database')
|
const {
|
||||||
|
event_schedule: EventTimes,
|
||||||
|
event_role_view: EventRoleView,
|
||||||
|
event_roles: EventRoles,
|
||||||
|
} = require('./models')
|
||||||
|
|
||||||
const ReadEvents = async () => {
|
const ReadEvents = async () => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
const events = await EventTimes.findAll()
|
||||||
|
return events
|
||||||
const res = await client.query(
|
|
||||||
"SELECT * FROM event_times"
|
|
||||||
)
|
|
||||||
return res.rows
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error reading event entries:', error)
|
console.error('Error reading event entries:', error)
|
||||||
return false
|
return false
|
||||||
@@ -16,34 +16,30 @@ const ReadEvents = async () => {
|
|||||||
|
|
||||||
const GetEventRole = async () => {
|
const GetEventRole = async () => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
const eventRoles = await EventRoleView.findAll()
|
||||||
|
|
||||||
const res = await client.query(
|
|
||||||
"SELECT * FROM event_role_view"
|
|
||||||
)
|
|
||||||
const rolesEventMap = new Map()
|
const rolesEventMap = new Map()
|
||||||
res.rows.forEach(row => rolesEventMap.set(row.event_name, row.role))
|
|
||||||
|
eventRoles.forEach(row => rolesEventMap.set(row.event_name, row.role))
|
||||||
|
|
||||||
return rolesEventMap
|
return rolesEventMap
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error('Error fetching event roles:', error)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetIconRole = async () => {
|
const GetIconRole = async () => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
const eventIcons = await EventRoles.findAll({
|
||||||
|
attributes: ['role', 'icon_name'],
|
||||||
|
})
|
||||||
|
const rolesIconMap = new Map()
|
||||||
|
|
||||||
const res = await client.query(
|
eventIcons.forEach(row => rolesIconMap.set(row.icon_name, row.role))
|
||||||
"SELECT role, icon_name FROM event_roles"
|
|
||||||
)
|
|
||||||
const rolesEventMap = new Map()
|
|
||||||
res.rows.forEach(row => rolesEventMap.set(row.icon_name, row.role))
|
|
||||||
|
|
||||||
return rolesEventMap
|
return rolesIconMap
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error('Error fetching icon roles:', error)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
37
src/database/models/birthday.js
Normal file
37
src/database/models/birthday.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
const Sequelize = require('sequelize')
|
||||||
|
module.exports = function(sequelize, DataTypes) {
|
||||||
|
return sequelize.define('birthday', {
|
||||||
|
id: {
|
||||||
|
autoIncrement: true,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: false,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
date: {
|
||||||
|
type: DataTypes.DATEONLY,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
discorduser: {
|
||||||
|
type: DataTypes.STRING(100),
|
||||||
|
allowNull: false,
|
||||||
|
references: {
|
||||||
|
model: 'discorduser',
|
||||||
|
key: 'name',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
sequelize,
|
||||||
|
tableName: 'birthday',
|
||||||
|
schema: 'public',
|
||||||
|
timestamps: false,
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'birthday_pkey',
|
||||||
|
unique: true,
|
||||||
|
fields: [
|
||||||
|
{ name: 'id' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
36
src/database/models/blacklist.js
Normal file
36
src/database/models/blacklist.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
const Sequelize = require('sequelize')
|
||||||
|
module.exports = function(sequelize, DataTypes) {
|
||||||
|
return sequelize.define('blacklist', {
|
||||||
|
name: {
|
||||||
|
type: DataTypes.STRING(100),
|
||||||
|
allowNull: false,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
reason: {
|
||||||
|
type: DataTypes.TEXT,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
reportedby: {
|
||||||
|
type: DataTypes.STRING(100),
|
||||||
|
allowNull: true,
|
||||||
|
references: {
|
||||||
|
model: 'discorduser',
|
||||||
|
key: 'name',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
sequelize,
|
||||||
|
tableName: 'blacklist',
|
||||||
|
schema: 'public',
|
||||||
|
timestamps: false,
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'blacklist_pkey',
|
||||||
|
unique: true,
|
||||||
|
fields: [
|
||||||
|
{ name: 'name' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
24
src/database/models/discorduser.js
Normal file
24
src/database/models/discorduser.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
const Sequelize = require('sequelize')
|
||||||
|
module.exports = function(sequelize, DataTypes) {
|
||||||
|
return sequelize.define('discorduser', {
|
||||||
|
name: {
|
||||||
|
type: DataTypes.STRING(100),
|
||||||
|
allowNull: false,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
sequelize,
|
||||||
|
tableName: 'discorduser',
|
||||||
|
schema: 'public',
|
||||||
|
timestamps: false,
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'discorduser_pkey',
|
||||||
|
unique: true,
|
||||||
|
fields: [
|
||||||
|
{ name: 'name' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
37
src/database/models/event.js
Normal file
37
src/database/models/event.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
const Sequelize = require('sequelize')
|
||||||
|
module.exports = function(sequelize, DataTypes) {
|
||||||
|
return sequelize.define('event', {
|
||||||
|
id: {
|
||||||
|
autoIncrement: true,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: false,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: DataTypes.STRING(255),
|
||||||
|
allowNull: false,
|
||||||
|
unique: 'event_name_key',
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
sequelize,
|
||||||
|
tableName: 'event',
|
||||||
|
schema: 'public',
|
||||||
|
timestamps: false,
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'event_name_key',
|
||||||
|
unique: true,
|
||||||
|
fields: [
|
||||||
|
{ name: 'name' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'event_pkey',
|
||||||
|
unique: true,
|
||||||
|
fields: [
|
||||||
|
{ name: 'id' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
41
src/database/models/event_roles.js
Normal file
41
src/database/models/event_roles.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
const Sequelize = require('sequelize')
|
||||||
|
module.exports = function(sequelize, DataTypes) {
|
||||||
|
return sequelize.define('event_roles', {
|
||||||
|
event_id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: true,
|
||||||
|
references: {
|
||||||
|
model: 'event',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
role: {
|
||||||
|
type: DataTypes.STRING(50),
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
icon_name: {
|
||||||
|
type: DataTypes.STRING(50),
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
role_id: {
|
||||||
|
autoIncrement: true,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: false,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
sequelize,
|
||||||
|
tableName: 'event_roles',
|
||||||
|
schema: 'public',
|
||||||
|
timestamps: false,
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'event_roles_pkey',
|
||||||
|
unique: true,
|
||||||
|
fields: [
|
||||||
|
{ name: 'role_id' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
45
src/database/models/event_schedule.js
Normal file
45
src/database/models/event_schedule.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
const Sequelize = require('sequelize')
|
||||||
|
module.exports = function(sequelize, DataTypes) {
|
||||||
|
return sequelize.define('event_schedule', {
|
||||||
|
id: {
|
||||||
|
autoIncrement: true,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: false,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
event_id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: false,
|
||||||
|
references: {
|
||||||
|
model: 'event',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
day_of_week: {
|
||||||
|
type: DataTypes.STRING(9),
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
start_time: {
|
||||||
|
type: DataTypes.TIME,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
end_time: {
|
||||||
|
type: DataTypes.TIME,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
sequelize,
|
||||||
|
tableName: 'event_schedule',
|
||||||
|
schema: 'public',
|
||||||
|
timestamps: false,
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'event_schedule_pkey',
|
||||||
|
unique: true,
|
||||||
|
fields: [
|
||||||
|
{ name: 'id' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
43
src/database/models/index.js
Normal file
43
src/database/models/index.js
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
const Sequelize = require('sequelize')
|
||||||
|
const process = require('process')
|
||||||
|
const basename = path.basename(__filename)
|
||||||
|
const env = process.env.NODE_ENV || 'development'
|
||||||
|
const config = require(__dirname + '/../config/config.json')[env]
|
||||||
|
const db = {}
|
||||||
|
|
||||||
|
let sequelize
|
||||||
|
if (config.use_env_variable) {
|
||||||
|
sequelize = new Sequelize(process.env[config.use_env_variable], config)
|
||||||
|
} else {
|
||||||
|
sequelize = new Sequelize(config.database, config.username, config.password, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
fs
|
||||||
|
.readdirSync(__dirname)
|
||||||
|
.filter(file => {
|
||||||
|
return (
|
||||||
|
file.indexOf('.') !== 0 &&
|
||||||
|
file !== basename &&
|
||||||
|
file.slice(-3) === '.js' &&
|
||||||
|
file.indexOf('.test.js') === -1
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.forEach(file => {
|
||||||
|
const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes)
|
||||||
|
db[model.name] = model
|
||||||
|
})
|
||||||
|
|
||||||
|
Object.keys(db).forEach(modelName => {
|
||||||
|
if (db[modelName].associate) {
|
||||||
|
db[modelName].associate(db)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
db.sequelize = sequelize
|
||||||
|
db.Sequelize = Sequelize
|
||||||
|
|
||||||
|
module.exports = db
|
||||||
49
src/database/models/init-models.js
Normal file
49
src/database/models/init-models.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
var DataTypes = require('sequelize').DataTypes
|
||||||
|
var _birthday = require('./birthday')
|
||||||
|
var _blacklist = require('./blacklist')
|
||||||
|
var _discorduser = require('./discorduser')
|
||||||
|
var _event = require('./event')
|
||||||
|
var _event_roles = require('./event_roles')
|
||||||
|
var _event_schedule = require('./event_schedule')
|
||||||
|
var _static = require('./static')
|
||||||
|
var _static_members = require('./static_members')
|
||||||
|
|
||||||
|
function initModels(sequelize) {
|
||||||
|
var birthday = _birthday(sequelize, DataTypes)
|
||||||
|
var blacklist = _blacklist(sequelize, DataTypes)
|
||||||
|
var discorduser = _discorduser(sequelize, DataTypes)
|
||||||
|
var event = _event(sequelize, DataTypes)
|
||||||
|
var event_roles = _event_roles(sequelize, DataTypes)
|
||||||
|
var event_schedule = _event_schedule(sequelize, DataTypes)
|
||||||
|
var static = _static(sequelize, DataTypes)
|
||||||
|
var static_members = _static_members(sequelize, DataTypes)
|
||||||
|
|
||||||
|
discorduser.belongsToMany(static, { as: 'static_id_statics', through: static_members, foreignKey: 'username', otherKey: 'static_id' })
|
||||||
|
static.belongsToMany(discorduser, { as: 'username_discordusers', through: static_members, foreignKey: 'static_id', otherKey: 'username' })
|
||||||
|
birthday.belongsTo(discorduser, { as: 'discorduser_discorduser', foreignKey: 'discorduser'})
|
||||||
|
discorduser.hasMany(birthday, { as: 'birthdays', foreignKey: 'discorduser'})
|
||||||
|
blacklist.belongsTo(discorduser, { as: 'reportedby_discorduser', foreignKey: 'reportedby'})
|
||||||
|
discorduser.hasMany(blacklist, { as: 'blacklists', foreignKey: 'reportedby'})
|
||||||
|
static_members.belongsTo(discorduser, { as: 'username_discorduser', foreignKey: 'username'})
|
||||||
|
discorduser.hasMany(static_members, { as: 'static_members', foreignKey: 'username'})
|
||||||
|
event_roles.belongsTo(event, { as: 'event', foreignKey: 'event_id'})
|
||||||
|
event.hasMany(event_roles, { as: 'event_roles', foreignKey: 'event_id'})
|
||||||
|
event_schedule.belongsTo(event, { as: 'event', foreignKey: 'event_id'})
|
||||||
|
event.hasMany(event_schedule, { as: 'event_schedules', foreignKey: 'event_id'})
|
||||||
|
static_members.belongsTo(static, { as: 'static', foreignKey: 'static_id'})
|
||||||
|
static.hasMany(static_members, { as: 'static_members', foreignKey: 'static_id'})
|
||||||
|
|
||||||
|
return {
|
||||||
|
birthday,
|
||||||
|
blacklist,
|
||||||
|
discorduser,
|
||||||
|
event,
|
||||||
|
event_roles,
|
||||||
|
event_schedule,
|
||||||
|
static,
|
||||||
|
static_members,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.exports = initModels
|
||||||
|
module.exports.initModels = initModels
|
||||||
|
module.exports.default = initModels
|
||||||
49
src/database/models/static.js
Normal file
49
src/database/models/static.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
const Sequelize = require('sequelize')
|
||||||
|
module.exports = function(sequelize, DataTypes) {
|
||||||
|
return sequelize.define('static', {
|
||||||
|
id: {
|
||||||
|
autoIncrement: true,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: false,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: DataTypes.STRING(12),
|
||||||
|
allowNull: false,
|
||||||
|
unique: 'unique_name',
|
||||||
|
},
|
||||||
|
creator: {
|
||||||
|
type: DataTypes.STRING(255),
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
sequelize,
|
||||||
|
tableName: 'static',
|
||||||
|
schema: 'public',
|
||||||
|
timestamps: false,
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'static_pkey',
|
||||||
|
unique: true,
|
||||||
|
fields: [
|
||||||
|
{ name: 'id' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'unique_name',
|
||||||
|
unique: true,
|
||||||
|
fields: [
|
||||||
|
{ name: 'name' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
38
src/database/models/static_members.js
Normal file
38
src/database/models/static_members.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
const Sequelize = require('sequelize')
|
||||||
|
module.exports = function(sequelize, DataTypes) {
|
||||||
|
return sequelize.define('static_members', {
|
||||||
|
static_id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: false,
|
||||||
|
primaryKey: true,
|
||||||
|
references: {
|
||||||
|
model: 'static',
|
||||||
|
key: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
username: {
|
||||||
|
type: DataTypes.STRING(100),
|
||||||
|
allowNull: false,
|
||||||
|
primaryKey: true,
|
||||||
|
references: {
|
||||||
|
model: 'discorduser',
|
||||||
|
key: 'name',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
sequelize,
|
||||||
|
tableName: 'static_members',
|
||||||
|
schema: 'public',
|
||||||
|
timestamps: false,
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'static_members_pkey',
|
||||||
|
unique: true,
|
||||||
|
fields: [
|
||||||
|
{ name: 'static_id' },
|
||||||
|
{ name: 'username' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,61 +1,81 @@
|
|||||||
const { getClient } = require('./database')
|
const {
|
||||||
|
static: Static,
|
||||||
|
static_members: StaticMembers,
|
||||||
|
discorduser: DiscordUser,
|
||||||
|
} = require('./models')
|
||||||
|
|
||||||
const CreateStatic = async (name, creator, members, size) => {
|
const CreateStatic = async (name, creator, members, size) => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
const staticEntry = await Static.create({
|
||||||
|
name,
|
||||||
|
creator,
|
||||||
|
size,
|
||||||
|
})
|
||||||
|
|
||||||
const result = await client.query(
|
const staticId = staticEntry.id
|
||||||
"INSERT INTO static (name, creator, size) VALUES ($1, $2, $3) RETURNING id",
|
|
||||||
[name, creator, size]
|
|
||||||
)
|
|
||||||
|
|
||||||
const staticId = result.rows[0].id
|
await Promise.all(
|
||||||
|
members.map(async member => {
|
||||||
|
const [user] = await DiscordUser.findOrCreate({
|
||||||
|
where: {
|
||||||
|
name: member,
|
||||||
|
},
|
||||||
|
defaults: {
|
||||||
|
name: member,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
for (const member of members) {
|
await StaticMembers.create({
|
||||||
await client.query(
|
static_id: staticId,
|
||||||
"INSERT INTO static_members (static_id, member) VALUES ($1, $2)",
|
member: user.name,
|
||||||
[staticId, member]
|
})
|
||||||
)
|
})
|
||||||
}
|
)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error creating static entry:', error)
|
console.error('Error creating static entry:', error)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ReadStatic = async (name) => {
|
const ReadStatic = async (name) => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
const staticEntry = await Static.findOne({
|
||||||
|
where: { name },
|
||||||
const res = await client.query(
|
})
|
||||||
"SELECT * FROM static WHERE name = $1",
|
return staticEntry || false
|
||||||
[name]
|
} catch (error) {
|
||||||
)
|
console.error('Error reading static entry:', error)
|
||||||
return res.rows
|
return false
|
||||||
} catch (error) {
|
}
|
||||||
console.error('Error reading static entry:', error)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DeleteStatic = async (name) => {
|
const DeleteStatic = async (name) => {
|
||||||
try {
|
try {
|
||||||
const client = getClient()
|
const staticEntry = await Static.findOne({
|
||||||
|
where: { name },
|
||||||
|
})
|
||||||
|
|
||||||
await client.query(
|
if (!staticEntry) return false
|
||||||
"DELETE FROM static WHERE name = $1",
|
|
||||||
[name]
|
await StaticMembers.destroy({
|
||||||
)
|
where: {
|
||||||
} catch (error) {
|
static_id: staticEntry.id,
|
||||||
console.error('Error deleting static entry:', error)
|
},
|
||||||
return false
|
})
|
||||||
}
|
|
||||||
|
await staticEntry.destroy()
|
||||||
|
|
||||||
|
return true
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error deleting static entry:', error)
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
CreateStatic,
|
CreateStatic,
|
||||||
ReadStatic,
|
ReadStatic,
|
||||||
DeleteStatic,
|
DeleteStatic,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,23 +3,23 @@ require('dotenv').config()
|
|||||||
const { REST } = require('@discordjs/rest')
|
const { REST } = require('@discordjs/rest')
|
||||||
const { SlashCommandBuilder } = require('@discordjs/builders')
|
const { SlashCommandBuilder } = require('@discordjs/builders')
|
||||||
const {
|
const {
|
||||||
initReactionPerRole,
|
initReactionPerRole,
|
||||||
messageReactionAdd,
|
messageReactionAdd,
|
||||||
messageReactionRemove,
|
messageReactionRemove,
|
||||||
} = require('../features/reactionPerRole')
|
} = require('../features/reactionPerRole')
|
||||||
|
|
||||||
const {
|
const {
|
||||||
handleBlacklistAdd,
|
handleBlacklistAdd,
|
||||||
handleBlacklistCheck,
|
handleBlacklistCheck,
|
||||||
handleBlacklistShow,
|
handleBlacklistShow,
|
||||||
updateGlobalMessage,
|
updateGlobalMessage,
|
||||||
} = require('../features/blacklist')
|
} = require('../features/blacklist')
|
||||||
|
|
||||||
const {
|
const {
|
||||||
handleBirthdayAdd,
|
handleBirthdayAdd,
|
||||||
handleBirthdayUpdate,
|
handleBirthdayUpdate,
|
||||||
handleBirthdayCheck,
|
handleBirthdayCheck,
|
||||||
handleBirthdayDelete,
|
handleBirthdayDelete,
|
||||||
} = require('../features/birthday')
|
} = require('../features/birthday')
|
||||||
|
|
||||||
const { startBirthdayCheckCron } = require('../tasks/checkBirthday')
|
const { startBirthdayCheckCron } = require('../tasks/checkBirthday')
|
||||||
@@ -28,179 +28,179 @@ const { startEventCheckCron } = require('../tasks/eventReminder')
|
|||||||
const rest = new REST({ version: '10' }).setToken(process.env.BOT_TOKEN)
|
const rest = new REST({ version: '10' }).setToken(process.env.BOT_TOKEN)
|
||||||
|
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
intents: [
|
intents: [
|
||||||
GatewayIntentBits.Guilds,
|
GatewayIntentBits.Guilds,
|
||||||
GatewayIntentBits.GuildMessages,
|
GatewayIntentBits.GuildMessages,
|
||||||
GatewayIntentBits.GuildMembers,
|
GatewayIntentBits.GuildMembers,
|
||||||
GatewayIntentBits.MessageContent,
|
GatewayIntentBits.MessageContent,
|
||||||
GatewayIntentBits.GuildMessageReactions,
|
GatewayIntentBits.GuildMessageReactions,
|
||||||
],
|
],
|
||||||
partials: [
|
partials: [
|
||||||
Partials.Channel,
|
Partials.Channel,
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on('interactionCreate', async interaction => {
|
client.on('interactionCreate', async interaction => {
|
||||||
if (!interaction.isCommand()) return
|
if (!interaction.isCommand()) return
|
||||||
|
|
||||||
switch (interaction.commandName) {
|
switch (interaction.commandName) {
|
||||||
case 'blacklist':
|
case 'blacklist':
|
||||||
const reportedUser = interaction.options.getString('player')
|
const reportedUser = interaction.options.getString('player')
|
||||||
const reason = interaction.options.getString('reason')
|
const reason = interaction.options.getString('reason')
|
||||||
const reportedByUser = interaction.user.username
|
const reportedByUser = interaction.user.username
|
||||||
|
|
||||||
const res = await handleBlacklistAdd(reportedUser, reason, reportedByUser)
|
const res = await handleBlacklistAdd(reportedUser, reason, reportedByUser)
|
||||||
if (res) {
|
if (res) {
|
||||||
if (res.name === reportedUser)
|
if (res.name === reportedUser)
|
||||||
interaction.reply({ content: `This user has already been reported`, ephemeral: true })
|
interaction.reply({ content: 'This user has already been reported', ephemeral: true })
|
||||||
else {
|
else {
|
||||||
interaction.reply({ content: `Player ** ${reportedUser}** had been successfully reported for ${reason}`, ephemeral: true })
|
interaction.reply({ content: `Player ** ${reportedUser}** had been successfully reported for ${reason}`, ephemeral: true })
|
||||||
updateGlobalMessage(interaction)
|
updateGlobalMessage(interaction)
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
interaction.reply({ content: `ERROR trying to add the player to the blacklist, please contact @Crylia`, ephemeral: true })
|
interaction.reply({ content: 'ERROR trying to add the player to the blacklist, please contact @Crylia', ephemeral: true })
|
||||||
|
|
||||||
break
|
break
|
||||||
case 'blacklist-check-player':
|
case 'blacklist-check-player':
|
||||||
const player = interaction.options.getString('player')
|
const player = interaction.options.getString('player')
|
||||||
|
|
||||||
const reason2 = await handleBlacklistCheck(player)
|
const reason2 = await handleBlacklistCheck(player)
|
||||||
reason2 ?
|
reason2 ?
|
||||||
await interaction.reply({ content: `** ${reason2.name}** is blacklisted for: ** ${reason2.reason || 'No reason provided.'}**`, ephemeral: true }) :
|
await interaction.reply({ content: `** ${reason2.name}** is blacklisted for: ** ${reason2.reason || 'No reason provided.'}**`, ephemeral: true }) :
|
||||||
await interaction.reply({ content: `** ${player}** is not blacklisted.`, ephemeral: true })
|
await interaction.reply({ content: `** ${player}** is not blacklisted.`, ephemeral: true })
|
||||||
|
|
||||||
break
|
break
|
||||||
case 'birthday':
|
case 'birthday':
|
||||||
const user = interaction.user.username
|
const user = interaction.user.username
|
||||||
const birthday = interaction.options.getString('birthday')
|
const birthday = interaction.options.getString('birthday')
|
||||||
|
|
||||||
// Matches format xx.xx.xxxx, later dd.mm.yyyy
|
// Matches format xx.xx.xxxx, later dd.mm.yyyy
|
||||||
const match = birthday.match(/^(\d{2})\.(\d{2})\.(\d{4})$/)
|
const match = birthday.match(/^(\d{2})\.(\d{2})\.(\d{4})$/)
|
||||||
if (!match) {
|
if (!match) {
|
||||||
await interaction.reply({ content: 'Invalid date format. Please use dd.mm.yyyy.', ephemeral: true })
|
await interaction.reply({ content: 'Invalid date format. Please use dd.mm.yyyy.', ephemeral: true })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const day = parseInt(match[1], 10)
|
const day = parseInt(match[1], 10)
|
||||||
const month = parseInt(match[2], 10)
|
const month = parseInt(match[2], 10)
|
||||||
const year = parseInt(match[3], 10)
|
const year = parseInt(match[3], 10)
|
||||||
|
|
||||||
// Validates dd.mm ae legit, year doesnt matter for the birthday
|
// Validates dd.mm ae legit, year doesnt matter for the birthday
|
||||||
const isValidDate = (day, month, year) => {
|
const isValidDate = (day, month, year) => {
|
||||||
if (month < 1 || month > 12) return false
|
if (month < 1 || month > 12) return false
|
||||||
|
|
||||||
const daysInMonth = [31, ((year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
const daysInMonth = [31, ((year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
||||||
return day > 0 && day <= daysInMonth[month - 1]
|
return day > 0 && day <= daysInMonth[month - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidDate(day, month, year)) {
|
if (!isValidDate(day, month, year)) {
|
||||||
await interaction.reply({ content: 'Invalid date. Please enter a valid birthday as dd.mm.yyyy.', ephemeral: true })
|
await interaction.reply({ content: 'Invalid date. Please enter a valid birthday as dd.mm.yyyy.', ephemeral: true })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await handleBirthdayCheck(user, birthday).length > 0 ?
|
await handleBirthdayCheck(user, birthday).length > 0 ?
|
||||||
await handleBirthdayUpdate(user, birthday) :
|
await handleBirthdayUpdate(user, birthday) :
|
||||||
handleBirthdayAdd(user, birthday) ?
|
handleBirthdayAdd(user, birthday) ?
|
||||||
await interaction.reply({ content: `Set ${birthday} as your birthday.Everyone will be notified once the day arrives!`, ephemeral: true }) :
|
await interaction.reply({ content: `Set ${birthday} as your birthday.Everyone will be notified once the day arrives!`, ephemeral: true }) :
|
||||||
await interaction.reply({ content: `Something went wrong when setting / updating your birthday, please contact @crylia`, ephemeral: true })
|
await interaction.reply({ content: 'Something went wrong when setting / updating your birthday, please contact @crylia', ephemeral: true })
|
||||||
break
|
break
|
||||||
case 'birthday-check':
|
case 'birthday-check':
|
||||||
const birthdayCheck = await handleBirthdayCheck(interaction.user.username)
|
const birthdayCheck = await handleBirthdayCheck(interaction.user.username)
|
||||||
birthdayCheck ?
|
birthdayCheck ?
|
||||||
await interaction.reply({ content: `Your birthday is currently set to ${new Date(birthdayCheck[0].date).toLocaleDateString('de-DE')}.`, ephemeral: true }) :
|
await interaction.reply({ content: `Your birthday is currently set to ${new Date(birthdayCheck[0].date).toLocaleDateString('de-DE')}.`, ephemeral: true }) :
|
||||||
await interaction.reply({ content: "You don't have a birthday set. Use the`birthday` command to set one.", ephemeral: true })
|
await interaction.reply({ content: 'You don\'t have a birthday set. Use the`birthday` command to set one.', ephemeral: true })
|
||||||
break
|
break
|
||||||
case 'birthday-delete':
|
case 'birthday-delete':
|
||||||
await handleBirthdayDelete(interaction.user.username) ?
|
await handleBirthdayDelete(interaction.user.username) ?
|
||||||
await interaction.reply({ content: "Your birthday has been deleted.", ephemeral: true }) :
|
await interaction.reply({ content: 'Your birthday has been deleted.', ephemeral: true }) :
|
||||||
await interaction.reply({ content: "You don't have a birthday set.", ephemeral: true })
|
await interaction.reply({ content: 'You don\'t have a birthday set.', ephemeral: true })
|
||||||
break
|
break
|
||||||
case 'static-create':
|
case 'static-create':
|
||||||
|
|
||||||
break
|
break
|
||||||
case 'static-delete':
|
case 'static-delete':
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'static-show':
|
case 'static-show':
|
||||||
|
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on('messageReactionAdd', async (reaction, user) => {
|
client.on('messageReactionAdd', async (reaction, user) => {
|
||||||
messageReactionAdd(user, reaction)
|
messageReactionAdd(user, reaction)
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on('messageReactionRemove', async (reaction, user) => {
|
client.on('messageReactionRemove', async (reaction, user) => {
|
||||||
messageReactionRemove(user, reaction)
|
messageReactionRemove(user, reaction)
|
||||||
})
|
})
|
||||||
|
|
||||||
client.once('ready', async () => {
|
client.once('ready', async () => {
|
||||||
console.log(`Logged in as ${client.user.tag} `)
|
console.log(`Logged in as ${client.user.tag} `)
|
||||||
startBirthdayCheckCron(client)
|
startBirthdayCheckCron(client)
|
||||||
startEventCheckCron(client)
|
startEventCheckCron(client)
|
||||||
updateGlobalMessage(client)
|
updateGlobalMessage(client)
|
||||||
initReactionPerRole(client)
|
initReactionPerRole(client)
|
||||||
})
|
})
|
||||||
|
|
||||||
const connectDiscord = async () => {
|
const connectDiscord = async () => {
|
||||||
try {
|
try {
|
||||||
console.log('Started refreshing application (/) commands.')
|
console.log('Started refreshing application (/) commands.')
|
||||||
|
|
||||||
const commands = [
|
const commands = [
|
||||||
new SlashCommandBuilder()
|
new SlashCommandBuilder()
|
||||||
.setName('birthday')
|
.setName('birthday')
|
||||||
.setDescription('Set yourself a birthday')
|
.setDescription('Set yourself a birthday')
|
||||||
.addStringOption(option =>
|
.addStringOption(option =>
|
||||||
option.setName('birthday')
|
option.setName('birthday')
|
||||||
.setDescription('Set (or overwrite) your birthday as dd.mm.yyyy (e.g. 01.12.1999)')
|
.setDescription('Set (or overwrite) your birthday as dd.mm.yyyy (e.g. 01.12.1999)')
|
||||||
.setRequired(true)
|
.setRequired(true)
|
||||||
),
|
),
|
||||||
new SlashCommandBuilder()
|
new SlashCommandBuilder()
|
||||||
.setName('birthday-check')
|
.setName('birthday-check')
|
||||||
.setDescription('Check your set birthday (only you will see the date)'),
|
.setDescription('Check your set birthday (only you will see the date)'),
|
||||||
new SlashCommandBuilder()
|
new SlashCommandBuilder()
|
||||||
.setName('birthday-delete')
|
.setName('birthday-delete')
|
||||||
.setDescription('Delete your birthday, nobody will know when your birthday arrives :('),
|
.setDescription('Delete your birthday, nobody will know when your birthday arrives :('),
|
||||||
new SlashCommandBuilder()
|
new SlashCommandBuilder()
|
||||||
.setName('blacklist')
|
.setName('blacklist')
|
||||||
.setDescription('Add a player to a blacklist with a reason')
|
.setDescription('Add a player to a blacklist with a reason')
|
||||||
.addStringOption(option =>
|
.addStringOption(option =>
|
||||||
option.setName('player')
|
option.setName('player')
|
||||||
.setDescription('The in-game name of the player')
|
.setDescription('The in-game name of the player')
|
||||||
.setRequired(true)
|
.setRequired(true)
|
||||||
)
|
)
|
||||||
.addStringOption(option =>
|
.addStringOption(option =>
|
||||||
option.setName('reason')
|
option.setName('reason')
|
||||||
.setDescription('Explain what happened, why should this player be blacklisted')
|
.setDescription('Explain what happened, why should this player be blacklisted')
|
||||||
.setRequired(true)
|
.setRequired(true)
|
||||||
),
|
),
|
||||||
new SlashCommandBuilder()
|
new SlashCommandBuilder()
|
||||||
.setName('blacklist-check-player')
|
.setName('blacklist-check-player')
|
||||||
.setDescription('Check if a player is blacklisted')
|
.setDescription('Check if a player is blacklisted')
|
||||||
.addStringOption(option =>
|
.addStringOption(option =>
|
||||||
option.setName('player')
|
option.setName('player')
|
||||||
.setDescription('The in-game name of the player')
|
.setDescription('The in-game name of the player')
|
||||||
.setRequired(true)
|
.setRequired(true)
|
||||||
)
|
),
|
||||||
].map(command => command.toJSON())
|
].map(command => command.toJSON())
|
||||||
|
|
||||||
await rest.put(
|
await rest.put(
|
||||||
Routes.applicationCommands(process.env.CLIENT_ID),
|
Routes.applicationCommands(process.env.CLIENT_ID),
|
||||||
{ body: commands },
|
{ body: commands }
|
||||||
)
|
)
|
||||||
console.log('Successfully reloaded application (/) commands.')
|
console.log('Successfully reloaded application (/) commands.')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
client.login(process.env.BOT_TOKEN)
|
client.login(process.env.BOT_TOKEN)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error logging in to Discord:', error)
|
console.error('Error logging in to Discord:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { client, connectDiscord }
|
module.exports = { client, connectDiscord }
|
||||||
|
|||||||
@@ -1,43 +1,43 @@
|
|||||||
const { CreateBirthday, ReadBirthday, UpdateBirthday, DeleteBirthday } = require('../database/birthdaydb')
|
const { CreateBirthday, ReadBirthday, UpdateBirthday, DeleteBirthday } = require('../database/birthdaydb')
|
||||||
|
|
||||||
const handleBirthdayAdd = async (user, birthday) => {
|
const handleBirthdayAdd = async (user, birthday) => {
|
||||||
if (!user || !birthday) return false
|
if (!user || !birthday) return false
|
||||||
|
|
||||||
const result = await CreateBirthday(user, birthday)
|
const result = await CreateBirthday(user, birthday)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBirthdayCheck = async (user) => {
|
const handleBirthdayCheck = async (user) => {
|
||||||
if (!user) return false
|
if (!user) return false
|
||||||
|
|
||||||
const result = await ReadBirthday(user)
|
const result = await ReadBirthday(user)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBirthdayDelete = async (user) => {
|
const handleBirthdayDelete = async (user) => {
|
||||||
if (!user) return false
|
if (!user) return false
|
||||||
|
|
||||||
const result = await DeleteBirthday(user)
|
const result = await DeleteBirthday(user)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBirthdayUpdate = async (user, birthday) => {
|
const handleBirthdayUpdate = async (user, birthday) => {
|
||||||
if (!user || !birthday) return false
|
if (!user || !birthday) return false
|
||||||
|
|
||||||
const result = await UpdateBirthday(user, birthday)
|
const result = await UpdateBirthday(user, birthday)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBirthdayGetAll = async () => await ReadBirthday()
|
const handleBirthdayGetAll = async () => await ReadBirthday()
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
handleBirthdayAdd,
|
handleBirthdayAdd,
|
||||||
handleBirthdayCheck,
|
handleBirthdayCheck,
|
||||||
handleBirthdayDelete,
|
handleBirthdayDelete,
|
||||||
handleBirthdayUpdate,
|
handleBirthdayUpdate,
|
||||||
handleBirthdayGetAll,
|
handleBirthdayGetAll,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,104 +2,104 @@ const { CreateBlacklist, ReadBlacklist, UpdateBlacklist, DeleteBlacklist } = req
|
|||||||
const { EmbedBuilder } = require('discord.js')
|
const { EmbedBuilder } = require('discord.js')
|
||||||
|
|
||||||
const handleBlacklistAdd = async (reportedUser, reason, reportedByUser) => {
|
const handleBlacklistAdd = async (reportedUser, reason, reportedByUser) => {
|
||||||
if (!reportedUser || !reason || !reportedByUser) return false
|
if (!reportedUser || !reason || !reportedByUser) return false
|
||||||
|
|
||||||
const result = await CreateBlacklist(reportedUser, reason, reportedByUser)
|
const result = await CreateBlacklist(reportedUser, reason, reportedByUser)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBlacklistCheck = async (user) => {
|
const handleBlacklistCheck = async (user) => {
|
||||||
if (!user) return false
|
if (!user) return false
|
||||||
|
|
||||||
const result = await ReadBlacklist(user)
|
const result = await ReadBlacklist(user)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBlacklistShow = async () => await ReadBlacklist()
|
const handleBlacklistShow = async () => await ReadBlacklist()
|
||||||
|
|
||||||
const createBlacklistEmbeds = (playerEntries, maxChars = 30) => {
|
const createBlacklistEmbeds = (playerEntries, maxChars = 30) => {
|
||||||
const embeds = []
|
const embeds = []
|
||||||
let embed = new EmbedBuilder()
|
let embed = new EmbedBuilder()
|
||||||
.setColor('#0099ff')
|
.setColor('#0099ff')
|
||||||
.setTitle('Blacklist (Page 1)')
|
.setTitle('Blacklist (Page 1)')
|
||||||
.setDescription('Players who have been blacklisted and the reasons.')
|
.setDescription('Players who have been blacklisted and the reasons.')
|
||||||
|
|
||||||
let fieldCount = 0
|
let fieldCount = 0
|
||||||
let pageIndex = 1
|
let pageIndex = 1
|
||||||
|
|
||||||
playerEntries.forEach(([playerName, reason]) => {
|
playerEntries.forEach(([playerName, reason]) => {
|
||||||
let splitReason = []
|
let splitReason = []
|
||||||
while (reason.length > maxChars) {
|
while (reason.length > maxChars) {
|
||||||
let splitIndex = reason.lastIndexOf(' ', maxChars)
|
let splitIndex = reason.lastIndexOf(' ', maxChars)
|
||||||
if (splitIndex === -1) splitIndex = maxChars
|
if (splitIndex === -1) splitIndex = maxChars
|
||||||
splitReason.push(reason.substring(0, splitIndex))
|
splitReason.push(reason.substring(0, splitIndex))
|
||||||
reason = reason.substring(splitIndex + 1)
|
reason = reason.substring(splitIndex + 1)
|
||||||
}
|
}
|
||||||
splitReason.push(reason)
|
splitReason.push(reason)
|
||||||
|
|
||||||
const nameField = playerName || '\u200B'
|
const nameField = playerName || '\u200B'
|
||||||
const valueField = splitReason.join('\n').trim() || '\u200B'
|
const valueField = splitReason.join('\n').trim() || '\u200B'
|
||||||
|
|
||||||
if (valueField !== '\u200B') {
|
if (valueField !== '\u200B') {
|
||||||
embed.addFields({ name: nameField, value: valueField, inline: true })
|
embed.addFields({ name: nameField, value: valueField, inline: true })
|
||||||
fieldCount++
|
fieldCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldCount >= 25) {
|
if (fieldCount >= 25) {
|
||||||
embeds.push(embed)
|
embeds.push(embed)
|
||||||
pageIndex++
|
pageIndex++
|
||||||
embed = new EmbedBuilder()
|
embed = new EmbedBuilder()
|
||||||
.setColor('#0099ff')
|
.setColor('#0099ff')
|
||||||
.setTitle(`Blacklist (Page ${pageIndex})`)
|
.setTitle(`Blacklist (Page ${pageIndex})`)
|
||||||
.setDescription('Players who have been blacklisted and the reasons.')
|
.setDescription('Players who have been blacklisted and the reasons.')
|
||||||
fieldCount = 0
|
fieldCount = 0
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (fieldCount > 0) {
|
if (fieldCount > 0) {
|
||||||
embeds.push(embed)
|
embeds.push(embed)
|
||||||
}
|
}
|
||||||
|
|
||||||
return embeds
|
return embeds
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateGlobalMessage = async (client) => {
|
const updateGlobalMessage = async (client) => {
|
||||||
try {
|
try {
|
||||||
let targetChannel = null
|
let targetChannel = null
|
||||||
|
|
||||||
for (const [_, oauthGuild] of await client.guilds.fetch()) {
|
for (const [_, oauthGuild] of await client.guilds.fetch()) {
|
||||||
targetChannel = (await (await oauthGuild.fetch()).channels.fetch()).find(ch => ch.name === 'blacklist')
|
targetChannel = (await (await oauthGuild.fetch()).channels.fetch()).find(ch => ch.name === 'blacklist')
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!targetChannel) {
|
if (!targetChannel) {
|
||||||
console.error('Channel with name "blacklist" not found.')
|
console.error('Channel with name "blacklist" not found.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const messages = await targetChannel.messages.fetch({ limit: 100 })
|
const messages = await targetChannel.messages.fetch({ limit: 100 })
|
||||||
await Promise.all(messages.map(msg => msg.delete()))
|
await Promise.all(messages.map(msg => msg.delete()))
|
||||||
|
|
||||||
const blacklistEntries = await handleBlacklistShow()
|
const blacklistEntries = await handleBlacklistShow()
|
||||||
|
|
||||||
const playerEntries = blacklistEntries.map(entry => [entry.name, entry.reason])
|
const playerEntries = blacklistEntries.map(entry => [entry.name, entry.reason])
|
||||||
|
|
||||||
const embeds = createBlacklistEmbeds(playerEntries)
|
const embeds = createBlacklistEmbeds(playerEntries)
|
||||||
|
|
||||||
for (const embed of embeds)
|
for (const embed of embeds)
|
||||||
await targetChannel.send({ embeds: [embed] })
|
await targetChannel.send({ embeds: [embed] })
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error updating global message:', error)
|
console.error('Error updating global message:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
handleBlacklistAdd,
|
handleBlacklistAdd,
|
||||||
handleBlacklistCheck,
|
handleBlacklistCheck,
|
||||||
handleBlacklistShow,
|
handleBlacklistShow,
|
||||||
updateGlobalMessage,
|
updateGlobalMessage,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,206 +1,206 @@
|
|||||||
const { GetIconRole } = require('../database/eventdb')
|
const { GetIconRole } = require('../database/eventdb')
|
||||||
const cron = require('node-cron');
|
const cron = require('node-cron')
|
||||||
|
|
||||||
let reminderMessageID = null
|
let reminderMessageID = null
|
||||||
let rolesMap = new Map()
|
let rolesMap = new Map()
|
||||||
|
|
||||||
const areMapsEqual = (map1, map2) => {
|
const areMapsEqual = (map1, map2) => {
|
||||||
if (map1.size !== map2.size) return false
|
if (map1.size !== map2.size) return false
|
||||||
|
|
||||||
for (const [key, value] of map1)
|
for (const [key, value] of map1)
|
||||||
if (map2.get(key) !== value) return false
|
if (map2.get(key) !== value) return false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const editReactionMessage = async (client) => {
|
const editReactionMessage = async (client) => {
|
||||||
try {
|
try {
|
||||||
for (const [_, oauthGuild] of await client.guilds.fetch()) {
|
for (const [_, oauthGuild] of await client.guilds.fetch()) {
|
||||||
const guild = await oauthGuild.fetch()
|
const guild = await oauthGuild.fetch()
|
||||||
const rolesChannel = (await guild.channels.fetch()).find(ch => ch.name === 'roles')
|
const rolesChannel = (await guild.channels.fetch()).find(ch => ch.name === 'roles')
|
||||||
|
|
||||||
if (!rolesChannel) {
|
if (!rolesChannel) {
|
||||||
console.log("Channel not found")
|
console.log('Channel not found')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const message = await rolesChannel.messages.fetch(reminderMessageID)
|
const message = await rolesChannel.messages.fetch(reminderMessageID)
|
||||||
|
|
||||||
const newRolesFromDB = await GetIconRole()
|
const newRolesFromDB = await GetIconRole()
|
||||||
|
|
||||||
if (areMapsEqual(rolesMap, newRolesFromDB)) {
|
if (areMapsEqual(rolesMap, newRolesFromDB)) {
|
||||||
console.log(`No changes to the roles, quitting`)
|
console.log('No changes to the roles, quitting')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rolesMap = newRolesFromDB
|
rolesMap = newRolesFromDB
|
||||||
|
|
||||||
const currentLines = message.content.split('\n').slice(1)
|
const currentLines = message.content.split('\n').slice(1)
|
||||||
|
|
||||||
const currentRoleMap = new Map()
|
const currentRoleMap = new Map()
|
||||||
currentLines.forEach(line => {
|
currentLines.forEach(line => {
|
||||||
if (!line.trim()) return
|
if (!line.trim()) return
|
||||||
const [icon, roleName] = line.split(': ')
|
const [icon, roleName] = line.split(': ')
|
||||||
const iconName = icon.match(/<:(\w+):\d+>/)[1]
|
const iconName = icon.match(/<:(\w+):\d+>/)[1]
|
||||||
currentRoleMap.set(iconName, roleName.replace(/`/g, ''))
|
currentRoleMap.set(iconName, roleName.replace(/`/g, ''))
|
||||||
})
|
})
|
||||||
|
|
||||||
const rolesToAdd = [], rolesToRemove = []
|
const rolesToAdd = [], rolesToRemove = []
|
||||||
|
|
||||||
for (const [iconName, roleName] of rolesMap)
|
for (const [iconName, roleName] of rolesMap)
|
||||||
if (!currentRoleMap.has(iconName))
|
if (!currentRoleMap.has(iconName))
|
||||||
rolesToAdd.push({ icon: iconName, name: roleName })
|
rolesToAdd.push({ icon: iconName, name: roleName })
|
||||||
|
|
||||||
for (const [iconName, roleName] of currentRoleMap)
|
for (const [iconName, roleName] of currentRoleMap)
|
||||||
if (!rolesMap.has(iconName))
|
if (!rolesMap.has(iconName))
|
||||||
rolesToRemove.push({ icon: iconName, name: roleName })
|
rolesToRemove.push({ icon: iconName, name: roleName })
|
||||||
|
|
||||||
const emojis = await guild.emojis.fetch()
|
const emojis = await guild.emojis.fetch()
|
||||||
|
|
||||||
let updatedContent = 'React to get your roles!\n\n'
|
let updatedContent = 'React to get your roles!\n\n'
|
||||||
rolesMap.forEach((roleName, iconName) => {
|
rolesMap.forEach((roleName, iconName) => {
|
||||||
const emoji = emojis.find(e => e.name === iconName)
|
const emoji = emojis.find(e => e.name === iconName)
|
||||||
if (emoji)
|
if (emoji)
|
||||||
updatedContent += `${emoji}: \`${roleName}\`\n\n`
|
updatedContent += `${emoji}: \`${roleName}\`\n\n`
|
||||||
else
|
else
|
||||||
console.log(`Couldn't find emoji ${iconName}`)
|
console.log(`Couldn't find emoji ${iconName}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
await message.edit(updatedContent)
|
await message.edit(updatedContent)
|
||||||
|
|
||||||
for (const role of rolesToAdd) {
|
for (const role of rolesToAdd) {
|
||||||
const icon = emojis.find(e => e.name === role.icon)
|
const icon = emojis.find(e => e.name === role.icon)
|
||||||
if (icon)
|
if (icon)
|
||||||
await message.react(`${icon}`)
|
await message.react(`${icon}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const role of rolesToRemove) {
|
for (const role of rolesToRemove) {
|
||||||
const reaction = message.reactions.cache.find(r => r.emoji.name === role.icon)
|
const reaction = message.reactions.cache.find(r => r.emoji.name === role.icon)
|
||||||
if (!reaction) continue
|
if (!reaction) continue
|
||||||
|
|
||||||
await reaction.remove()
|
await reaction.remove()
|
||||||
|
|
||||||
const roleToRemove = message.guild.roles.cache.find(r => r.name === role.name)
|
const roleToRemove = message.guild.roles.cache.find(r => r.name === role.name)
|
||||||
if (!roleToRemove) continue
|
if (!roleToRemove) continue
|
||||||
|
|
||||||
const members = await message.guild.members.fetch();
|
const members = await message.guild.members.fetch()
|
||||||
const membersWithRole = members.filter(member => member.roles.cache.has(roleToRemove.id));
|
const membersWithRole = members.filter(member => member.roles.cache.has(roleToRemove.id))
|
||||||
|
|
||||||
for (const member of membersWithRole.values())
|
for (const member of membersWithRole.values())
|
||||||
await member.roles.remove(roleToRemove)
|
await member.roles.remove(roleToRemove)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const createReactionMessage = async (client) => {
|
const createReactionMessage = async (client) => {
|
||||||
try {
|
try {
|
||||||
for (const [_, oauthGuild] of await client.guilds.fetch()) {
|
for (const [_, oauthGuild] of await client.guilds.fetch()) {
|
||||||
const guild = await oauthGuild.fetch()
|
const guild = await oauthGuild.fetch()
|
||||||
const rolesChannel = (await guild.channels.fetch()).find(ch => ch.name === 'roles')
|
const rolesChannel = (await guild.channels.fetch()).find(ch => ch.name === 'roles')
|
||||||
|
|
||||||
if (!rolesChannel) {
|
if (!rolesChannel) {
|
||||||
console.log("Channel not found")
|
console.log('Channel not found')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchedMessage = await rolesChannel.messages.fetch({ limit: 1 })
|
const fetchedMessage = await rolesChannel.messages.fetch({ limit: 1 })
|
||||||
if (fetchedMessage.size > 0) {
|
if (fetchedMessage.size > 0) {
|
||||||
reminderMessageID = fetchedMessage.first().id
|
reminderMessageID = fetchedMessage.first().id
|
||||||
console.log('Reminder MessageID: ', reminderMessageID)
|
console.log('Reminder MessageID: ', reminderMessageID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const emojis = await guild.emojis.fetch()
|
const emojis = await guild.emojis.fetch()
|
||||||
|
|
||||||
let message = 'React to get your roles!\n\n'
|
let message = 'React to get your roles!\n\n'
|
||||||
for (const [iconName, roleName] of rolesMap) {
|
for (const [iconName, roleName] of rolesMap) {
|
||||||
const emoji = emojis.find(e => e.name === iconName)
|
const emoji = emojis.find(e => e.name === iconName)
|
||||||
if (emoji)
|
if (emoji)
|
||||||
message += `<:${emoji.name}:${emoji.id}> : \`${roleName}\`\n\n`
|
message += `<:${emoji.name}:${emoji.id}> : \`${roleName}\`\n\n`
|
||||||
else
|
else
|
||||||
console.log(`Emoji for ${iconName} not found`)
|
console.log(`Emoji for ${iconName} not found`)
|
||||||
}
|
}
|
||||||
const sentMessage = await rolesChannel.send(message)
|
const sentMessage = await rolesChannel.send(message)
|
||||||
|
|
||||||
for (const [iconName, _] of rolesMap) {
|
for (const [iconName, _] of rolesMap) {
|
||||||
const emoji = emojis.find(e => e.name === iconName)
|
const emoji = emojis.find(e => e.name === iconName)
|
||||||
if (emoji) await sentMessage.react(emoji.id)
|
if (emoji) await sentMessage.react(emoji.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
reminderMessageID = sentMessage.id
|
reminderMessageID = sentMessage.id
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageReactionAdd = async (user, reaction) => {
|
const messageReactionAdd = async (user, reaction) => {
|
||||||
if (user.id === '1280557738530963506') return
|
if (user.id === '1280557738530963506') return
|
||||||
|
|
||||||
const { message, emoji } = reaction
|
const { message, emoji } = reaction
|
||||||
const guild = message.guild
|
const guild = message.guild
|
||||||
const member = await guild.members.fetch(user.id)
|
const member = await guild.members.fetch(user.id)
|
||||||
if (!member) return
|
if (!member) return
|
||||||
|
|
||||||
if (message.id === reminderMessageID) {
|
if (message.id === reminderMessageID) {
|
||||||
const roleMap = await GetIconRole()
|
const roleMap = await GetIconRole()
|
||||||
|
|
||||||
const roleName = roleMap.get(emoji.name)
|
const roleName = roleMap.get(emoji.name)
|
||||||
if (roleName) {
|
if (roleName) {
|
||||||
try {
|
try {
|
||||||
const roles = await guild.roles.fetch()
|
const roles = await guild.roles.fetch()
|
||||||
const role = roles.find(r => r.name === roleName)
|
const role = roles.find(r => r.name === roleName)
|
||||||
|
|
||||||
if (role && !member.roles.cache.has(role.id))
|
if (role && !member.roles.cache.has(role.id))
|
||||||
await member.roles.add(role)
|
await member.roles.add(role)
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error fetching role for ${roleName}`, error)
|
console.error(`Error fetching role for ${roleName}`, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageReactionRemove = async (user, reaction) => {
|
const messageReactionRemove = async (user, reaction) => {
|
||||||
const { message, emoji } = reaction
|
const { message, emoji } = reaction
|
||||||
const guild = message.guild
|
const guild = message.guild
|
||||||
|
|
||||||
const member = await guild.members.fetch(user.id)
|
const member = await guild.members.fetch(user.id)
|
||||||
if (!member) return
|
if (!member) return
|
||||||
|
|
||||||
if (message.id === reminderMessageID) {
|
if (message.id === reminderMessageID) {
|
||||||
const roleMap = await GetIconRole()
|
const roleMap = await GetIconRole()
|
||||||
|
|
||||||
const roleName = roleMap.get(emoji.name)
|
const roleName = roleMap.get(emoji.name)
|
||||||
if (roleName) {
|
if (roleName) {
|
||||||
try {
|
try {
|
||||||
const roles = await guild.roles.fetch()
|
const roles = await guild.roles.fetch()
|
||||||
const role = roles.find(r => r.name === roleName)
|
const role = roles.find(r => r.name === roleName)
|
||||||
|
|
||||||
if (role && member.roles.cache.has(role.id))
|
if (role && member.roles.cache.has(role.id))
|
||||||
await member.roles.remove(role)
|
await member.roles.remove(role)
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error fetching role for ${roleName}`, error)
|
console.error(`Error fetching role for ${roleName}`, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const initReactionPerRole = async (client) => {
|
const initReactionPerRole = async (client) => {
|
||||||
rolesMap = await GetIconRole()
|
rolesMap = await GetIconRole()
|
||||||
|
|
||||||
await createReactionMessage(client)
|
await createReactionMessage(client)
|
||||||
|
|
||||||
cron.schedule('0 * * * *', async () => {
|
cron.schedule('0 * * * *', async () => {
|
||||||
await editReactionMessage(client)
|
await editReactionMessage(client)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
initReactionPerRole,
|
initReactionPerRole,
|
||||||
messageReactionAdd,
|
messageReactionAdd,
|
||||||
messageReactionRemove,
|
messageReactionRemove,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
const { CreateStatic, ReadStatic, DeleteStatic } = require('../database/staticdb')
|
const { CreateStatic, ReadStatic, DeleteStatic } = require('../database/staticdb')
|
||||||
|
|
||||||
const handleStaticAdd = async (name, creator, members, size) => {
|
const handleStaticAdd = async (name, creator, members, size) => {
|
||||||
if (!name || !createor || !members || !size) return false
|
if (!name || !createor || !members || !size) return false
|
||||||
|
|
||||||
const result = await CreateStatic(name, creator, members, size)
|
const result = await CreateStatic(name, creator, members, size)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleStaticGet = async (name) => {
|
const handleStaticGet = async (name) => {
|
||||||
if (!name) return false;
|
if (!name) return false
|
||||||
|
|
||||||
const result = await ReadStatic(name)
|
const result = await ReadStatic(name)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleStaticDelete = async (name) => {
|
const handleStaticDelete = async (name) => {
|
||||||
if (!name) return false
|
if (!name) return false
|
||||||
|
|
||||||
const result = await DeleteStatic(name)
|
const result = await DeleteStatic(name)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
handleStaticAdd,
|
handleStaticAdd,
|
||||||
handleStaticGet,
|
handleStaticGet,
|
||||||
handleStaticDelete,
|
handleStaticDelete,
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/index.js
19
src/index.js
@@ -1,16 +1,13 @@
|
|||||||
|
const { Sequelize } = require('sequelize')
|
||||||
const { connectDiscord } = require('./discord/discordClient')
|
const { connectDiscord } = require('./discord/discordClient')
|
||||||
const { connectDatabase, createClient } = require('./database/database');
|
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const client = createClient({
|
|
||||||
connectionString: `postgresql://${process.env.DB_USER}:${process.env.DB_PASS}@${process.env.DB_HOST}/${process.env.DB_NAME}`
|
connectDiscord()
|
||||||
})
|
|
||||||
connectDatabase(client).then(() => {
|
} catch (error) {
|
||||||
connectDiscord()
|
console.error('Error initializing application:', error)
|
||||||
})
|
}
|
||||||
} catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
})()
|
})()
|
||||||
|
|||||||
@@ -1,41 +1,41 @@
|
|||||||
const cron = require('node-cron');
|
const cron = require('node-cron')
|
||||||
const { handleBirthdayGetAll } = require('../features/birthday');
|
const { handleBirthdayGetAll } = require('../features/birthday')
|
||||||
|
|
||||||
const startBirthdayCheckCron = async (client) => {
|
const startBirthdayCheckCron = async (client) => {
|
||||||
cron.schedule('0 20 * * *', async () => {
|
cron.schedule('0 20 * * *', async () => {
|
||||||
try {
|
try {
|
||||||
console.log('Running birthday check...');
|
console.log('Running birthday check...')
|
||||||
|
|
||||||
for (const [guildId, oauthGuild] of await client.guilds.fetch()) {
|
for (const [guildId, oauthGuild] of await client.guilds.fetch()) {
|
||||||
const guild = await oauthGuild.fetch()
|
const guild = await oauthGuild.fetch()
|
||||||
const birthdayChannel = (await guild.channels.fetch()).find(ch => ch.name === 'main')
|
const birthdayChannel = (await guild.channels.fetch()).find(ch => ch.name === 'main')
|
||||||
|
|
||||||
if (!birthdayChannel) continue
|
if (!birthdayChannel) continue
|
||||||
|
|
||||||
const birthdays = await handleBirthdayGetAll();
|
const birthdays = await handleBirthdayGetAll()
|
||||||
console.log("birthdays:", birthdays)
|
console.log('birthdays:', birthdays)
|
||||||
if (birthdays.length < 1) continue
|
if (birthdays.length < 1) continue
|
||||||
|
|
||||||
let message = '🎉 **Today\'s Birthdays!** 🎉\n\n';
|
let message = '🎉 **Today\'s Birthdays!** 🎉\n\n'
|
||||||
for (const birthday of birthdays) {
|
for (const birthday of birthdays) {
|
||||||
const birthdayDate = new Date(birthday.date);
|
const birthdayDate = new Date(birthday.date)
|
||||||
if (birthdayDate.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' }) === new Date().toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' })) {
|
if (birthdayDate.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' }) === new Date().toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' })) {
|
||||||
(await guild.members.fetch()).forEach(user => {
|
(await guild.members.fetch()).forEach(user => {
|
||||||
if (user.user.username === birthday.discorduser) {
|
if (user.user.username === birthday.discorduser) {
|
||||||
message += `🎂 **Happy Birthday, <@${user.id}>!** 🎂\nWishing you a fantastic day filled with joy and surprises! 🎁🎈\n\n**Everyone, make sure to wish <@${user.id}> a wonderful birthday!** 🎊🎉\n\n`;
|
message += `🎂 **Happy Birthday, <@${user.id}>!** 🎂\nWishing you a fantastic day filled with joy and surprises! 🎁🎈\n\n**Everyone, make sure to wish <@${user.id}> a wonderful birthday!** 🎊🎉\n\n`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(message)
|
console.log(message)
|
||||||
if (message !== '🎉 **Today\'s Birthdays!** 🎉\n\n') {
|
if (message !== '🎉 **Today\'s Birthdays!** 🎉\n\n') {
|
||||||
await birthdayChannel.send(message);
|
await birthdayChannel.send(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error in scheduled birthday check:", error);
|
console.log('Error in scheduled birthday check:', error)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
module.exports = { startBirthdayCheckCron };
|
module.exports = { startBirthdayCheckCron }
|
||||||
|
|||||||
@@ -1,79 +1,79 @@
|
|||||||
const cron = require('node-cron');
|
const cron = require('node-cron')
|
||||||
const { ReadEvents, GetEventRole } = require('../database/eventdb')
|
const { ReadEvents, GetEventRole } = require('../database/eventdb')
|
||||||
const { EmbedBuilder } = require('discord.js')
|
const { EmbedBuilder } = require('discord.js')
|
||||||
|
|
||||||
let eventCache = []
|
let eventCache = []
|
||||||
|
|
||||||
const FetchEvents = async () => {
|
const FetchEvents = async () => {
|
||||||
const res = await ReadEvents()
|
const res = await ReadEvents()
|
||||||
|
|
||||||
eventCache = res
|
eventCache = res
|
||||||
}
|
}
|
||||||
|
|
||||||
const convertToISO = (time, date) => {
|
const convertToISO = (time, date) => {
|
||||||
const utcDate = new Date(`${date}T${time}`);
|
const utcDate = new Date(`${date}T${time}`)
|
||||||
utcDate.setHours(utcDate.getHours());
|
utcDate.setHours(utcDate.getHours())
|
||||||
return utcDate.toISOString().split('.')[0];
|
return utcDate.toISOString().split('.')[0]
|
||||||
};
|
}
|
||||||
|
|
||||||
const convertToUTC = (time) => {
|
const convertToUTC = (time) => {
|
||||||
const [hours, minutes, seconds] = time.split(':').map(Number);
|
const [hours, minutes, seconds] = time.split(':').map(Number)
|
||||||
const date = new Date();
|
const date = new Date()
|
||||||
date.setUTCHours(hours - 2, minutes, seconds);
|
date.setUTCHours(hours - 2, minutes, seconds)
|
||||||
return date.toISOString().split('.')[0];
|
return date.toISOString().split('.')[0]
|
||||||
};
|
}
|
||||||
|
|
||||||
const isReminderTime = (eventStartUTC) => {
|
const isReminderTime = (eventStartUTC) => {
|
||||||
const now = new Date();
|
const now = new Date()
|
||||||
const [eventHours, eventMinutes] = eventStartUTC.split('T')[1].split(':').map(Number);
|
const [eventHours, eventMinutes] = eventStartUTC.split('T')[1].split(':').map(Number)
|
||||||
const eventStartDateTime = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), eventHours, eventMinutes));
|
const eventStartDateTime = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), eventHours, eventMinutes))
|
||||||
const reminderTime = new Date(eventStartDateTime.getTime() - 15 * 60 * 1000);
|
const reminderTime = new Date(eventStartDateTime.getTime() - 15 * 60 * 1000)
|
||||||
console.log(now, reminderTime, eventStartDateTime)
|
console.log(now, reminderTime, eventStartDateTime)
|
||||||
return now >= reminderTime && now < eventStartDateTime;
|
return now >= reminderTime && now < eventStartDateTime
|
||||||
};
|
}
|
||||||
|
|
||||||
const getDayOfWeek = () => new Date(Date.UTC(new Date().getUTCFullYear(), new Date().getUTCMonth(), new Date().getUTCDate())).toLocaleDateString('en-US', { weekday: 'long' });
|
const getDayOfWeek = () => new Date(Date.UTC(new Date().getUTCFullYear(), new Date().getUTCMonth(), new Date().getUTCDate())).toLocaleDateString('en-US', { weekday: 'long' })
|
||||||
|
|
||||||
const startEventCheckCron = async (client) => {
|
const startEventCheckCron = async (client) => {
|
||||||
cron.schedule('45 * * * *', async () => {
|
cron.schedule('45 * * * *', async () => {
|
||||||
await FetchEvents()
|
await FetchEvents()
|
||||||
|
|
||||||
for (const [_, oauthGuild] of await client.guilds.fetch()) {
|
for (const [_, oauthGuild] of await client.guilds.fetch()) {
|
||||||
const guild = await oauthGuild.fetch()
|
const guild = await oauthGuild.fetch()
|
||||||
const channel = (await guild.channels.fetch()).find(ch => ch.name === 'reminder')
|
const channel = (await guild.channels.fetch()).find(ch => ch.name === 'reminder')
|
||||||
|
|
||||||
if (!channel) continue
|
if (!channel) continue
|
||||||
|
|
||||||
eventCache.forEach(async (event) => {
|
eventCache.forEach(async (event) => {
|
||||||
let { schedule_id, event_name, start_time, end_time, day_of_week } = event
|
let { schedule_id, event_name, start_time, end_time, day_of_week } = event
|
||||||
if (!((!day_of_week || day_of_week === getDayOfWeek()) && isReminderTime(convertToUTC(start_time)))) return
|
if (!((!day_of_week || day_of_week === getDayOfWeek()) && isReminderTime(convertToUTC(start_time)))) return
|
||||||
|
|
||||||
const rolesEventMap = await GetEventRole()
|
const rolesEventMap = await GetEventRole()
|
||||||
const role = guild.roles.cache.find(r => r.name === rolesEventMap.get(event_name))
|
const role = guild.roles.cache.find(r => r.name === rolesEventMap.get(event_name))
|
||||||
const roleId = role ? role.id : null
|
const roleId = role ? role.id : null
|
||||||
|
|
||||||
const embed = new EmbedBuilder()
|
const embed = new EmbedBuilder()
|
||||||
.setTitle(event_name)
|
.setTitle(event_name)
|
||||||
.setDescription(`${event_name} starts at **${start_time} CEST** and ends at **${end_time} CEST**. \n ${roleId ? `<@&${roleId}>` : 'No role assigned'} \n`)
|
.setDescription(`${event_name} starts at **${start_time} CEST** and ends at **${end_time} CEST**. \n ${roleId ? `<@&${roleId}>` : 'No role assigned'} \n`)
|
||||||
.addFields(
|
.addFields(
|
||||||
{ name: 'Day of Week', value: day_of_week ? day_of_week : 'Daily', inline: true },
|
{ name: 'Day of Week', value: day_of_week ? day_of_week : 'Daily', inline: true },
|
||||||
{
|
{
|
||||||
name: 'Compare Time',
|
name: 'Compare Time',
|
||||||
value: `[Click here to compare event time to your local time](https://www.timeanddate.com/worldclock/fixedtime.html?iso=${convertToISO(start_time, new Date().toISOString().split('T')[0])}&msg=${encodeURIComponent(event_name)})`,
|
value: `[Click here to compare event time to your local time](https://www.timeanddate.com/worldclock/fixedtime.html?iso=${convertToISO(start_time, new Date().toISOString().split('T')[0])}&msg=${encodeURIComponent(event_name)})`,
|
||||||
inline: true
|
inline: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.setFooter({ text: `Schedule ID: ${schedule_id}` })
|
.setFooter({ text: `Schedule ID: ${schedule_id}` })
|
||||||
.setColor('#00FF00')
|
.setColor('#00FF00')
|
||||||
|
|
||||||
await channel.send({ embeds: [embed] }).catch(console.error)
|
await channel.send({ embeds: [embed] }).catch(console.error)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
startEventCheckCron,
|
startEventCheckCron,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user