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 { private readonly logger = new Logger(NowPlayingService.name); 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 }, ) { const nowPlaying = await this.prisma.nowPlaying.upsert({ where: { stationId }, create: { stationId, song: data.song, artist: data.artist, coverUrl: data.coverUrl, }, update: { song: data.song, artist: data.artist, coverUrl: data.coverUrl, }, }); this.gateway.broadcastNowPlaying(stationId, { song: data.song, artist: data.artist, coverUrl: data.coverUrl, updatedAt: nowPlaying.updatedAt, }); return nowPlaying; } async getNowPlaying(stationId: string) { return this.prisma.nowPlaying.findUnique({ where: { stationId }, }); } async getAllNowPlaying() { return this.prisma.nowPlaying.findMany({ include: { station: true }, }); } }