diff --git a/bot/README.md b/bot/README.md index 215e23f6c..4226ba4a9 100644 --- a/bot/README.md +++ b/bot/README.md @@ -8,7 +8,7 @@ Automatically translate streaming service links. ## Platform Support -This bot supports every platform the [song.link](song.link) platform supports as it takes advantage of its API. +This bot supports every platform the [song.link](https://song.link) platform supports as it takes advantage of its API. Currently, it detects the following URL Schemes: diff --git a/bot/src/config.ts b/bot/src/config.ts index 2fe5d070d..99a8ebac9 100644 --- a/bot/src/config.ts +++ b/bot/src/config.ts @@ -8,6 +8,7 @@ export enum LoggerLayers { client = "client", songLink = "songLink", embedGenerator = "embedGenerator", + deezerMetadata = "deezerMetadata", slashCommands = "slashCommands" } diff --git a/bot/src/getSongLink/getSongLink.test.ts b/bot/src/getSongLink/getSongLink.test.ts index 6132fb8df..ed6448275 100644 --- a/bot/src/getSongLink/getSongLink.test.ts +++ b/bot/src/getSongLink/getSongLink.test.ts @@ -72,7 +72,7 @@ const nonDeezerMockSongData: MockSonglinkResponse = { describe("getDetailedMetadata", () => { test("Should fetch detailed metadata for a song", async () => { expect(await getDetailedMetadata(mockSongData as SonglinkResponse)) - .toHaveProperty("artistName", "Neutral Milk Hotel"); + .toHaveProperty("releaseYear", "2005-09-06"); }); test("Should fetch detailed metadata for an album", async () => { expect(await getDetailedMetadata(mockAlbumData as SonglinkResponse)) diff --git a/bot/src/getSongLink/getSongLink.ts b/bot/src/getSongLink/getSongLink.ts index d862b47b8..dc327f1b7 100644 --- a/bot/src/getSongLink/getSongLink.ts +++ b/bot/src/getSongLink/getSongLink.ts @@ -1,13 +1,13 @@ import { getLinks } from "songlink-api"; -import * as deezerApi from "deezer-api-ts"; import { SonglinkPlatform } from "songlink-api/lib/types/Platform"; import { SonglinkResponse } from "songlink-api/lib/types/Response"; import { LoggerLayers } from "../config"; import { createLayeredLogger } from "../utils/logger"; +import { getDeezerMetadata } from "./metadata/deezer"; const logger = createLayeredLogger(LoggerLayers.songLink); -interface MetaData { +export interface MetaData { title?: string; artistName?: string; artwork?: string; @@ -40,41 +40,7 @@ export const getIdFromEntity = (entity: string): string => { export const getDetailedMetadata = async (data: SonglinkResponse): Promise => { if (data.linksByPlatform.deezer) { - try { - logger.info("Fetching metadata from Deezer"); - - const entityId = getIdFromEntity(data.linksByPlatform.deezer.entityUniqueId); - - let metaData; - if (data.linksByPlatform.deezer.entityUniqueId.includes("SONG")) { - const songMetaData = await deezerApi.getTrack(parseInt(entityId)); - metaData = { - title: songMetaData.title, - artist: songMetaData.artist, - artwork: songMetaData.album?.cover || "" - }; - } else { - metaData = await deezerApi.getAlbum(parseInt(entityId)); - } - - - if (!metaData.title) { - logger.warn("Attempted to fetch metadata from deezer but received empty response"); - return; - } - - logger.info(`Successfully fetched metadata for ${metaData.title}`); - - return { - title: metaData.title, - artistName: metaData.artist.name, - artwork: metaData.cover, - genres: metaData.genres?.data.map(genre => genre.name), - releaseYear: metaData.release_date - }; - } catch (e) { - logger.error("Unable to fetch metadata from Deezer:", e); - } + return await getDeezerMetadata(data); } else { logger.warn("Requested metaData but it is not on any supported streaming services"); } diff --git a/bot/src/getSongLink/metadata/deezer.ts b/bot/src/getSongLink/metadata/deezer.ts new file mode 100644 index 000000000..9ba18db67 --- /dev/null +++ b/bot/src/getSongLink/metadata/deezer.ts @@ -0,0 +1,52 @@ +import * as deezerApi from "deezer-api-ts"; +import { SonglinkResponse } from "songlink-api/lib/types/Response"; +import { LoggerLayers } from "../../config"; +import { createLayeredLogger } from "../../utils/logger"; +import { getIdFromEntity, MetaData } from "../getSongLink"; + +const logger = createLayeredLogger(LoggerLayers.deezerMetadata); + +export const getDeezerMetadata = async (data: SonglinkResponse): Promise => { + try { + logger.info("Fetching metadata from Deezer"); + + const entityId = getIdFromEntity(data.linksByPlatform.deezer.entityUniqueId); + + let metaData; + if (data.linksByPlatform.deezer.entityUniqueId.includes("SONG")) { + const songMetaData = await deezerApi.getTrack(parseInt(entityId)); + let albumMetadata; + if (songMetaData.album.id) { + albumMetadata = await deezerApi.getAlbum(songMetaData.album.id); + } + + metaData = { + title: songMetaData.title, + artist: songMetaData.artist, + artwork: songMetaData.album?.cover || "", + genres: albumMetadata?.genres || undefined, + release_date: albumMetadata?.release_date || undefined + }; + } else { + metaData = await deezerApi.getAlbum(parseInt(entityId)); + } + + + if (!metaData.title) { + logger.warn("Attempted to fetch metadata from deezer but received empty response"); + return; + } + + logger.info(`Successfully fetched metadata for ${metaData.title}`); + + return { + title: metaData.title, + artistName: metaData.artist.name, + artwork: metaData.cover, + genres: metaData.genres?.data.map(genre => genre.name), + releaseYear: metaData.release_date + }; + } catch (e) { + logger.error("Unable to fetch metadata from Deezer:", e); + } +};