diff --git a/README.md b/README.md index 1ba0aef..b8d910f 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ | 36 氪 | 热榜 | 36kr | 🟢 | | 51CTO | 推荐榜 | 51cto | 🟢 | | CSDN | 排行榜 | csdn | 🟢 | -| NodeSeek | 最新动态 | nodeseek | 🟢 | +| NodeSeek | 最新动态 | nodeseek | 🟠 | | 稀土掘金 | 热榜 | juejin | 🟢 | | 腾讯新闻 | 热点榜 | qq-news | 🟢 | | 新浪网 | 热榜 | sina | 🟢 | @@ -62,6 +62,7 @@ | 吾爱破解 | 榜单 | 52pojie | ❌ | | 全球主机交流 | 榜单 | hostloc | ❌ | | 虎嗅 | 24小时 | huxiu | 🟢 | +| 酷安 | 热榜 | coolapk | 🟢 | | 虎扑 | 步行街热帖 | hupu | 🟢 | | 爱范儿 | 快讯 | ifanr | 🟢 | | 英雄联盟 | 更新公告 | lol | 🟢 | @@ -72,8 +73,8 @@ | NGA | 热帖 | ngabbs | 🟢 | | V2EX | 主题榜 | v2ex | ⚠️ | | HelloGitHub | Trending | hellogithub | 🟢 | -| 中央气象台 | 全国气象预警 | weatheralarm | 🟢 | -| 中国地震台 | 地震速报 | earthquake | 🟢 | +| 中央气象台 | 全国气象预警 | weatheralarm | 🟠 | +| 中国地震台 | 地震速报 | earthquake | 🟠 | | 历史上的今天 | 月-日 | history | 🟢 | diff --git a/package.json b/package.json index 0cf50c6..760dc5a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dailyhot-api", - "version": "2.0.5", + "version": "2.0.6", "description": "An Api on Today's Hot list", "keywords": [ "API", diff --git a/src/router.types.d.ts b/src/router.types.d.ts index 465395f..d410565 100644 --- a/src/router.types.d.ts +++ b/src/router.types.d.ts @@ -127,6 +127,7 @@ export type RouterType = { cover: string; created_at: number; view_status: number; + images: string[]; }; user: { nickname: string; @@ -305,4 +306,13 @@ export type RouterType = { top_num: string; time: string; }; + coolapk: { + id: number; + ttitle: string; + shareUrl: string; + username:string; + tpic: string; + message: string; + replynum: number; + }; }; diff --git a/src/routes/coolapk.ts b/src/routes/coolapk.ts new file mode 100644 index 0000000..992a37a --- /dev/null +++ b/src/routes/coolapk.ts @@ -0,0 +1,45 @@ +import type { RouterData } from "../types.js"; +import type { RouterType } from "../router.types.js"; +import { get } from "../utils/getData.js"; +import { genHeaders } from "../utils/getToken/coolapk.js"; + +export const handleRoute = async (_: undefined, noCache: boolean) => { + const { fromCache, data, updateTime } = await getList(noCache); + const routeData: RouterData = { + name: "coolapk", + title: "酷安", + type: "热榜", + link: "https://www.coolapk.com/", + total: data?.length || 0, + updateTime, + fromCache, + data, + }; + return routeData; +}; + +const getList = async (noCache: boolean) => { + const url = `https://api.coolapk.com/v6/page/dataList?url=/feed/statList?cacheExpires=300&statType=day&sortField=detailnum&title=今日热门&title=今日热门&subTitle=&page=1`; + const result = await get({ + url, + noCache, + headers: await genHeaders(), + }); + const list = result.data.data; + console.log(list); + return { + fromCache: result.fromCache, + updateTime: result.updateTime, + data: list.map((v: RouterType["coolapk"]) => ({ + id: v.id, + title: v.message, + cover: v.tpic, + author: v.username, + desc: v.ttitle, + timestamp: null, + hot: null, + url: v.shareUrl, + mobileUrl: v.shareUrl, + })), + }; +}; diff --git a/src/routes/genshin.ts b/src/routes/genshin.ts index 1ba2cc6..4a2d3b8 100644 --- a/src/routes/genshin.ts +++ b/src/routes/genshin.ts @@ -31,7 +31,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => { const getList = async (options: Options, noCache: boolean) => { const { type } = options; - const url = `https://bbs-api.miyoushe.com/post/wapi/getNewsList?gids=2&page_size=20&type=${type}`; + const url = `https://bbs-api-static.miyoushe.com/painter/wapi/getNewsList?client_type=4&gids=2&last_id=&page_size=20&type=${type}`; const result = await get({ url, noCache }); const list = result.data.data.list; return { @@ -43,7 +43,7 @@ const getList = async (options: Options, noCache: boolean) => { id: data.post_id, title: data.subject, desc: data.content, - cover: data.cover, + cover: data.cover || data?.images?.[0], author: v.user?.nickname || null, timestamp: getTime(data.created_at), hot: data.view_status, diff --git a/src/routes/honkai.ts b/src/routes/honkai.ts index 19de96e..80518b1 100644 --- a/src/routes/honkai.ts +++ b/src/routes/honkai.ts @@ -31,7 +31,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => { const getList = async (options: Options, noCache: boolean) => { const { type } = options; - const url = `https://bbs-api.miyoushe.com/post/wapi/getNewsList?gids=1&page_size=20&type=${type}`; + const url = `https://bbs-api-static.miyoushe.com/painter/wapi/getNewsList?client_type=4&gids=1&last_id=&page_size=20&type=${type}`; const result = await get({ url, noCache }); const list = result.data.data.list; return { @@ -43,7 +43,7 @@ const getList = async (options: Options, noCache: boolean) => { id: data.post_id, title: data.subject, desc: data.content, - cover: data.cover, + cover: data.cover || data?.images?.[0], author: v.user?.nickname || null, timestamp: getTime(data.created_at), hot: data.view_status, diff --git a/src/routes/nodeseek.ts b/src/routes/nodeseek.ts index a148caa..77f4c18 100644 --- a/src/routes/nodeseek.ts +++ b/src/routes/nodeseek.ts @@ -28,15 +28,12 @@ export const handleRoute = async (_: undefined, noCache: boolean) => { const getList = async (noCache: boolean) => { const url = `https://rss.nodeseek.com/`; const result = await get({ url, noCache }); - const rssData = await parseStringPromise(result.data); - const list = rssData.rss.channel[0].item; - return { fromCache: result.fromCache, updateTime: result.updateTime, - data: list.map((v: any) => ({ + data: list.map((v) => ({ id: v.guid[0]._, title: v.title[0], desc: v.description ? v.description[0] : "", diff --git a/src/routes/starrail.ts b/src/routes/starrail.ts index 4b4c7da..fb0d7ea 100644 --- a/src/routes/starrail.ts +++ b/src/routes/starrail.ts @@ -31,7 +31,7 @@ export const handleRoute = async (c: ListContext, noCache: boolean) => { const getList = async (options: Options, noCache: boolean) => { const { type } = options; - const url = `https://bbs-api.miyoushe.com/post/wapi/getNewsList?gids=6&page_size=20&type=${type}`; + const url = `https://bbs-api-static.miyoushe.com/painter/wapi/getNewsList?client_type=4&gids=6&page_size=20&type=${type}`; const result = await get({ url, noCache }); const list = result.data.data.list; return { @@ -43,7 +43,7 @@ const getList = async (options: Options, noCache: boolean) => { id: data.post_id, title: data.subject, desc: data.content, - cover: data.cover, + cover: data.cover || data?.images?.[0], author: v.user?.nickname || null, timestamp: getTime(data.created_at), hot: data.view_status, diff --git a/src/utils/getToken/coolapk.ts b/src/utils/getToken/coolapk.ts new file mode 100644 index 0000000..8a5b5ea --- /dev/null +++ b/src/utils/getToken/coolapk.ts @@ -0,0 +1,49 @@ +import md5 from "md5"; + +/** + * 获取随机的DEVICE_ID + * @returns DEVICE_ID + */ +const getRandomDEVICE_ID = () => { + const id = [10, 6, 6, 6, 14]; + return id.map((i) => Math.random().toString(36).substring(2, i)).join("-"); +}; + +/** + * 获取APP_TOKEN + * @returns APP_TOKEN + */ +const get_app_token = async () => { + const DEVICE_ID = getRandomDEVICE_ID(); + const now = Math.round(Date.now() / 1000); + const hex_now = "0x" + now.toString(16); + const md5_now = await md5(now.toString()); + const s = + "token://com.coolapk.market/c67ef5943784d09750dcfbb31020f0ab?" + + md5_now + + "$" + + DEVICE_ID + + "&com.coolapk.market"; + const md5_s = await md5(Buffer.from(s).toString("base64")); + const token = md5_s + DEVICE_ID + hex_now; + return token; +}; + +/** + * 获取请求头 + * @returns 请求头 + */ +export const genHeaders = async () => { + return { + "X-Requested-With": "XMLHttpRequest", + "X-App-Id": "com.coolapk.market", + "X-App-Token": await get_app_token(), + "X-Sdk-Int": "29", + "X-Sdk-Locale": "zh-CN", + "X-App-Version": "11.0", + "X-Api-Version": "11", + "X-App-Code": "2101202", + "User-Agent": + "Mozilla/5.0 (Linux; Android 10; Mi 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.15 Mobile Safari/537.36", + }; +};