2025-09-28 17:55:05 +03:00
const axios = require ( 'axios' )
const dayjs = require ( 'dayjs' )
const utc = require ( 'dayjs/plugin/utc' )
const parseDuration = require ( 'parse-duration' ) . default
dayjs . extend ( utc )
module . exports = {
site : 'freeview.co.uk' ,
days : 2 ,
url ( { date , channel } ) {
const [ networkId ] = channel . site _id . split ( '#' )
const startTimestamp = date . startOf ( 'd' ) . unix ( )
return ` https://www.freeview.co.uk/api/tv-guide?nid= ${ networkId } &start= ${ startTimestamp } `
} ,
2025-10-31 11:00:28 +00:00
async parser ( { content , channel } ) {
2025-09-28 17:55:05 +03:00
let programs = [ ]
let items = parseItems ( content , channel )
2025-10-31 11:00:28 +00:00
for ( const item of items ) {
2025-09-28 17:55:05 +03:00
const start = parseStart ( item )
const duration = parseDuration ( item . duration )
const stop = start . add ( duration , 'ms' )
2025-10-31 11:00:28 +00:00
const details = await loadProgramDetails ( item )
const synopsis = details ? . synopsis
2025-09-28 17:55:05 +03:00
programs . push ( {
title : item . main _title ,
subtitle : item . secondary _title ,
2025-10-31 11:00:28 +00:00
description : synopsis ? . long || synopsis ? . medium || synopsis ? . short || null ,
2025-09-28 17:55:05 +03:00
image : parseImage ( item ) ,
start ,
stop
} )
2025-10-31 11:00:28 +00:00
}
2025-09-28 17:55:05 +03:00
return programs
} ,
async channels ( ) {
const startTimestamp = dayjs . utc ( ) . startOf ( 'd' ) . unix ( )
2026-04-22 16:16:53 +01:00
let channels = [ ]
for ( let networkId = 64257 ; networkId <= 64425 ; networkId ++ ) { // loop through all valid networkIds starting from 64257 (Greater London) to 64425 (Belfast) to ensure we can get all the channels available on freeview
console . log ( networkId )
const data = await axios
. get ( ` https://www.freeview.co.uk/api/tv-guide?nid= ${ networkId } &start= ${ startTimestamp } ` )
. then ( r => r . data )
. catch ( console . log )
2025-09-28 17:55:05 +03:00
2026-04-22 16:16:53 +01:00
channels = channels . concat ( data . data . programs . map ( item => ( {
lang : 'en' ,
site _id : ` ${ networkId } # ${ item . service _id } ` ,
name : item . title
} ) ) )
}
const uniqueServiceIds = Array . from ( new Set ( channels . map ( c => c . site _id . split ( '#' ) [ 1 ] ) ) )
return uniqueServiceIds . map ( serviceId => {
return channels . find ( c => c . site _id . split ( '#' ) [ 1 ] === serviceId )
} )
2025-09-28 17:55:05 +03:00
}
}
function parseImage ( item ) {
return item . image _url ? ` ${ item . image _url } ?w=800 ` : null
}
function parseStart ( item ) {
return dayjs ( item . start _time )
}
function parseItems ( content , channel ) {
try {
const data = JSON . parse ( content )
const programs = data ? . data ? . programs
if ( ! Array . isArray ( programs ) ) return [ ]
const [ , channelId ] = channel . site _id . split ( '#' )
const channelData = programs . find ( p => p . service _id === channelId )
const channelPrograms = channelData ? . events
if ( ! Array . isArray ( channelPrograms ) ) return [ ]
return channelPrograms
} catch {
return [ ]
}
}
2025-10-31 11:00:28 +00:00
async function loadProgramDetails ( item ) {
const url = ` https://www.freeview.co.uk/api/program?pid= ${ item . program _id } &start_time= ${ item . start _time } &duration= ${ item . duration } `
const data = await axios
. get ( url )
. then ( r => {
const programs = r ? . data ? . data ? . programs
return Array . isArray ( programs ) && programs . length > 0 ? programs [ 0 ] : { }
} )
. catch ( console . log )
return data || { }
2026-04-22 16:16:53 +01:00
}