UNPKG

rsshub

Version:
94 lines (81 loc) 3.41 kB
import { Route } from '@/types'; import cache from '@/utils/cache'; import got from '@/utils/got'; export const route: Route = { path: '/manga/update/:comicid', categories: ['social-media'], example: '/bilibili/manga/update/26009', parameters: { comicid: '漫画 id, 可在 URL 中找到, 支持带有`mc`前缀' }, features: { requireConfig: false, requirePuppeteer: false, antiCrawler: false, supportBT: false, supportPodcast: false, supportScihub: false, }, radar: [ { source: ['manga.bilibili.com/detail/:comicid'], }, ], name: '漫画更新', maintainers: ['hoilc'], handler, }; // Based on https://github.com/SocialSisterYi/bilibili-API-collect/issues/1168#issuecomment-2620749895 async function genReqSign(query, body) { // Don't import on top-level to avoid a cyclic dependency - wasm-exec.js generated via `pnpm build`, which in turn needs wasm-exec.js to import routes correctly const { Go } = await import('./wasm-exec'); // Cache the wasm binary as it's quite large (~2MB) // Here the binary is saved as base64 as the cache stores strings const wasmBufferBase64 = await cache.tryGet('bilibili-manga-wasm-20250208', async () => { const wasmResp = await got('https://s1.hdslb.com/bfs/manga-static/manga-pc/6732b1bf426cfc634293.wasm', { responseType: 'arrayBuffer', }); return Buffer.from(wasmResp.data).toString('base64'); }); const wasmBuffer = Buffer.from(wasmBufferBase64, 'base64'); const go = new Go(); const { instance } = await WebAssembly.instantiate(wasmBuffer, go.importObject); go.run(instance); if (void 0 === globalThis.genReqSign) { throw new Error('WASM function not available'); } const signature = globalThis.genReqSign(query, body, Date.now()); return signature.sign; } async function handler(ctx) { const comic_id = ctx.req.param('comicid').startsWith('mc') ? ctx.req.param('comicid').replace('mc', '') : ctx.req.param('comicid'); const link = `https://manga.bilibili.com/detail/mc${comic_id}`; const spi_response = await got('https://api.bilibili.com/x/frontend/finger/spi'); const query = 'device=pc&platform=web&nov=25'; const body = JSON.stringify({ comic_id: Number(comic_id), }); const ultraSign = await genReqSign(query, body); const response = await got({ method: 'POST', url: `https://manga.bilibili.com/twirp/comic.v2.Comic/ComicDetail?${query}&ultra_sign=${ultraSign}`, body, headers: { Referer: link, Cookie: `buvid3=${spi_response.data.data.b_3}; buvid4=${spi_response.data.data.b_4}`, }, }); const data = response.data.data; const author = data.author_name.join(', '); return { title: `${data.title} - 哔哩哔哩漫画`, link, image: data.vertical_cover, description: data.classic_lines, item: data.ep_list.slice(0, 20).map((item) => ({ title: item.short_title === item.title ? item.short_title : `${item.short_title} ${item.title}`, author, description: `<img src="${item.cover}">`, pubDate: new Date(item.pub_time + ' +0800'), link: `https://manga.bilibili.com/mc${comic_id}/${item.id}`, })), }; }