Skip to content

Commit

Permalink
Merge pull request #92 from mimotej/add-db
Browse files Browse the repository at this point in the history
feat: Add mongodb as a default database for application
  • Loading branch information
mimotej authored Oct 11, 2023
2 parents acec59b + f0e6c18 commit 72b4c63
Show file tree
Hide file tree
Showing 13 changed files with 494 additions and 120 deletions.
1 change: 1 addition & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
setupFilesAfterEnv: ['<rootDir>/tests/utils/singletonPrisma.ts'],
};
78 changes: 78 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"homepage": "https://github.com/OqixDevs/OqixTS#readme",
"dependencies": {
"@discordjs/rest": "2.0.0",
"@prisma/client": "^5.2.0",
"discord-api-types": "0.37.52",
"discord.js": "14.12.1",
"dotenv": "16.3.1",
Expand All @@ -47,11 +48,15 @@
"eslint": "8.47.0",
"jest": "29.6.2",
"prettier": "3.0.1",
"prisma": "^5.2.0",
"ts-jest": "29.1.1",
"ts-node": "10.9.1",
"typescript": "5.1.6"
},
"optionalDependencies": {
"nodemon": "3.0.1"
},
"prisma": {
"schema": "src/model/schema.prisma"
}
}
6 changes: 6 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Client, GatewayIntentBits } from 'discord.js';
import {
actionListener,
channelListener,
interactionListener,
pinVoteListener,
Expand All @@ -15,12 +16,16 @@ import { SubjectChannels } from './utils';
export default () => {
dotenv.config();
const token = process.env.DISCORD_TOKEN; // add your token here

console.log('Bot is starting...');

const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildModeration,
],
});
client.login(token);
Expand All @@ -32,6 +37,7 @@ export default () => {
}
});

actionListener(client);
interactionListener(client);
channelListener(client);
pinVoteListener(client);
Expand Down
92 changes: 59 additions & 33 deletions src/commands/verify.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js';
import { sanitizeUrl } from '@braintree/sanitize-url';
import { assignRole, scrapeConfirmationStudies, scrapeThesis } from '../utils';
import * as fs from 'fs';
import { prisma } from '../model';

/**
* Takes URL to confirmation of studies and thesis and if the data scraped from websites are correct verifies user with role.
Expand All @@ -28,14 +28,6 @@ export const data = new SlashCommandBuilder()
);

export async function execute(interaction: ChatInputCommandInteraction) {
let userLog = undefined;
try {
userLog = fs.readFileSync('./userLog.json', 'utf8');
} catch (e) {
fs.writeFileSync('./userLog.json', '[]');
userLog = fs.readFileSync('./userLog.json', 'utf8');
}
const userLogJSON = JSON.parse(userLog);
const idConfirmationMuni = interaction.options.getString(
'linktoconfirmationmuni'
);
Expand All @@ -50,60 +42,94 @@ export async function execute(interaction: ChatInputCommandInteraction) {
const idConfirmationMuniParsedUrl = new URL(
sanitizeUrl(idConfirmationMuni)
);
for (const key in userLogJSON) {
if (interaction.user.id === userLogJSON[key].id) {
return interaction.reply({
content:
'User already verified! Contact admin if you need to verify again.',
ephemeral: true,
});
} else if (
userLogJSON[key].idThesis ===
bachelorThesisParsedUrl.pathname.split('/')[3]
) {
return interaction.reply({
content: 'This thesis is already used! Please contact admin.',
ephemeral: true,
});
}

await interaction.reply({
content: 'Verifying, wait please...',
ephemeral: true,
});
let user;
try {
user = await prisma.users.findMany({
where: {
discordId: interaction.user.id,
},
});
} catch (err) {
console.log(`Database error: ${err}`);
return interaction.editReply({
content: 'Verification failed! Contact admin.',
});
}
if (user.length != 0 && user[0].status !== 'removed') {
return interaction.editReply({
content:
'User already verified! Contact admin if you need to verify again.',
});
}
try {
user = await prisma.users.findMany({
where: {
idThesis: bachelorThesisParsedUrl.pathname.split('/')[3],
},
});
} catch (err) {
console.log(`Database error: ${err}`);
return interaction.editReply({
content: 'Verification failed! Contact admin.',
});
}
if (user.length != 0 && user[0].status !== 'removed') {
return interaction.editReply({
content: 'This thesis is already used! Please contact admin.',
});
}
const authorName = await scrapeThesis(bachelorThesisParsedUrl.pathname);
if (!authorName) {
return interaction.reply({
return interaction.editReply({
content:
'Could not get the author name. Maybe thesis URL is wrong or the website did not respond.',
ephemeral: true,
});
}
const scrapedConfirmationStudy = await scrapeConfirmationStudies(
idConfirmationMuniParsedUrl.pathname
);
if (!scrapedConfirmationStudy) {
return interaction.reply({
return interaction.editReply({
content:
'Could not get infromation from the confirmation of studies. Maybe confirmation of studies URL is wrong or the website did not respond.',
ephemeral: true,
});
}

if (user[0]?.status === 'removed') {
try {
await prisma.users.delete({
where: {
id: user[0].id,
},
});
} catch (err) {
console.log(`Database error: ${err}`);
return interaction.editReply({
content: 'Verification failed! Contact admin.',
});
}
}
const roleProgramm = await assignRole(
interaction,
scrapedConfirmationStudy,
authorName,
bachelorThesisParsedUrl
);
if (roleProgramm) {
return interaction.reply({
return interaction.editReply({
content:
'You have been successfully verified with role ' +
roleProgramm.name +
'.',
ephemeral: true,
});
}
return interaction.reply({
return interaction.editReply({
content:
'Verification failed check if you entered the correct information or contact admin.',
ephemeral: true,
});
}
62 changes: 62 additions & 0 deletions src/listeners/actionListener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Listenes for kick or ban actions and adds either a removed or ban value to user status if user is verified
* also check for ban remove and adds removed value to user status so that user can be verified again
*/

import { Client, GuildBan } from 'discord.js';
import { prisma } from '../model';

export default (client: Client) => {
client.on('guildBanAdd', async (guildBan: GuildBan) => {
const user = await prisma.users.findFirst({
where: {
discordId: guildBan.user.id,
},
});
if (user) {
await prisma.users.update({
where: {
id: user.id,
},
data: {
status: 'banned',
},
});
}
});
client.on('guildBanRemove', async (guildBan: GuildBan) => {
const user = await prisma.users.findFirst({
where: {
discordId: guildBan.user.id,
},
});
if (user) {
await prisma.users.update({
where: {
id: user.id,
},
data: {
status: 'removed',
},
});
}
});

client.on('guildMemberRemove', async (member) => {
const user = await prisma.users.findFirst({
where: {
discordId: member.id,
},
});
if (user && user.status !== 'banned') {
await prisma.users.update({
where: {
id: user.id,
},
data: {
status: 'removed',
},
});
}
});
};
1 change: 1 addition & 0 deletions src/listeners/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* Listeners which are called when event happens
*/
export { default as actionListener } from './actionListener';
export { default as interactionListener } from './interactionListener';
export { default as channelListener } from './channelListener';
export { default as pinVoteListener } from './pinVoteListener';
1 change: 1 addition & 0 deletions src/model/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './prisma';
Loading

0 comments on commit 72b4c63

Please sign in to comment.