src/utils/bans.ts (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
import config from "@/config";
import type { GetUserResponse } from "@/types/roblox";
import { ContainerBuilder, TextDisplayBuilder } from "discord.js";
const projects = Object.values(config.data.projects);
const BASE_URL = "https://apis.roblox.com/user/cloud/v2/universes";
export type Restriction = {
active: true | false;
startTime: string;
privateReason: string;
displayReason: string;
excludeAltAccounts: boolean;
inherited: boolean;
};
export type GetBansResponse = {
path: string;
user: string;
gameJoinRestriction: Restriction;
};
export type GetBansResponseWithProject = GetBansResponse & {
project: string;
};
export async function getBans(
userId: string,
): Promise<GetBansResponseWithProject[] | null> {
if (!config.data.roblox?.cookie) return null;
const fetches = projects.map(async (project) => {
const url = `${BASE_URL}/${project.universe}/user-restrictions/${userId}`;
const bans = await fetch(url, {
headers: {
Cookie: config.data.roblox?.cookie || "",
},
});
if (!bans.ok) {
console.error(
`failed to fetch bans for user ${userId} in project ${project.name}:`,
bans.statusText,
);
return null;
}
const data: GetBansResponse = await bans.json();
return { ...data, project: project.displayName };
});
const results = await Promise.all(fetches);
const bansArray = results.filter(
(data): data is GetBansResponseWithProject => data !== null,
);
return bansArray;
}
export async function buildBansContainer(
user: GetUserResponse,
): Promise<ContainerBuilder> {
const bansContainer = new ContainerBuilder();
{
const bansTitle = new TextDisplayBuilder().setContent(
`## Bans for ${user.displayName || user.name}`,
);
const bans = await getBans(user.id);
const constructBan = (ban: GetBansResponseWithProject) => {
if (!ban.gameJoinRestriction.active) {
return new TextDisplayBuilder().setContent(
`**${ban.project}**: no active ban`,
);
}
const restriction: Restriction = ban.gameJoinRestriction;
return new TextDisplayBuilder().setContent(
`**${ban.project}**\n> **Active since** <t:${Math.round(
new Date(restriction.startTime).getTime() / 1000,
)}:R>\n> **Display reason:** ${restriction.displayReason}\n> **Reason:** ${restriction.privateReason}\n`,
);
};
if (bans && bans.length > 0) {
const banComponents = bans.map(constructBan);
bansContainer.addTextDisplayComponents(bansTitle, ...banComponents);
} else {
bansContainer.addTextDisplayComponents(
bansTitle,
new TextDisplayBuilder().setContent(
"no active bans found for this user",
),
);
}
}
return bansContainer;
}
|