re-add per page/leaderboard embed colors
All checks were successful
Deploy Backend / deploy (push) Successful in 3m31s
Deploy Website / deploy (push) Successful in 5m17s

This commit is contained in:
Lee
2024-10-16 07:31:52 +01:00
parent 7f42a27d8f
commit ff9408fb8c
12 changed files with 131 additions and 22 deletions

View File

@ -9,11 +9,58 @@ import NodeCache from "node-cache";
import ScoreSaberLeaderboardToken from "@ssr/common/types/token/scoresaber/score-saber-leaderboard-token";
import ScoreSaberPlayer, { getScoreSaberPlayerFromToken } from "@ssr/common/types/player/impl/scoresaber-player";
import { Config } from "../common/config";
import ky from "ky";
import { createCanvas, loadImage } from "canvas";
import { extractColors } from "extract-colors";
const cache = new NodeCache({ stdTTL: 60 * 60, checkperiod: 120 });
const imageOptions = { width: 1200, height: 630 };
export class ImageService {
/**
* Gets the average color of an image
*
* @param src the image url
* @returns the average color
* @private
*/
public static async getAverageImageColor(src: string): Promise<{ color: string } | undefined> {
src = decodeURIComponent(src);
return await this.fetchWithCache<{ color: string }>(`average_color-${src}`, async () => {
try {
const response = await ky.get(src);
if (response.status !== 200) {
throw new Error(`Failed to fetch image: ${src}`);
}
const imageBuffer = await response.arrayBuffer();
// Create an image from the buffer using canvas
const img = await loadImage(Buffer.from(imageBuffer));
const canvas = createCanvas(img.width, img.height);
const ctx = canvas.getContext("2d");
// Draw the image onto the canvas
ctx.drawImage(img, 0, 0);
// Get the pixel data from the canvas
const imageData = ctx.getImageData(0, 0, img.width, img.height);
const { data, width, height } = imageData;
// Extract the colors
const color = await extractColors({ data, width, height });
return {
color: color[2].hex,
};
} catch (error) {
return {
color: "#fff",
};
}
});
}
/**
* Fetches data with caching.
*

View File

@ -0,0 +1,36 @@
import ScoreSaberPlayerScoreToken from "@ssr/common/types/token/scoresaber/score-saber-player-score-token";
// @ts-ignore
import { MessageBuilder, Webhook } from "discord-webhook-node";
import { Config } from "../common/config";
import { formatPp } from "@ssr/common/utils/number-utils";
export class ScoreService {
public static async notifyNumberOne(playerScore: ScoreSaberPlayerScoreToken) {
const { score, leaderboard } = playerScore;
const player = score.leaderboardPlayerInfo;
// Not ranked
if (leaderboard.stars <= 0) {
return;
}
// Not #1 rank
if (score.rank !== 1) {
return;
}
const hook = new Webhook({
url: Config.numberOneWebhook,
});
hook.setUsername("Number One Feed");
const embed = new MessageBuilder();
embed.setTitle(`${player.name} set a #${score.rank} on ${leaderboard.songName} ${leaderboard.songSubName}`);
embed.setDescription(`
**Player:** https://ssr.fascinated.cc/player/${player.id}
**Leaderboard:** https://ssr.fascinated.cc/leaderboard/${leaderboard.id}
**PP:** ${formatPp(score.pp)}
`);
embed.setThumbnail(leaderboard.coverImage);
embed.setColor("#00ff00");
await hook.send(embed);
}
}