feat: now-playing polling from Record API with station mapping and WebSocket broadcast

This commit is contained in:
nk
2026-06-02 19:31:48 +03:00
parent 2ae682fb68
commit 7823b17d55
4 changed files with 219 additions and 15 deletions

View File

@@ -1,6 +1,22 @@
import { Injectable, Logger } from '@nestjs/common';
import { Interval } from '@nestjs/schedule';
import { PrismaService } from '../prisma/prisma.service';
import { NowPlayingGateway } from './now-playing.gateway';
import { RecordStationSyncService } from './record-station-sync.service';
interface RecordTrack {
id: number;
artist: string;
song: string;
image100?: string;
image200?: string;
image600?: string;
}
interface RecordNowPlayingItem {
id: number;
track: RecordTrack;
}
@Injectable()
export class NowPlayingService {
@@ -9,8 +25,60 @@ export class NowPlayingService {
constructor(
private readonly prisma: PrismaService,
private readonly gateway: NowPlayingGateway,
private readonly recordSync: RecordStationSyncService,
) {}
@Interval(30000)
async pollRecordNowPlaying() {
try {
const response = await fetch(
'https://www.radiorecord.ru/api/stations/now/',
{ headers: { 'Accept-Encoding': 'gzip, deflate' } },
);
if (!response.ok) {
this.logger.warn(`Record API returned ${response.status}`);
return;
}
const data = (await response.json()) as {
result: RecordNowPlayingItem[];
};
const nowPlaying = data.result ?? [];
for (const np of nowPlaying) {
const stationId =
this.recordSync.getStationIdByNowPlayingId(np.id);
if (!stationId) continue;
const coverUrl = np.track.image600 ?? np.track.image200 ?? np.track.image100;
const updated = await this.prisma.nowPlaying.upsert({
where: { stationId },
create: {
stationId,
song: np.track.song,
artist: np.track.artist,
coverUrl,
},
update: {
song: np.track.song,
artist: np.track.artist,
coverUrl,
},
});
this.gateway.broadcastNowPlaying(stationId, {
song: np.track.song,
artist: np.track.artist,
coverUrl,
updatedAt: updated.updatedAt,
});
}
} catch (error) {
this.logger.error(`Failed to poll now playing: ${error.message}`);
}
}
async updateNowPlaying(
stationId: string,
data: { song: string; artist: string; coverUrl?: string },