all repos — discord-utils @ 2109185c6680068abea65220af0279b0ca989e48

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
import { container } from "@sapphire/framework";
import config from "@/config";
import type { BanResponse, RobloxUser } from "./types";

const COOKIE = config.roblox.cookie;
let CSRF_TOKEN: string | undefined;

const request = (url: URL, options?: RequestInit) =>
	fetch(url, {
		headers: {
			Cookie: COOKIE,
		},
		...options,
	});

export async function getUser(id: string): Promise<RobloxUser> {
	const url = new URL(`https://users.roblox.com/v1/users/${id}`);

	const response = await request(url);
	return (await response.json()) as RobloxUser;
}

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();
}

export * from "./types";