Created
February 8, 2018 01:50
-
-
Save kaorun343/faea90c8a6ef4183915f7531d91fa47a to your computer and use it in GitHub Desktop.
NHKのAPI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as http from 'http' | |
interface List { | |
/** 番組 */ | |
readonly list: { | |
readonly [key: string]: Program | |
} | |
} | |
interface DescriptionList { | |
/** 番組 */ | |
readonly list: { | |
readonly [key: string]: Description | |
} | |
} | |
interface NowOnAirList { | |
/** 現在提供中の番組 */ | |
readonly nowonair_list: { | |
readonly [key: string]: NonOnAir | |
} | |
} | |
export interface NonOnAir { | |
/** 前に放送した番組 */ | |
readonly previous?: Program | |
/** 現在放送中の番組 */ | |
readonly present: Program | |
/** 次に放送予定の番組 */ | |
readonly following?: Program | |
} | |
export interface Program { | |
/** 番組ID */ | |
readonly id: number | |
/** 番組イベントID */ | |
readonly event_id: number | |
/** 放送開始日時(YYYY-MM-DDTHH:mm:ssZ形式) */ | |
readonly start_time: string | |
/** 放送終了日時(YYYY-MM-DDTHH:mm:ssZ形式) */ | |
readonly end_time: string | |
/** Areaオブジェクト */ | |
readonly area: Area | |
/** Serviceオブジェクト */ | |
readonly service: Service | |
/** 番組名 */ | |
readonly title: string | |
/** 番組内容 */ | |
readonly subtitle: string | |
/** 番組ジャンル */ | |
readonly genres: string[] | |
} | |
export interface Description { | |
/** 番組ID */ | |
readonly id: number | |
/** 番組イベントID */ | |
readonly event_id: number | |
/** 放送開始日時(YYYY-MM-DDTHH:mm:ssZ形式) */ | |
readonly start_time: string | |
/** 放送終了日時(YYYY-MM-DDTHH:mm:ssZ形式) */ | |
readonly end_time: string | |
/** Areaオブジェクト */ | |
readonly area: Area | |
/** Serviceオブジェクト */ | |
readonly service: Service | |
/** 番組名 */ | |
readonly title: string | |
/** 番組内容 */ | |
readonly subtitle: string | |
/** 番組詳細 */ | |
readonly content: string | |
/** 出演者 */ | |
readonly act: string | |
/** 番組ジャンル */ | |
readonly genres: string[] | |
/** 番組ロゴ画像(Logoオブジェクト) */ | |
readonly program_logo: Logo | |
/** 番組サイトURL(番組単位) */ | |
readonly program_url?: string | |
/** 番組サイトURL(放送回単位) */ | |
readonly episode_url?: string | |
/** 番組に関連するハッシュタグ */ | |
readonly hashtags: string | |
} | |
export interface Area { | |
/** 地域ID */ | |
readonly id: number | |
/** 地域名 */ | |
readonly name: string | |
} | |
export interface Service { | |
/** サービスID */ | |
readonly id: string | |
/** サービス名 */ | |
readonly name: string | |
/** サービスロゴ画像:小(Logoオブジェクト) */ | |
readonly logo_s: Logo | |
/** サービスロゴ画像:中(Logoオブジェクト) */ | |
readonly logo_m: Logo | |
/** サービスロゴ画像:大(Logoオブジェクト) */ | |
readonly logo_l: Logo | |
} | |
export interface Logo { | |
/** ロゴ画像のURL */ | |
readonly url?: string | |
/** ロゴ画像の幅 */ | |
readonly width?: number | |
/** ロゴ画像の高さ */ | |
readonly height?: number | |
} | |
/** | |
* 放送地域、サービス(放送波)、日付を指定することで、該当する番組表情報を取得することが可能です。 | |
* @param area 地域ID | |
* @param service サービスID | |
* @param date 日付 | |
*/ | |
export function getProgramList(area: string, service: string, date: string) { | |
const url = buildUrl('list', area, service, date) | |
return getData<List>(url).then(list => list.list[area]) | |
} | |
/** | |
* 放送地域、EPG番組ジャンル、日付を指定することで、該当する条件の番組リストを取得することが可能です。 | |
* @param area 地域ID | |
* @param service サービスID | |
* @param genre ジャンルID | |
* @param date 日付 | |
*/ | |
export function getProgramGenre(area: string, service: string, genre: string, date: string) { | |
const url = buildUrl('genre', area, service, genre, date) | |
return getData<List>(url).then(list => list.list[area]) | |
} | |
/** | |
* 番組IDを指定することで、該当する番組の詳細情報を取得することが可能です。 | |
* @param area 地域ID | |
* @param service サービスID | |
* @param id 番組ID | |
*/ | |
export function getProgramInfo(area: string, service: string, id: string) { | |
const url = buildUrl('info', area, service, id) | |
return getData<DescriptionList>(url).then(list => list.list[area]) | |
} | |
/** | |
* 放送地域、サービス(放送波)を指定することで、現在放送している番組情報を取得することが可能です。 | |
* @param area 地域ID | |
* @param service サービスID | |
*/ | |
export function getNowOnAir(area: string, service: string) { | |
const url = buildUrl('now', area, service) | |
return getData<NowOnAirList>(url).then(list => list.nowonair_list[area]) | |
} | |
function buildUrl(...params: string[]) { | |
const apikey = '' | |
const domain = 'http://api/nhk/or.jp/v2/pg' | |
const joined = params.join('/') | |
return `${domain}/${joined}.json?key=${apikey}` | |
} | |
function getData<T>(url: string) { | |
return new Promise<T>((resolve, reject) => { | |
http.get(url, response => { | |
const error = checkError(response) | |
if (error) { | |
response.resume() | |
reject(error) | |
return | |
} | |
let rawData = '' | |
response.on('data', chunck => { | |
rawData += chunck | |
}) | |
response.on('end', () => { | |
try { | |
const parsedData = JSON.parse(rawData) | |
resolve(parsedData) | |
} catch (e) { | |
reject(e) | |
} | |
}) | |
}).on('error', e => { | |
reject(e) | |
}) | |
}) | |
} | |
function checkError(response: http.IncomingMessage) { | |
const { statusCode } = response | |
const contentType = response.headers['content-type']! | |
if (statusCode !== 200) { | |
return new Error(`Request Failed. Status Code: ${statusCode}`) | |
} else if (!/^application\/json/.test(contentType)) { | |
return new Error(`Invalid content-type. Expected application/json but recieved ${contentType}`) | |
} | |
return | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment