123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759 |
- const presence = new Presence({
- clientId: "1273851679191728160",
- }),
- strings = presence.getStrings({
- play: "general.playing",
- pause: "general.paused",
- live: "general.live",
- }),
- baseImage =
- "https://cdn.rcd.gg/PreMiD/websites/I/iHeartRadio/assets/logo.png";
- function checkLength(string: string): string {
- if (string.length > 128) return `${string.substring(0, 125)}...`;
- else return string;
- }
- /**
- * @param {string} stationName
- * @returns {string|null}
- */
- async function getStationDesc(stationName: string) {
- const stationInfoReq = await fetch(
- `https://api.iheart.com/api/v2/content/liveStations?q=${new URLSearchParams(
- stationName
- )}`
- ),
- stationInfoRes = await stationInfoReq.json();
- if (stationInfoRes.total === 0) return null;
- return stationInfoRes.hits[0].description;
- }
- let stationDescription: string | null = null;
- presence.on("UpdateData", async () => {
- const presenceData: PresenceData = {
- largeImageKey: baseImage,
- details: "Browsing iHeartRadio...",
- };
- if (document.location.href.includes("www.iheart.com")) {
- switch (document.location.pathname) {
- case "/for-you/": {
- presenceData.details = "Viewing For You";
- break;
- }
- case "/your-library/": {
- presenceData.details = "Viewing Library";
- break;
- }
- case "/your-library/recently-played/": {
- presenceData.details = "Viewing Recently Played Library";
- break;
- }
- case "/your-library/saved-stations/": {
- presenceData.details = "Viewing Saved Stations Library";
- break;
- }
- case "/your-library/podcasts/": {
- presenceData.details = "Viewing Podcasts Library";
- break;
- }
- case "/your-library/playlists/": {
- presenceData.details = "Viewing Playlists Library";
- break;
- }
- case "/artist/": {
- presenceData.details = "Viewing Popular Artists";
- break;
- }
- case "/artist/genre/alternative/": {
- presenceData.details = "Viewing Alternative Artists";
- break;
- }
- case "/artist/genre/christian-gospel/": {
- presenceData.details = "Viewing Christian & Gospel Artists";
- break;
- }
- case "/artist/genre/classic-rock/": {
- presenceData.details = "Viewing Classic Rock Artists";
- break;
- }
- case "/artist/genre/classical/": {
- presenceData.details = "Viewing Classical Artists";
- break;
- }
- case "/artist/genre/college-radio/": {
- presenceData.details = "Viewing College Radio Artists";
- break;
- }
- case "/artist/genre/comedy/": {
- presenceData.details = "Viewing Comedy Artists";
- break;
- }
- case "/artist/genre/country/": {
- presenceData.details = "Viewing Country Artists";
- break;
- }
- case "/artist/genre/dance-electronic/": {
- presenceData.details = "Viewing Dance & Electronic Artists";
- break;
- }
- case "/artist/genre/hip-hop/": {
- presenceData.details = "Viewing Hip-Hop Artists";
- break;
- }
- case "/artist/genre/jazz-blues/": {
- presenceData.details = "Viewing Jazz & Blues Artists";
- break;
- }
- case "/artist/genre/kids-family/": {
- presenceData.details = "Viewing Kids & Family Artists";
- break;
- }
- case "/artist/genre/latin/": {
- presenceData.details = "Viewing Latin Artists";
- break;
- }
- case "/artist/genre/mix-variety/": {
- presenceData.details = "Viewing Mix & Variety Artists";
- break;
- }
- case "/artist/genre/oldies-classic-hits/": {
- presenceData.details = "Viewing Oldies & Classic Hits Artists";
- break;
- }
- case "/artist/genre/public-radio/": {
- presenceData.details = "Viewing Public Radio Artists";
- break;
- }
- case "/artist/genre/rb-throwbacks/": {
- presenceData.details = "Viewing R&B & Throwbacks Artists";
- break;
- }
- case "/artist/genre/reggae-island/": {
- presenceData.details = "Viewing Reggae & Island Artists";
- break;
- }
- case "/artist/genre/rock/": {
- presenceData.details = "Viewing Rock Artists";
- break;
- }
- case "/artist/genre/soft-rock/": {
- presenceData.details = "Viewing Soft Rock Artists";
- break;
- }
- case "/artist/genre/top-40-pop/": {
- presenceData.details = "Viewing Top 40 & Pop Artists";
- break;
- }
- case "/playlist/": {
- presenceData.details = "Viewing Playlists";
- break;
- }
- }
- if (
- (document.location.href.includes("live") &&
- document.querySelector('div[data-test="hero-container"]') &&
- !document.location.href.includes("/live/country/")) ||
- (document.location.href.includes("live") &&
- document.querySelector('div[data-test="hero-container"]') &&
- document.location.pathname !== "/live/")
- ) {
- const stationName = document
- .querySelector('div[data-test="hero-container"]')
- ?.querySelector("h1")?.textContent,
- stationDesc = document
- .querySelector('div[data-test="hero-container"]')
- ?.querySelector("h2")?.textContent;
- presenceData.details = stationName
- ? `Viewing ${stationName} Station`
- : "Viewing Station Page";
- presenceData.state = stationDesc;
- presenceData.largeImageKey =
- document
- .querySelector('div[data-test="hero-container"]')
- ?.querySelector("img")?.src ?? baseImage;
- presenceData.buttons = [
- {
- label: "View Station",
- url: document.location.href,
- },
- ];
- }
- if (
- document.location.href.includes("artist") &&
- document
- .querySelector('h1[data-test="artist-title"]')
- ?.querySelector("p")
- ?.querySelector("span") &&
- document.location.pathname !== "/artist/"
- ) {
- const artistName = document
- .querySelector('h1[data-test="artist-title"]')
- ?.querySelector("p")
- ?.querySelector("span")?.textContent;
- presenceData.details = "Viewing Artist";
- presenceData.state = artistName;
- presenceData.largeImageKey =
- document
- .querySelector('div[data-test="hero-artist"]')
- ?.querySelector("img")?.src ?? baseImage;
- presenceData.buttons = [
- {
- label: "View Artist",
- url: document.location.href,
- },
- ];
- }
- if (
- document.querySelector('div[data-test="control-set"]') &&
- document
- .querySelector('div[data-test="control-set"]')
- ?.querySelector('svg[aria-label="Stop Icon"]')
- ) {
- const playerArtwork = document
- .querySelector('div[data-test="player-artwork-image"]')
- ?.querySelector("div")
- ?.querySelector("img")?.src,
- metadataText =
- document
- .querySelector('div[data-test="player-text"]')
- ?.querySelectorAll("a") ?? null;
- presenceData.state = document
- .querySelector('div[data-test="player-text"]')
- ?.querySelector("a")?.textContent;
- presenceData.largeImageKey = playerArtwork ?? baseImage;
- presenceData.smallImageKey = Assets.Live;
- presenceData.smallImageText = (await strings).live;
- if (
- metadataText &&
- metadataText[0] &&
- metadataText[1] &&
- metadataText[2]
- ) {
- presenceData.details =
- metadataText[1]?.textContent && metadataText[2]?.textContent
- ? `${metadataText[1]?.textContent} · ${metadataText[2]?.textContent}`
- : "";
- presenceData.buttons = [
- {
- label: "View Station",
- url: metadataText[0]?.href ?? null,
- },
- ];
- }
- if (
- metadataText &&
- metadataText[1]?.getAttribute("href")?.includes("song") &&
- metadataText[2]?.getAttribute("href")?.includes("artist")
- ) {
- presenceData.buttons = [
- {
- label: "View Song",
- url:
- document.location.origin + metadataText[1]?.getAttribute("href"),
- },
- {
- label: "View Artist",
- url:
- document.location.origin + metadataText[2]?.getAttribute("href"),
- },
- ];
- }
- }
- if (
- document.querySelector('div[data-test="control-set"]') &&
- document
- .querySelector('div[data-test="control-set"]')
- ?.querySelector('svg[aria-label="Pause Icon"]')
- ) {
- const playerArtwork = document
- .querySelector('div[data-test="player-artwork-image"]')
- ?.querySelector("div")
- ?.querySelector("img")?.src,
- metadataText =
- document
- .querySelector('div[data-test="player-text"]')
- ?.querySelectorAll("a") ?? null,
- currentTime = presence.timestampFromFormat(
- document.querySelector('div[aria-label="Seekbar Position"]')
- ?.textContent
- ),
- timestamps = presence.getTimestamps(
- currentTime,
- presence.timestampFromFormat(
- document.querySelector('div[aria-label="Seekbar Duration"]')
- ?.textContent
- )
- );
- presenceData.state = document
- .querySelector('div[data-test="player-text"]')
- ?.querySelector("a")?.textContent;
- presenceData.details =
- metadataText &&
- metadataText[1]?.textContent &&
- metadataText[2]?.textContent
- ? `${metadataText[1]?.textContent} · ${metadataText[2]?.textContent}`
- : "";
- presenceData.largeImageKey = playerArtwork ?? baseImage;
- presenceData.smallImageKey = Assets.Play;
- presenceData.smallImageText = (await strings).play;
- presenceData.startTimestamp = timestamps[0];
- presenceData.endTimestamp = timestamps[1];
- if (
- metadataText &&
- metadataText[1]?.getAttribute("href")?.includes("song") &&
- metadataText[2]?.getAttribute("href")?.includes("artist")
- ) {
- presenceData.buttons = [
- {
- label: "View Song",
- url:
- document.location.origin + metadataText[1]?.getAttribute("href"),
- },
- {
- label: "View Artist",
- url:
- document.location.origin + metadataText[2]?.getAttribute("href"),
- },
- ];
- }
- }
- await presence.setActivity(presenceData);
- } else if (document.location.href.includes("listen.iheart.com")) {
- presenceData.details = "Browsing iHeartRadio [BETA]";
- switch (document.location.pathname) {
- case "/browse/live": {
- presenceData.details = "Viewing Search Stations";
- break;
- }
- case "/search": {
- presenceData.details = "Searching for Stations";
- break;
- }
- case "/library/live": {
- presenceData.details = "Viewing Library of Followed Stations";
- break;
- }
- case "/browse/artists": {
- presenceData.details = "Viewing Search Artists";
- break;
- }
- case "/browse/podcasts": {
- presenceData.details = "Viewing Search Podcasts";
- break;
- }
- case "/browse/playlists": {
- presenceData.details = "Viewing Search Playlists";
- break;
- }
- case "/library/artists": {
- presenceData.details = "Viewing Artists Library";
- break;
- }
- case "/library/podcasts": {
- presenceData.details = "Viewing Podcasts Library";
- break;
- }
- case "/library/playlists": {
- presenceData.details = "Viewing Playlists Library";
- break;
- }
- }
- if (
- document.location.href.includes("live") &&
- document.querySelector('main[data-test="main"]') &&
- !document.location.href.includes("/browse/live")
- ) {
- const stationName = document
- .querySelector('main[data-test="main"]')
- ?.querySelector("h1")?.textContent,
- stationArtwork = document
- .querySelector('main[data-test="main"]')
- ?.querySelector('div[data-test="image-container"]')
- ?.querySelector("img").src;
- presenceData.details = stationName
- ? `Viewing ${stationName} Station`
- : "Viewing Station Page";
- presenceData.state = document
- .querySelector('main[data-test="main"]')
- ?.querySelector("p").textContent;
- presenceData.largeImageKey = stationArtwork ?? baseImage;
- presenceData.buttons = [
- {
- label: "View Station",
- url: document.location.href,
- },
- ];
- }
- if (
- document.location.href.includes("artist") &&
- document.querySelector('main[data-test="main"]') &&
- !document.location.href.includes("/browse/artists")
- ) {
- const artistArtwork = document
- .querySelector('main[data-test="main"]')
- ?.querySelector('div[data-test="image-container"]')
- ?.querySelector("img").src;
- presenceData.details = "Viewing Artist";
- presenceData.state =
- document.querySelector('main[data-test="main"]')?.querySelector("h1")
- ?.textContent ?? "Unknown Artist";
- presenceData.largeImageKey = artistArtwork ?? baseImage;
- presenceData.buttons = [
- {
- label: "View Artist",
- url: document.location.href,
- },
- ];
- }
- if (
- document.location.href.includes("song") &&
- document.querySelector('main[data-test="main"]') &&
- document
- .querySelector('div[data-test="song-hero"]')
- ?.querySelector("p")
- ?.querySelector("a")
- ) {
- const songName = document
- .querySelector('main[data-test="main"]')
- ?.querySelector("h1")?.textContent,
- songArtwork = document
- .querySelector('main[data-test="main"]')
- ?.querySelector('div[data-test="image-container"]')
- ?.querySelector("img").src,
- songArtist = document
- .querySelector('div[data-test="song-hero"]')
- ?.querySelector("p")
- ?.querySelector("a");
- presenceData.details = "Viewing Song";
- presenceData.state =
- songName && songArtist?.textContent
- ? `${songName} · ${songArtist?.textContent}`
- : "Unknown Song";
- presenceData.largeImageKey = songArtwork;
- presenceData.buttons = [
- {
- label: "View Song",
- url: document.location.href,
- },
- {
- label: "View Artist",
- url: songArtist?.href ?? null,
- },
- ];
- }
- if (
- document.location.href.includes("album") &&
- document.querySelector('main[data-test="main"]') &&
- document
- .querySelector('div[data-test="album-hero"]')
- ?.querySelector("p")
- ?.querySelector("a")
- ) {
- const albumName = document
- .querySelector('main[data-test="main"]')
- ?.querySelector("h1")?.textContent,
- albumArtwork = document
- .querySelector('main[data-test="main"]')
- ?.querySelector('div[data-test="image-container"]')
- ?.querySelector("img").src,
- albumArtist = document
- .querySelector('div[data-test="album-hero"]')
- ?.querySelector("p")
- ?.querySelector("a");
- presenceData.details = "Viewing Album";
- presenceData.state =
- albumName && albumArtist?.textContent
- ? `${albumName} · ${albumArtist?.textContent}`
- : "Unknown Album";
- presenceData.largeImageKey = albumArtwork ?? baseImage;
- presenceData.buttons = [
- {
- label: "View Album",
- url: document.location.href,
- },
- {
- label: "View Artist",
- url: albumArtist?.href ?? null,
- },
- ];
- }
- if (
- document.location.href.includes("playlist") &&
- document.querySelector('main[data-test="main"]') &&
- document
- .querySelector('div[data-test="hero-container"]')
- ?.querySelector("h1")?.textContent
- ) {
- const playlistTitle = document
- .querySelector('div[data-test="hero-container"]')
- ?.querySelector("h1")?.textContent,
- playlistCreator = document
- .querySelector('div[data-test="hero-container"]')
- ?.querySelectorAll("p")[1]?.textContent;
- presenceData.details = "Viewing Playlist";
- presenceData.state =
- playlistTitle && playlistCreator
- ? `${playlistTitle} · ${playlistCreator}`
- : "Unknown Playlist";
- presenceData.largeImageKey =
- document
- .querySelector('div[data-test="image-container"]')
- ?.querySelector("img").src ?? baseImage;
- presenceData.buttons = [
- {
- label: "View Playlist",
- url: document.location.href,
- },
- ];
- }
- if (
- document.location.href.includes("podcast") &&
- document.querySelector('main[data-test="main"]') &&
- !document.location.href.includes("browse/podcasts")
- ) {
- const podcastName = document
- .querySelector('div[data-test="hero-container"]')
- ?.querySelector("h1")?.textContent,
- podcastIcon = document
- .querySelector('div[data-test="hero-container"]')
- ?.querySelector('div[data-test="image-container"]')
- ?.querySelector("img")?.src;
- presenceData.details = "Viewing Podcast";
- presenceData.state = podcastName ?? "Unknown Podcast";
- presenceData.largeImageKey = podcastIcon ?? baseImage;
- presenceData.buttons = [
- {
- label: "View Podcast",
- url: document.location.href,
- },
- ];
- }
- if (
- document.location.href.includes("episode") &&
- document.querySelector('main[data-test="main"]') &&
- !document.location.href.includes("browse/podcasts")
- ) {
- const episodeName = document
- .querySelector('main[data-test="main"]')
- ?.querySelector("h1")?.textContent,
- podcastIcon = document
- .querySelector('main[data-test="main"]')
- ?.querySelector('div[data-test="image-container"]')
- ?.querySelector("img")?.src,
- podcastName = document
- .querySelector('main[data-test="main"]')
- ?.querySelector("a");
- presenceData.details = episodeName
- ? `Viewing ${episodeName}`
- : "Viewing Unknown Episode";
- presenceData.state = podcastName?.textContent ?? "Unknown Podcast";
- presenceData.largeImageKey = podcastIcon ?? baseImage;
- presenceData.buttons = [
- {
- label: "View Episode",
- url: document.location.href,
- },
- {
- label: "View Podcast",
- url: podcastName?.href ?? null,
- },
- ];
- }
- if (
- document.querySelector('div[data-test="player-controls"]') &&
- document
- .querySelector('div[data-test="player-controls"]')
- ?.querySelector('button[data-test="player-play-button"]')
- ?.querySelector('svg[aria-label="Pause Icon"]')
- ) {
- const playerArtwork =
- document
- .querySelector('div[data-test="player-metadata"]')
- ?.querySelector('div[data-test="image-container"]')
- ?.querySelector("img")?.src ?? baseImage,
- songTitle = document.querySelector('a[data-test="title-link"]'),
- artist = document.querySelector('a[data-test="description-link"]'),
- stationName = document.querySelector('a[data-test="subtitle-link"]'),
- songPosition = document.querySelector(
- 'span[aria-label="position"][role="timer"][data-kind="caption-4"]'
- ),
- songDuration = document.querySelector(
- 'span[aria-label="duration"][role="timer"][data-kind="caption-4"]'
- ),
- timestamps = presence.getTimestamps(
- presence.timestampFromFormat(songPosition?.textContent),
- presence.timestampFromFormat(songDuration?.textContent)
- );
- presenceData.largeImageKey = playerArtwork
- ? `${playerArtwork}`
- : baseImage;
- presenceData.details =
- songTitle?.textContent && artist?.textContent
- ? `${songTitle?.textContent} · ${artist?.textContent}`
- : "";
- presenceData.state = stationName?.textContent;
- presenceData.smallImageKey = Assets.Play;
- presenceData.smallImageText = (await strings).play;
- presenceData.startTimestamp = timestamps[0];
- presenceData.endTimestamp = timestamps[1];
- if (
- artist?.getAttribute("href")?.includes("podcast") &&
- stationName?.getAttribute("href")?.includes("episode")
- ) {
- presenceData.details = checkLength(artist?.textContent);
- presenceData.state = checkLength(stationName?.textContent);
- presenceData.buttons = [
- {
- label: "View Episode",
- url: document.location.origin + stationName?.getAttribute("href"),
- },
- {
- label: "View Podcast",
- url: document.location.origin + artist?.getAttribute("href"),
- },
- ];
- }
- if (
- artist?.getAttribute("href")?.includes("artist") &&
- songTitle?.getAttribute("href")?.includes("song")
- ) {
- presenceData.buttons = [
- {
- label: "View Song",
- url: document.location.origin + songTitle?.getAttribute("href"),
- },
- {
- label: "View Artist",
- url: document.location.origin + artist?.getAttribute("href"),
- },
- ];
- }
- }
- if (
- document.querySelector('div[data-test="player-controls"]') &&
- document
- .querySelector('div[data-test="player-controls"]')
- ?.querySelector('button[data-test="player-play-button"]')
- ?.querySelector('svg[aria-label="Stop Icon"]')
- ) {
- const stationName = document.querySelector(
- 'a[data-test="subtitle-link"]'
- ),
- stationFallbackName = document.querySelector(
- 'a[data-test="fallback-subtitle-link"]'
- ),
- stationMetaTitle = document.querySelector('a[data-test="title-link"]'),
- stationFallbackDesc = document.querySelector(
- 'a[data-test="fallback-description-link"]'
- ),
- stationMetaDesc = document.querySelector(
- 'a[data-test="description-link"]'
- ),
- stationArtwork = document
- .querySelector('div[data-test="image-container"]')
- ?.querySelector("img")?.src;
- let stationArtWorkFixed;
- if (stationDescription && stationFallbackDesc?.textContent)
- stationDescription = null;
- if (!stationDescription && !stationFallbackDesc?.textContent) {
- stationName?.textContent
- ? (stationDescription = await getStationDesc(
- stationName?.textContent
- ))
- : (stationDescription = await getStationDesc(
- stationFallbackName?.textContent
- ));
- }
- if (stationArtwork && stationArtwork.includes("ops=cover"))
- stationArtWorkFixed = stationArtwork.replace("(400,400)", "(500,500)");
- presenceData.state =
- stationName?.textContent && stationDescription
- ? `${stationName?.textContent} · ${stationDescription}`
- : stationFallbackDesc?.textContent ?? stationName?.textContent;
- presenceData.details =
- stationMetaTitle && stationMetaDesc
- ? `${stationMetaTitle?.textContent} · ${stationMetaDesc?.textContent}`
- : stationFallbackName?.textContent;
- presenceData.smallImageKey = Assets.Live;
- presenceData.smallImageText = (await strings).live;
- presenceData.largeImageKey = stationArtWorkFixed
- ? `${stationArtWorkFixed}`
- : stationArtwork
- ? `${stationArtwork}`
- : baseImage;
- if (
- stationFallbackDesc?.getAttribute("href")?.includes("live") ||
- stationFallbackName?.getAttribute("href")?.includes("live")
- ) {
- presenceData.buttons = [
- {
- label: "View Station",
- url: stationFallbackDesc?.getAttribute("href")
- ? document.location.origin +
- stationFallbackDesc?.getAttribute("href")
- : document.location.origin +
- stationFallbackName?.getAttribute("href"),
- },
- ];
- }
- if (
- stationMetaTitle?.getAttribute("href")?.includes("song") &&
- stationMetaDesc?.getAttribute("href")?.includes("artist")
- ) {
- presenceData.buttons = [
- {
- label: "View Song",
- url:
- document.location.origin + stationMetaTitle?.getAttribute("href"),
- },
- {
- label: "View Artist",
- url:
- document.location.origin + stationMetaDesc?.getAttribute("href"),
- },
- ];
- }
- }
- await presence.setActivity(presenceData);
- }
- });
|