move og image to backend
This commit is contained in:
parent
ef634194b8
commit
6f88ab8f30
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
@ -14,12 +14,14 @@
|
|||||||
"@ssr/common": "workspace:common",
|
"@ssr/common": "workspace:common",
|
||||||
"@tqman/nice-logger": "^1.0.1",
|
"@tqman/nice-logger": "^1.0.1",
|
||||||
"@typegoose/typegoose": "^12.8.0",
|
"@typegoose/typegoose": "^12.8.0",
|
||||||
|
"@vercel/og": "^0.6.3",
|
||||||
"elysia": "latest",
|
"elysia": "latest",
|
||||||
"elysia-autoroutes": "^0.5.0",
|
"elysia-autoroutes": "^0.5.0",
|
||||||
"elysia-decorators": "^1.0.2",
|
"elysia-decorators": "^1.0.2",
|
||||||
"elysia-helmet": "^2.0.0",
|
"elysia-helmet": "^2.0.0",
|
||||||
"elysia-rate-limit": "^4.1.0",
|
"elysia-rate-limit": "^4.1.0",
|
||||||
"mongoose": "^8.7.0"
|
"mongoose": "^8.7.0",
|
||||||
|
"react": "^18.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"bun-types": "latest"
|
"bun-types": "latest"
|
||||||
|
@ -1,19 +1,10 @@
|
|||||||
import { ImageResponse } from "next/og";
|
import { ImageResponse } from "@vercel/og";
|
||||||
import { scoresaberService } from "@ssr/common/service/impl/scoresaber";
|
import { formatNumberWithCommas, formatPp } from "website/src/common/number-utils";
|
||||||
import { NextRequest } from "next/server";
|
import { config } from "website/config";
|
||||||
import { formatNumberWithCommas, formatPp } from "@/common/number-utils";
|
import React from "react";
|
||||||
import { config } from "../../../../../../config";
|
import ScoreSaberPlayerToken from "@ssr/common/types/token/scoresaber/score-saber-player-token";
|
||||||
|
|
||||||
export async function GET(request: NextRequest) {
|
|
||||||
const playerId = request.nextUrl.searchParams.get("id");
|
|
||||||
if (!playerId) {
|
|
||||||
return new Response(null, { status: 400 });
|
|
||||||
}
|
|
||||||
const player = await scoresaberService.lookupPlayer(playerId);
|
|
||||||
if (!player) {
|
|
||||||
return new Response(null, { status: 404 });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
export function generatePlayerOgImage(player: ScoreSaberPlayerToken) {
|
||||||
return new ImageResponse(
|
return new ImageResponse(
|
||||||
(
|
(
|
||||||
<div tw="w-full h-full flex flex-col text-white bg-black text-3xl p-3 justify-center items-center">
|
<div tw="w-full h-full flex flex-col text-white bg-black text-3xl p-3 justify-center items-center">
|
||||||
@ -42,7 +33,12 @@ export async function GET(request: NextRequest) {
|
|||||||
<p tw="m-0">#{formatNumberWithCommas(player.rank)}</p>
|
<p tw="m-0">#{formatNumberWithCommas(player.rank)}</p>
|
||||||
</div>
|
</div>
|
||||||
<div tw="flex items-center px-2 justify-center items-center">
|
<div tw="flex items-center px-2 justify-center items-center">
|
||||||
<img src={`${config.siteUrl}/assets/flags/${player.country}.png`} height={20} alt="Player's Country" />
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||||
|
<img
|
||||||
|
src={`${config.siteUrl}/assets/flags/${player.country.toLowerCase()}.png`}
|
||||||
|
height={20}
|
||||||
|
alt="Player's Country"
|
||||||
|
/>
|
||||||
<p tw="pl-1 m-0">#{formatNumberWithCommas(player.countryRank)}</p>
|
<p tw="pl-1 m-0">#{formatNumberWithCommas(player.countryRank)}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -51,4 +51,14 @@ export default class PlayerController {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get("/og/:id", {
|
||||||
|
config: {},
|
||||||
|
params: t.Object({
|
||||||
|
id: t.String({ required: true }),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
public async getOpenGraphImage({ params: { id } }: { params: { id: string } }) {
|
||||||
|
return await PlayerService.generateOpenGraphImage(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import { scoresaberService } from "@ssr/common/service/impl/scoresaber";
|
|||||||
import ScoreSaberPlayerToken from "@ssr/common/types/token/scoresaber/score-saber-player-token";
|
import ScoreSaberPlayerToken from "@ssr/common/types/token/scoresaber/score-saber-player-token";
|
||||||
import { InternalServerError } from "../error/internal-server-error";
|
import { InternalServerError } from "../error/internal-server-error";
|
||||||
import ScoreSaberPlayerScoreToken from "@ssr/common/types/token/scoresaber/score-saber-player-score-token";
|
import ScoreSaberPlayerScoreToken from "@ssr/common/types/token/scoresaber/score-saber-player-score-token";
|
||||||
|
import { generatePlayerOgImage } from "../common/open-graph";
|
||||||
|
|
||||||
export class PlayerService {
|
export class PlayerService {
|
||||||
/**
|
/**
|
||||||
@ -155,4 +156,17 @@ export class PlayerService {
|
|||||||
`Updated scores set statistic for "${playerName}"(${playerId}), scores today: ${scores.rankedScores} ranked, ${scores.unrankedScores} unranked`
|
`Updated scores set statistic for "${playerName}"(${playerId}), scores today: ${scores.rankedScores} ranked, ${scores.unrankedScores} unranked`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the OpenGraph image for the player
|
||||||
|
*
|
||||||
|
* @param id the player's id
|
||||||
|
*/
|
||||||
|
public static async generateOpenGraphImage(id: string) {
|
||||||
|
const player = await scoresaberService.lookupPlayer(id);
|
||||||
|
if (player == undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return generatePlayerOgImage(player);
|
||||||
|
}
|
||||||
}
|
}
|
@ -10,5 +10,6 @@
|
|||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
|
"jsx": "react"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,15 +95,9 @@ export async function generateMetadata(props: Props): Promise<Metadata> {
|
|||||||
title: `${player.name}`,
|
title: `${player.name}`,
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: `ScoreSaber Reloaded - ${player.name}`,
|
title: `ScoreSaber Reloaded - ${player.name}`,
|
||||||
// description: `
|
|
||||||
// PP: ${formatPp(player.pp)}pp
|
|
||||||
// Rank: #${formatNumberWithCommas(player.rank)} (#${formatNumberWithCommas(player.countryRank)} ${player.country})
|
|
||||||
// Joined ScoreSaber: ${format(player.joinedDate, { date: "medium", time: "short" })}
|
|
||||||
//
|
|
||||||
// View the scores for ${player.name}!`,
|
|
||||||
images: [
|
images: [
|
||||||
{
|
{
|
||||||
url: `${config.siteUrl}/api/og/player/?id=${player.id}`,
|
url: `${config.siteApi}/player/og/${player.id}`,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user