all repos — stealth-developers @ 28a0470c5b3973651d9b1dec66820b5b41f94000

src/utils/userInfo.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
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
import type { GetUserResponse } from "@/types/roblox";
import {
	getConnectedRobloxUser,
	getRobloxIdFromUsername,
	getRobloxUser,
} from "@/utils/roblox";
import {
	ActionRowBuilder,
	ButtonBuilder,
	ButtonStyle,
	EmbedBuilder,
} from "discord.js";

export type AvatarSize =
	| 48
	| 50
	| 60
	| 75
	| 100
	| 110
	| 150
	| 180
	| 352
	| 420
	| 720;

export interface UserInfoResult {
	embed: EmbedBuilder;
	components: ActionRowBuilder<ButtonBuilder>[];
}

export async function getUserInfoFromRobloxUsername(
	username: string,
): Promise<UserInfoResult | { error: string }> {
	const robloxId = await getRobloxIdFromUsername(username);

	if (!robloxId) {
		return { error: "user not found or username is invalid" };
	}

	return getUserInfoFromRoblox(robloxId);
}

export async function getUserInfoFromDiscord(
	discordId: string,
): Promise<UserInfoResult | { error: string }> {
	const connectedAccount = await getConnectedRobloxUser(discordId);
	if ("error" in connectedAccount) {
		return { error: connectedAccount.error };
	}

	return getUserInfoFromRoblox(connectedAccount.robloxID);
}

export async function getUserInfoFromRoblox(
	robloxId: string,
	avatarSize: AvatarSize = 420,
): Promise<UserInfoResult | { error: string }> {
	try {
		const { user, thumbnail } = await getRobloxUser(robloxId, avatarSize);
		return formatUserInfo(
			user,
			thumbnail.done ? thumbnail.response.imageUri : null,
		);
	} catch (error) {
		return {
			error:
				error instanceof Error ? error.message : "failed to fetch user data",
		};
	}
}

export function formatUserInfo(
	user: GetUserResponse,
	thumbnailUrl: string | null,
): UserInfoResult {
	const createdAt = new Date(user.createTime);
	const timestamp = Math.floor(createdAt.getTime() / 1000);

	const embed = new EmbedBuilder()
		.setAuthor({
			name: user.displayName,
			url: `https://www.roblox.com/users/${user.id}/profile`,
		})
		.setDescription(user.about || null)
		.addFields(
			{
				name: "id",
				value: user.id,
			},
			{
				name: "username",
				value: user.name,
			},
			{
				name: "created",
				value: `<t:${timestamp}> (<t:${timestamp}:R>)`,
			},
		)
		.setColor(0x00aaff);

	if (thumbnailUrl) {
		embed.setThumbnail(thumbnailUrl);
	}

	const components = [
		new ActionRowBuilder<ButtonBuilder>().addComponents(
			new ButtonBuilder()
				.setURL(`https://www.roblox.com/users/${user.id}/profile`)
				.setLabel("view profile")
				.setStyle(ButtonStyle.Link),
		),
	];

	return { embed, components };
}