all repos — discord-utils @ 18d7f68a096e1f5eeaac2722dfc37e9e1d247747

src/roblox/index.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
import { container } from "@sapphire/framework";
import config from "@/config";

let CSRF_TOKEN: string | undefined;

export type RobloxUser = {
	username: string;
	displayName: string | null;
	id: string;
};

export async function getUser(id: string): Promise<RobloxUser> {
	const includeDisplayName = Math.random() < 0.5;

	return {
		username: "stub",
		displayName: includeDisplayName ? "stubDisplay" : null,
		id: id,
	};
}

export type BanResponse = {
	path: string;
	user: string;
	gameJoinRestriction: {
		active: boolean;
		startTime: string;
		privateReason: string;
		displayReason: string;
		excludeAltAccounts: boolean;
		inherited: boolean;
	};
};

export async function ban(
	userId: string,
	universeId: string,
	options: {
		duration: string | undefined;
		excludeAltAccounts: boolean;
		displayReason: string;
		privateReason: string;
	},
): Promise<BanResponse> {
	container.logger.debug(`banning ${userId} in universe ${universeId}`, {
		name: "ban",
		...options,
	});

	const makeRequest = async () => {
		const res = await fetch(
			`https://apis.roblox.com/user/cloud/v2/universes/${universeId}/user-restrictions/${userId}`,
			{
				method: "PATCH",
				headers: {
					"Content-Type": "application/json",
					Cookie: config.roblox.cookie,
					Host: "apis.roblox.com",
					Origin: "https://create.roblox.com",
					Referer: "https://create.roblox.com",
					"x-csrf-token": CSRF_TOKEN ?? "",
				},
				body: JSON.stringify({
					gameJoinRestriction: {
						active: true,
						...options,
					},
				}),
			},
		);

		const data = (await res.json()) as Record<string, unknown>;
		container.logger.debug("ban response", { ...data });

		if (res.status === 403) {
			const csrfHeader = res.headers.get("x-csrf-token");
			if (csrfHeader && csrfHeader !== "") {
				CSRF_TOKEN = csrfHeader;
				return await makeRequest();
			}
		}

		if (!res.ok) {
			throw new Error(`failed to ban user: ${res.status} ${res.statusText}`);
		}

		return data as BanResponse;
	};

	return await makeRequest();
}