rpc.ts 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import express from "express";
  2. import { createServer } from "http";
  3. import { ModuleRpcServer } from "rpc_ts/lib/server";
  4. import { ModuleRpcProtocolServer } from "rpc_ts/lib/protocol/server";
  5. import { NoctBotService } from "@shared/rpc/backend";
  6. import { logger } from "./logging";
  7. import { client } from "./client";
  8. import { tryDo } from "@shared/common/async_utils";
  9. import { getRepository } from "typeorm";
  10. import { GuildVerification } from "@shared/db/entity/GuildVerification";
  11. import { isAuthorisedAsync } from "./util";
  12. import { GuildMember } from "discord.js";
  13. const PORT = +(process.env.RPC_PORT ?? "8181");
  14. const app = express();
  15. async function checkUser(userId: string, check: (user: GuildMember, verification: GuildVerification) => Promise<boolean>): Promise<boolean> {
  16. const verificationGuildRepo = getRepository(GuildVerification);
  17. const guilds = await verificationGuildRepo.find({
  18. select: [
  19. "guildId",
  20. "verifiedRoleId",
  21. ]
  22. });
  23. for (const guild of guilds) {
  24. const guildInstance = await tryDo(client.bot.guilds.fetch(guild.guildId));
  25. if (!guildInstance.ok) {
  26. logger.error("Failed to fetch guild instance for guild %s: %s", guild.guildId, guildInstance.error);
  27. continue;
  28. }
  29. const user = await tryDo(guildInstance.result.members.fetch(userId));
  30. if (user.ok && await check(user.result, guild)) {
  31. return true;
  32. }
  33. }
  34. return false;
  35. }
  36. const handler: ModuleRpcServer.ServiceHandlerFor<typeof NoctBotService> = {
  37. async getPing({ ping }): Promise<{ text: string }> {
  38. return { text: `pong: ${ping}` };
  39. },
  40. async userInServer({ userId }): Promise<{ exists: boolean }> {
  41. return { exists: await checkUser(userId, async () => true) };
  42. },
  43. async userAuthorised({ userId }): Promise<{ authorised: boolean }> {
  44. return { authorised: await checkUser(userId, (user) => isAuthorisedAsync(user)) };
  45. },
  46. async userVerified({ userId }): Promise<{ verified: boolean }> {
  47. return { verified: await checkUser(userId, async (user, guild) => user.roles.cache.has(guild.verifiedRoleId)) };
  48. },
  49. async verifyUser({ userId }): Promise<{ ok: boolean }> {
  50. return { ok: !(await checkUser(userId, async (user, guild) => !(await tryDo(user.roles.add(guild.verifiedRoleId))).ok)) };
  51. }
  52. };
  53. app.use(ModuleRpcProtocolServer.registerRpcRoutes(NoctBotService, handler));
  54. export function startRpcServer(): void {
  55. logger.info(`Starting RPC at *:${PORT}`);
  56. createServer(app).listen(PORT);
  57. }