Skip to content

Commit

Permalink
fix a bunch of stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
ashleylamont committed Feb 15, 2024
1 parent a3fe77f commit 40ebb19
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 26 deletions.
63 changes: 44 additions & 19 deletions src/baserow-integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,26 @@ import {
BaserowWebhook,
} from "./baserow-types";
import express, { Express, Request } from "express";
import { Guild, GuildMember } from "discord.js";
import { Guild, GuildMember, Snowflake } from "discord.js";

const baserowData: Map<number, BaserowItem> = new Map();
const MEMBER_ROLE_ID = "753524901708693558";
const LIFE_MEMBER_ROLE_ID = "702889882598506558";
const CSSA_SERVER_ID = process.env.CSSA_SERVER || "";
const CSSA_SERVER_ID = process.env.CSSA_SERVER as Snowflake;
if (!CSSA_SERVER_ID) throw new Error("CSSA_SERVER not set.");

function transformUsername(username: string): string;
function transformUsername(username: string | null): string | undefined;
function transformUsername(username: string | null): string | undefined {
function transformUsername(username: string): [string, number];
function transformUsername(
username: string | null,
): [string, number] | undefined {
if (username === null) return undefined;
// New discord names are stored lowercase, and case insensitive
if (!username.includes("#")) {
username = username.toLowerCase();
return username;
return [username, 0];
}
const [name, discriminator] = username.split("#");
return [name, Number.parseInt(discriminator, 10)];
}

const isLifeMember = (item: BaserowItem): boolean => {
Expand Down Expand Up @@ -78,13 +82,20 @@ export async function refreshBaserowData() {
const memberRole = await cssaGuild.roles.fetch(MEMBER_ROLE_ID);
if (!memberRole) throw new Error("Couldn't get member role.");
const members = memberRole.members;
const memberUsernames = new Set(
fetchedData
.map((item) => item[BASEROW_ITEM_FIELDS.DISCORD_USERNAME])
.map((username) => transformUsername(username)),
);
const memberUsernames: Map<string, Set<number>> = new Map();
for (const item of fetchedData) {
const username = item[BASEROW_ITEM_FIELDS.DISCORD_USERNAME];
if (!username) continue;
const [name, discriminator] = transformUsername(username);
if (!memberUsernames.has(name)) memberUsernames.set(name, new Set());
memberUsernames.get(name)?.add(discriminator);
}
for (const member of members.values()) {
if (!memberUsernames.has(member.user.username))
const validDiscriminators = memberUsernames.get(member.user.username);
if (
validDiscriminators === undefined ||
!validDiscriminators.has(Number.parseInt(member.user.discriminator, 10))
)
eventPromises.push(member.roles.remove(memberRole));
}

Expand Down Expand Up @@ -166,16 +177,21 @@ class MemberNotFoundError extends Error {}

async function getGuildAndUser(
guildId: string,
username: string,
rawUsername: string,
): Promise<[Guild, GuildMember]> {
username = transformUsername(username);
const [username, discriminator] = transformUsername(rawUsername);
const guild = await discordClient.guilds.fetch(guildId);
if (!guild) throw new Error("Couldn't fetch guild data.");
const matchingMembers = await guild.members.fetch({ query: username });
for (const member of matchingMembers.values()) {
if (member.user.username === username) return [guild, member];
if (
member.user.username === username &&
member.user.discriminator === discriminator.toString(10)
)
return [guild, member];
}
throw new MemberNotFoundError("Couldn't find member in guild.");
console.log(`Couldn't find member in guild: ${username}#${discriminator}`);
throw new MemberNotFoundError("Couldn't find member in guild: " + username);
}

export async function performRoleUpdate(
Expand All @@ -188,6 +204,9 @@ export async function performRoleUpdate(
roleType === "member" ? MEMBER_ROLE_ID : LIFE_MEMBER_ROLE_ID,
);
if (!role) throw new Error("Couldn't get role.");
console.log(
`Performing role update: ${operation} ${roleType} for ${username}`,
);
await (operation === "add"
? member.roles.add(role)
: member.roles.remove(role));
Expand All @@ -202,7 +221,9 @@ export async function onRowCreate(row: BaserowItem) {
await performRoleUpdate(username, "lifeMember", "add");
}
} catch (error) {
console.warn("Error while processing onRowCreate:", error);
if (!(error instanceof MemberNotFoundError)) {
console.warn("Error while processing onRowCreate:", error);
}
}
}

Expand Down Expand Up @@ -230,7 +251,9 @@ export async function onRowUpdate(row: BaserowItem, oldRow: BaserowItem) {
await performRoleUpdate(newUsername, "lifeMember", "add");
}
} catch (error) {
console.warn("Error while processing onRowUpdate:", error);
if (!(error instanceof MemberNotFoundError)) {
console.warn("Error while processing onRowUpdate:", error);
}
}
}
}
Expand All @@ -243,7 +266,9 @@ export async function onRowUpdate(row: BaserowItem, oldRow: BaserowItem) {
try {
await performRoleUpdate(username, "lifeMember", "add");
} catch (error) {
console.warn("Error while processing onRowUpdate:", error);
if (!(error instanceof MemberNotFoundError)) {
console.warn("Error while processing onRowUpdate:", error);
}
}
}
}
Expand Down
12 changes: 7 additions & 5 deletions src/discord-client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Client, IntentsBitField } from "discord.js";
import { config } from "dotenv";
import registerCommands from "./command-registry";

export async function initDiscord(): Promise<Client<true>> {
return await new Promise((resolve, reject) => {
Expand All @@ -16,8 +15,6 @@ export async function initDiscord(): Promise<Client<true>> {
],
});

void registerCommands();

client.on("ready", () => {
console.log(
`Logged into discord as ${client.user?.tag ?? "USER IS NULL"}!`,
Expand All @@ -43,8 +40,13 @@ export async function initDiscord(): Promise<Client<true>> {
.catch(console.error);
}

if (client.isReady()) resolve(client);
else {
if (client.isReady()) {
client.guilds
.fetch(process.env.CSSA_SERVER!)
.then((guild) => guild.members.fetch())
.then(() => resolve(client))
.catch(reject);
} else {
reject(
new Error("client.on('ready') fired but client.isReady() is false."),
);
Expand Down
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import express from "express";
import { config } from "dotenv";

// This line must come before any other code that uses .env variables
config({ path: ".env" });

import { initDiscord } from "./discord-client";
import { attachDoorServer } from "./door-status";
import addReactionEvents from "./reacts";
import { attachBaserowWebhookListener } from "./baserow-integration";
import { startServerIcon } from "./server-icon";
import registerCommands from "./command-registry";

const PORT = 8080;
globalThis.appMaintainers = [];
Expand All @@ -15,6 +20,7 @@ async function main(): Promise<void> {
// with any subsequent code using it that the value will exist and be of the correct type.
// This means that this line must be executed before any other code that uses globalThis.discordClient.
globalThis.discordClient = await initDiscord();
await registerCommands();

// Initialise the express app and attach the door server
const expressApp = express();
Expand Down
2 changes: 0 additions & 2 deletions src/server-icon.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { config } from "dotenv";
import { Octokit } from "@octokit/rest";
import { Buffer } from "node:buffer";
import axios from "axios";
import { startOfTomorrow } from "date-fns";

export function startServerIcon(): void {
config({ path: ".env" });
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
timeZone: "Australia/Sydney",
Expand Down

0 comments on commit 40ebb19

Please sign in to comment.