From bdf862cbe8e025ddb6483d5dd1591c68217c0b47 Mon Sep 17 00:00:00 2001 From: Moritz Date: Sat, 27 Jan 2024 19:05:28 +0100 Subject: [PATCH] added user update endpoint --- docker-compose.yml | 1 + package.json | 2 +- src/core/config.ts | 2 +- src/events/onGuildMemberUpdateEvent.ts | 11 +--- src/http/apiController.ts | 74 +++++++++++++++++++++++++- src/http/httpClient.ts | 1 + src/interfaces/user.interface.ts | 4 +- src/services/user.service.ts | 7 +-- src/utils/departmentRolesMap.ts | 2 + src/utils/getDepartmentRoles.ts | 38 ------------- 10 files changed, 85 insertions(+), 57 deletions(-) delete mode 100644 src/utils/getDepartmentRoles.ts diff --git a/docker-compose.yml b/docker-compose.yml index 9681b1e..71641c6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,7 @@ services: command: npm run dev ports: - '9229:9229/tcp' + - '8000:8000/tcp' volumes: - .:/opt:delegated environment: diff --git a/package.json b/package.json index abd7419..d430d72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord-bot", - "version": "1.4.1", + "version": "1.5.0", "scripts": { "run": "tsc && node ./dist/src/index.js", "commands:update": "rimraf ./dist && tsc && node ./dist/scripts/registerCommands.js", diff --git a/src/core/config.ts b/src/core/config.ts index 8afd5de..55a4d2b 100644 --- a/src/core/config.ts +++ b/src/core/config.ts @@ -81,7 +81,7 @@ export const Config: EnvConfig = { HP_TOKEN: process.env.HP_TOKEN ?? '', PING_GROUPS: ['EDDH', 'EDDB', 'EDDV', 'EDDL', 'EDDK', 'EDDF', 'EDDS', 'EDDN', 'EDDM', 'CTR EDWW', 'CTR EDGG', 'CTR EDMM', 'Minor EDWW', 'Minor EDGG', 'Minor EDMM', 'ECFMP EDWW', 'ECFMP EDGG', 'ECFMP EDMM'], - MANAGEABLE_GROUPS: ['Mentor EDWW', 'Mentor EDGG', 'Mentor EDMM', 'Mentor', 'NAV EDWW', 'NAV EDGG', 'NAV EDMM', 'NAV', 'Event EDWW', 'Event EDGG', 'Event EDMM', 'Event', 'PTD Trainer', 'PMP Mentor'], + MANAGEABLE_GROUPS: ['EDWW Mentor', 'EDGG Mentor', 'EDMM Mentor', 'Mentor', 'EDWW Nav', 'EDGG Nav', 'EDMM Nav', 'NAV', 'EDWW Event', 'EDGG Event', 'EDMM Event', 'Event', 'PTD Trainer', 'PMP Mentor'], EVENT_UPDATE: process.env.EVENT_UPDATE == 'true', EVENT_UPDATE_CRON: process.env.EVENT_UPDATE_CRON ?? '0 */3 0 0 0', diff --git a/src/events/onGuildMemberUpdateEvent.ts b/src/events/onGuildMemberUpdateEvent.ts index 517c963..da1f361 100644 --- a/src/events/onGuildMemberUpdateEvent.ts +++ b/src/events/onGuildMemberUpdateEvent.ts @@ -7,7 +7,6 @@ import { sendModeratorMessage } from '../utils/sendModeratorMessage'; import dayjs from 'dayjs'; import vatgerApiService from '../services/vatgerApiService'; import vatsimApiService from '../services/vatsimApiService'; -import { getDepartmentRoles } from '../utils/getDepartmentRoles'; import { DiscordBotClient } from '../core/client'; export default class OnGuildMemberUpdateEvent extends DiscordEvent { @@ -28,15 +27,7 @@ export default class OnGuildMemberUpdateEvent extends DiscordEvent { if (isVatger) { await newUser.roles.add(Config.VATGER_MEMBER_ROLE_ID); console.log(`Added VATGER Role to ${newUser.id}`); - - const userCid = await vatsimApiService.getCIDFromDiscordID(newUser.id); - - if (userCid) { - const vatgerApiData = await vatgerApiService.getUserDetailsFromVatger(userCid); - const userRolesToAdd = await getDepartmentRoles(vatgerApiData.teams, guild); - - await newUser.roles.add(userRolesToAdd); - } + await userService.updateUser(newUser, { isVatger: true }) } } catch (e: any) { diff --git a/src/http/apiController.ts b/src/http/apiController.ts index 97b10ac..ca969aa 100644 --- a/src/http/apiController.ts +++ b/src/http/apiController.ts @@ -1,13 +1,17 @@ import { Request, Response } from 'express'; -import userModel from '../models/user.model'; +import userModel, { UserDocument } from '../models/user.model'; import { findGuildMemberByDiscordID } from '../utils/findGuildMember'; import { Config } from '../core/config'; -import { GuildMember } from 'discord.js'; +import { Collection, GuildMember, Role } from 'discord.js'; +import userService from '../services/user.service'; +import map from '../utils/departmentRolesMap'; +import { DiscordBotClient } from '../core/client'; async function handleMemberJoin(request: Request, response: Response) { response.send({ message: 'OK' }); try { + const cid = request.body.cid; if (cid == null) { @@ -66,7 +70,73 @@ async function handleMemberLeave(request: Request, response: Response) { } } +async function updateMember(req: Request, res: Response) { + try { + const guild = DiscordBotClient.guilds.cache.get(Config.GUILD_ID); + const cid = req.body.cid; + const teams: string[] = req.body.teams; + + const user: UserDocument | null = await userService.getUserByCid(cid); + + const guildMember: GuildMember | undefined = await findGuildMemberByDiscordID(user?.discordId); + let guildMemberRoles = guildMember?.roles.cache; + + for (const group of Config.MANAGEABLE_GROUPS) { + if (map.has(group)) { + if (teams.includes(group) && !guildMemberRoles?.some(r => r.id === map.get(group))) { + await guildMember?.roles.add(map.get(group)); + } else if (!teams.includes(group) && guildMemberRoles?.some(r => r.id === map.get(group))) { + await guildMember?.roles.remove(map.get(group)); + } + } + } + + guildMemberRoles = guildMember?.roles.cache; + const roleNamesArray: string[] = []; + + if (guildMemberRoles) { + for (const role of guildMemberRoles) { + roleNamesArray.push(role[1].name); + } + } + + const guildRoles: Collection | undefined = guild?.roles.cache; + + const navRole = guildRoles?.filter(r => r.name === 'Nav'); + const mentorRole = guildRoles?.filter(r => r.name === 'Mentor'); + const eventRole = guildRoles?.filter(r => r.name === 'Event'); + + if (navRole) { + if (roleNamesArray.filter(x => ['EDGG Nav','EDMM Nav','EDWW Nav'].includes(x)).length > 0) { + await guildMember?.roles.add(navRole) + } else { + await guildMember?.roles.remove(navRole) + } + } + if (mentorRole) { + if (roleNamesArray.filter(x => ['EDGG Mentor','EDMM Mentor','EDWW Mentor'].includes(x)).length > 0) { + await guildMember?.roles.add(mentorRole); + } else { + await guildMember?.roles.remove(mentorRole); + } + } + if (eventRole) { + if (roleNamesArray.filter(x => ['EDGG Event','EDMM Event','EDWW Event'].includes(x)).length > 0) { + await guildMember?.roles.add(eventRole) + } else { + await guildMember?.roles.remove(eventRole) + } + } + + res.send({ message: 'OK' }); + + } catch (error: any) { + console.error('Failed to update member', error.message); + } +} + export default { handleMemberJoin, handleMemberLeave, + updateMember }; diff --git a/src/http/httpClient.ts b/src/http/httpClient.ts index 973b4ae..0959d4b 100644 --- a/src/http/httpClient.ts +++ b/src/http/httpClient.ts @@ -14,3 +14,4 @@ httpClient.use(bodyParser.json()); httpClient.post('/member/join', apiController.handleMemberJoin); httpClient.post('/member/leave', apiController.handleMemberLeave); +httpClient.post('/member/update', apiController.updateMember); \ No newline at end of file diff --git a/src/interfaces/user.interface.ts b/src/interfaces/user.interface.ts index 0111862..ce73da2 100644 --- a/src/interfaces/user.interface.ts +++ b/src/interfaces/user.interface.ts @@ -1,4 +1,4 @@ -interface User { +interface IUser { discordId: string; cid: number; isVatger: boolean; @@ -7,4 +7,4 @@ interface User { militaryRating: number; } -export default User; +export default IUser; diff --git a/src/services/user.service.ts b/src/services/user.service.ts index 09e1a31..ebc946b 100644 --- a/src/services/user.service.ts +++ b/src/services/user.service.ts @@ -71,13 +71,14 @@ async function getUserByDiscordId(discordId: string) { } -async function getUserByCid(cid: number) { +async function getUserByCid(cid: number): Promise { try { const user: UserDocument | null = await userModel.findOne({ cid: cid }); - if (user) { - return user; + if (!user) { + throw new Error('Pilot not found'); } + return user; } catch (error) { throw new Error(`Cant get user CID: ${error}`); } diff --git a/src/utils/departmentRolesMap.ts b/src/utils/departmentRolesMap.ts index af4d755..d706543 100644 --- a/src/utils/departmentRolesMap.ts +++ b/src/utils/departmentRolesMap.ts @@ -11,6 +11,8 @@ map.set('EDMM Nav', '1107561970997149717'); map.set('EDGG Event', '1107563041509351455'); map.set('EDWW Event', '1107562913448865884'); map.set('EDMM Event', '1107563076942827531'); +map.set('PMP Mentor', '1108030536284385330'); +map.set('PTD Trainer', '1107774004758057001'); // Dev Map // const map = new Map(); diff --git a/src/utils/getDepartmentRoles.ts b/src/utils/getDepartmentRoles.ts deleted file mode 100644 index 708d00c..0000000 --- a/src/utils/getDepartmentRoles.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Guild, Role, RoleResolvable, StringMappedInteractionTypes } from "discord.js"; -import map from "./departmentRolesMap"; - - - - -export async function getDepartmentRoles(teams: string[], guild: Guild | undefined): Promise { - const rolesArray: string[] = []; - - for (const role of teams) { - if (map.has(role)) { - rolesArray.push(map.get(role)); - } - } - - if (teams.filter(x => x.includes('EDGG Nav' || 'EDMM Nav' || 'EDWW Nav')).length > 0) { - const role = guild?.roles.cache.find(r => r.name === 'NAV') - if (role) { - rolesArray.push(role.id); - } - } - - if (teams.filter(x => x.includes('EDGG Mentor' || 'EDMM Mentor' || 'EDWW Mentor')).length > 0) { - const role = guild?.roles.cache.find(r => r.name === 'Mentor') - if (role) { - rolesArray.push(role.id); - } - } - - if (teams.filter(x => x.includes('EDGG Event' || 'EDMM Event' || 'EDWW Event')).length > 0) { - const role = guild?.roles.cache.find(r => r.name === 'Event') - if (role) { - rolesArray.push(role.id); - } - } - - return rolesArray; -} \ No newline at end of file