From 514f478f63eb6fa31917c9273a76ed7ce308ff69 Mon Sep 17 00:00:00 2001 From: equt <17521736+equt@users.noreply.github.com> Date: Thu, 27 Jun 2024 22:41:54 +0800 Subject: [PATCH] feat(route): introduce `/bluearchive/news` (#16012) * feat(route): introduce `/bluearchive/news` * fix: correct fetch typing --------- --- lib/routes/bluearchive/namespace.ts | 7 +++ lib/routes/bluearchive/news.ts | 88 +++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 lib/routes/bluearchive/namespace.ts create mode 100644 lib/routes/bluearchive/news.ts diff --git a/lib/routes/bluearchive/namespace.ts b/lib/routes/bluearchive/namespace.ts new file mode 100644 index 000000000..67595cd5b --- /dev/null +++ b/lib/routes/bluearchive/namespace.ts @@ -0,0 +1,7 @@ +import type { Namespace } from '@/types'; + +export const namespace: Namespace = { + name: 'Blue Archive', + url: 'bluearchive.jp', + categories: ['game'], +}; diff --git a/lib/routes/bluearchive/news.ts b/lib/routes/bluearchive/news.ts new file mode 100644 index 000000000..ff2e23864 --- /dev/null +++ b/lib/routes/bluearchive/news.ts @@ -0,0 +1,88 @@ +import type { Route } from '@/types'; +import ofetch from '@/utils/ofetch'; +import { parseDate } from '@/utils/parse-date'; + +// type id => display name +type Mapping = Record; + +const JP: Mapping = { + '0': '全て', + '1': 'メンテナンス', + '2': 'お知らせ', + '3': 'イベント', +}; + +// render into MD table +const mkTable = (mapping: Mapping): string => { + const heading: string[] = [], + separator: string[] = [], + body: string[] = []; + + for (const key in mapping) { + heading.push(mapping[key]); + separator.push(':--:'); + body.push(key); + } + + return [heading.join(' | '), separator.join(' | '), body.join(' | ')].map((s) => `| ${s} |`).join('\n'); +}; + +const handler: Route['handler'] = async (ctx) => { + const { server } = ctx.req.param(); + + switch (server.toUpperCase()) { + case 'JP': + return await ja(ctx); + default: + throw []; + } +}; + +const ja: Route['handler'] = async (ctx) => { + const { type = '0' } = ctx.req.param(); + + const data = await ofetch<{ data: { rows: { id: number; content: string; summary: string; publishTime: number }[] } }, 'json'>('https://api-web.bluearchive.jp/api/news/list', { + params: { + typeId: type, + pageNum: 16, + pageIndex: 1, + }, + }); + + return { + title: `ブルアカ - ${JP[type]}`, + link: 'https://bluearchive.jp/news/newsJump', + language: 'ja-JP', + image: 'https://webcnstatic.yostar.net/ba_cn_web/prod/web/favicon.png', // The CN website has a larger one + icon: 'https://webcnstatic.yostar.net/ba_cn_web/prod/web/favicon.png', + logo: 'https://webcnstatic.yostar.net/ba_cn_web/prod/web/favicon.png', + item: data.data.rows.map((row) => ({ + title: row.summary, + description: row.content, + link: `https://bluearchive.jp/news/newsJump/${row.id}`, + pubDate: parseDate(row.publishTime), + })), + }; +}; + +export const route: Route = { + path: '/news/:server/:type?', + name: 'News', + categories: ['game'], + maintainers: ['equt'], + example: '/bluearchive/news/jp', + parameters: { + server: 'game server (ISO 3166 two-letter country code, case-insensitive), only `JP` is supported for now', + type: 'news type, checkout the table below for details', + }, + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, + handler, + description: [JP].map((el) => mkTable(el)).join('\n\n'), +};