feat: now-playing polling from Record API with station mapping and WebSocket broadcast
This commit is contained in:
@@ -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 },
|
||||
|
||||
Reference in New Issue
Block a user