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",
|
||||
"@tqman/nice-logger": "^1.0.1",
|
||||
"@typegoose/typegoose": "^12.8.0",
|
||||
"@vercel/og": "^0.6.3",
|
||||
"elysia": "latest",
|
||||
"elysia-autoroutes": "^0.5.0",
|
||||
"elysia-decorators": "^1.0.2",
|
||||
"elysia-helmet": "^2.0.0",
|
||||
"elysia-rate-limit": "^4.1.0",
|
||||
"mongoose": "^8.7.0"
|
||||
"mongoose": "^8.7.0",
|
||||
"react": "^18.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bun-types": "latest"
|
||||
|
@ -1,19 +1,10 @@
|
||||
import { ImageResponse } from "next/og";
|
||||
import { scoresaberService } from "@ssr/common/service/impl/scoresaber";
|
||||
import { NextRequest } from "next/server";
|
||||
import { formatNumberWithCommas, formatPp } from "@/common/number-utils";
|
||||
import { config } from "../../../../../../config";
|
||||
|
||||
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 });
|
||||
}
|
||||
import { ImageResponse } from "@vercel/og";
|
||||
import { formatNumberWithCommas, formatPp } from "website/src/common/number-utils";
|
||||
import { config } from "website/config";
|
||||
import React from "react";
|
||||
import ScoreSaberPlayerToken from "@ssr/common/types/token/scoresaber/score-saber-player-token";
|
||||
|
||||
export function generatePlayerOgImage(player: ScoreSaberPlayerToken) {
|
||||
return new ImageResponse(
|
||||
(
|
||||
<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>
|
||||
</div>
|
||||
<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>
|
||||
</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 { InternalServerError } from "../error/internal-server-error";
|
||||
import ScoreSaberPlayerScoreToken from "@ssr/common/types/token/scoresaber/score-saber-player-score-token";
|
||||
import { generatePlayerOgImage } from "../common/open-graph";
|
||||
|
||||
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`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"jsx": "react"
|
||||
}
|
||||
}
|
||||
|
@ -95,15 +95,9 @@ export async function generateMetadata(props: Props): Promise<Metadata> {
|
||||
title: `${player.name}`,
|
||||
openGraph: {
|
||||
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: [
|
||||
{
|
||||
url: `${config.siteUrl}/api/og/player/?id=${player.id}`,
|
||||
url: `${config.siteApi}/player/og/${player.id}`,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
Reference in New Issue
Block a user