mirror of
https://github.com/UiO-Gaming/name-100-uio-gamers.git
synced 2026-11-05 13:56:53 +01:00
Return an error instead of a wrong guess when the member lookup fails
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6a3487e6da
commit
e09b2f981f
2 files changed
+42
-107
No files matched your search
@@ -1,6 +1,5 @@
|
||||
import { authOptions } from "@/lib/auth";
|
||||
import { findDiscordMember } from "@/lib/members";
|
||||
import type { Match } from "@/types";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
@@ -10,6 +9,11 @@ export async function POST(request: Request) {
|
||||
return new Response("Unauthorized", { status: 401 });
|
||||
}
|
||||
const { input, guessedIds } = await request.json();
|
||||
const match: Match = await findDiscordMember(input, guessedIds);
|
||||
return NextResponse.json(match);
|
||||
|
||||
try {
|
||||
return NextResponse.json(await findDiscordMember(input, guessedIds));
|
||||
} catch (error) {
|
||||
console.error("Error finding Discord member:", error);
|
||||
return NextResponse.json({ error: "Failed to look up member" }, { status: 503 });
|
||||
}
|
||||
}
|
||||
+35
-104
@@ -57,124 +57,55 @@ function getDisplayName(member: DiscordGuildMember): string {
|
||||
return member.nick || member.user.global_name || member.user.username;
|
||||
}
|
||||
|
||||
function normalizeInput(input: string): string {
|
||||
return input.toLowerCase().trim();
|
||||
}
|
||||
|
||||
function memberMatchesInput(member: DiscordGuildMember, normalizedInput: string): boolean {
|
||||
const username = member.user.username.toLowerCase();
|
||||
const globalName = member.user.global_name?.toLowerCase() || "";
|
||||
const nickname = member.nick?.toLowerCase() || "";
|
||||
|
||||
return username === normalizedInput || globalName === normalizedInput || nickname === normalizedInput;
|
||||
return [member.user.username, member.user.global_name, member.nick].some(
|
||||
(name) => name?.toLowerCase() === normalizedInput,
|
||||
);
|
||||
}
|
||||
|
||||
export async function getPayingMemberCount(): Promise<number> {
|
||||
const payingMemberRoleId = process.env.DISCORD_REQUIRED_ROLE_ID;
|
||||
if (!payingMemberRoleId) {
|
||||
throw new Error("Missing DISCORD_REQUIRED_ROLE_ID environment variable");
|
||||
}
|
||||
const payingMemberRoleId = requireEnv("DISCORD_REQUIRED_ROLE_ID");
|
||||
const members = await getDiscordMembers();
|
||||
return members.filter((m) => m.roles.includes(payingMemberRoleId)).length;
|
||||
}
|
||||
|
||||
export async function findDiscordMember(input: string, guessedIds: string[] = []): Promise<Match> {
|
||||
const payingMemberRoleId = process.env.DISCORD_REQUIRED_ROLE_ID;
|
||||
export async function findDiscordMember(input: string, guessedIds: string[]): Promise<Match> {
|
||||
const payingMemberRoleId = requireEnv("DISCORD_REQUIRED_ROLE_ID");
|
||||
const normalizedInput = input.toLowerCase().trim();
|
||||
const guessed = new Set(guessedIds);
|
||||
|
||||
if (!payingMemberRoleId) {
|
||||
console.error("Missing required Discord environment variables");
|
||||
const candidates = (await getDiscordMembers()).filter((member) => memberMatchesInput(member, normalizedInput));
|
||||
const isPaying = (member: DiscordGuildMember) => member.roles.includes(payingMemberRoleId);
|
||||
const isUnguessed = (member: DiscordGuildMember) => !guessed.has(member.user.id);
|
||||
|
||||
const member =
|
||||
candidates.find((m) => isPaying(m) && isUnguessed(m)) ??
|
||||
candidates.find((m) => !isPaying(m) && isUnguessed(m)) ??
|
||||
candidates.find(isPaying) ??
|
||||
candidates[0];
|
||||
|
||||
if (!member) {
|
||||
return { input, name: undefined, description: undefined, correct: false };
|
||||
}
|
||||
|
||||
const name = getDisplayName(member);
|
||||
|
||||
if (!isPaying(member)) {
|
||||
return {
|
||||
id: member.user.id,
|
||||
input,
|
||||
name: undefined,
|
||||
name,
|
||||
description: undefined,
|
||||
translationKey: "notPayingMember",
|
||||
correct: false,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const members = await getDiscordMembers();
|
||||
const normalizedInput = normalizeInput(input);
|
||||
|
||||
const allMatchingMembers = members.filter((member) => memberMatchesInput(member, normalizedInput));
|
||||
|
||||
if (allMatchingMembers.length === 0) {
|
||||
return { input, name: undefined, description: undefined, correct: false };
|
||||
}
|
||||
|
||||
const payingMembers = allMatchingMembers.filter((member) => member.roles.includes(payingMemberRoleId));
|
||||
const nonPayingMembers = allMatchingMembers.filter((member) => !member.roles.includes(payingMemberRoleId));
|
||||
|
||||
const unguessedPayingMember = payingMembers.find((member) => !guessedIds.includes(member.user.id));
|
||||
|
||||
if (unguessedPayingMember) {
|
||||
const displayName = getDisplayName(unguessedPayingMember);
|
||||
const username = unguessedPayingMember.user.username;
|
||||
|
||||
return {
|
||||
id: unguessedPayingMember.user.id,
|
||||
input,
|
||||
name: displayName,
|
||||
description: displayName === username ? undefined : username,
|
||||
correct: true,
|
||||
};
|
||||
}
|
||||
|
||||
const unguessedNonPayingMember = nonPayingMembers.find((member) => !guessedIds.includes(member.user.id));
|
||||
|
||||
if (unguessedNonPayingMember) {
|
||||
return {
|
||||
id: unguessedNonPayingMember.user.id,
|
||||
input,
|
||||
name: getDisplayName(unguessedNonPayingMember),
|
||||
description: undefined,
|
||||
translationKey: "notPayingMember",
|
||||
correct: false,
|
||||
};
|
||||
}
|
||||
|
||||
// If we are here, all matching members (paying or not) have been guessed.
|
||||
// Return the first paying member match to signal a duplicate to the client.
|
||||
if (payingMembers.length > 0) {
|
||||
const firstPayingMatch = payingMembers[0];
|
||||
const displayName = getDisplayName(firstPayingMatch);
|
||||
const username = firstPayingMatch.user.username;
|
||||
|
||||
return {
|
||||
id: firstPayingMatch.user.id,
|
||||
input,
|
||||
name: displayName,
|
||||
description: displayName === username ? undefined : username,
|
||||
correct: true, // It is a correct member, but already guessed.
|
||||
};
|
||||
}
|
||||
|
||||
// If no paying members matched, return the first non-paying member.
|
||||
if (nonPayingMembers.length > 0) {
|
||||
const firstNonPayingMatch = nonPayingMembers[0];
|
||||
return {
|
||||
id: firstNonPayingMatch.user.id,
|
||||
input,
|
||||
name: getDisplayName(firstNonPayingMatch),
|
||||
description: undefined,
|
||||
translationKey: "notPayingMember",
|
||||
correct: false,
|
||||
};
|
||||
}
|
||||
|
||||
// Should not be reached if allMatchingMembers.length > 0
|
||||
return {
|
||||
input,
|
||||
name: undefined,
|
||||
description: undefined,
|
||||
correct: false,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Error finding Discord member:", error);
|
||||
return {
|
||||
input,
|
||||
name: undefined,
|
||||
description: undefined,
|
||||
correct: false,
|
||||
};
|
||||
}
|
||||
return {
|
||||
id: member.user.id,
|
||||
input,
|
||||
name,
|
||||
description: name === member.user.username ? undefined : member.user.username,
|
||||
correct: true,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user