diff --git a/lib/routes/51cto/namespace.ts b/lib/routes/51cto/namespace.ts new file mode 100644 index 00000000000000..96d3ff4ed31a85 --- /dev/null +++ b/lib/routes/51cto/namespace.ts @@ -0,0 +1,6 @@ +import type { Namespace } from '@/types'; + +export const namespace: Namespace = { + name: '51CTO', + url: '51cto.com', +}; diff --git a/lib/routes/51cto/recommend.ts b/lib/routes/51cto/recommend.ts new file mode 100644 index 00000000000000..fa5d426fb75182 --- /dev/null +++ b/lib/routes/51cto/recommend.ts @@ -0,0 +1,52 @@ +import { Route } from '@/types'; +import { parseDate } from '@/utils/parse-date'; +import got from '@/utils/got'; +import { getToken, sign } from './utils'; + +export const route: Route = { + path: '/index/recommend', + categories: ['programming'], + example: '/51cto/index/recommend', + radar: [ + { + source: ['51cto.com/'], + }, + ], + name: '推荐', + maintainers: ['cnkmmk'], + handler, + url: '51cto.com/', +}; + +async function handler(ctx) { + const url = 'https://api-media.51cto.com'; + const requestPath = 'index/index/recommend'; + const token = (await getToken()) as string; + const timestamp = Date.now(); + const params = { + page: 1, + page_size: ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 50, + limit_time: 0, + name_en: '', + }; + const response = await got(`${url}/${requestPath}`, { + searchParams: { + ...params, + timestamp, + token, + sign: sign(requestPath, params, timestamp, token), + }, + }); + const list = response.data.data.data.list; + return { + title: '51CTO', + link: 'https://www.51cto.com/', + description: '51cto - 推荐', + item: list.map((item) => ({ + title: item.title, + link: item.url, + pubDate: parseDate(item.pubdate, +8), + description: item.abstract, + })), + }; +} diff --git a/lib/routes/51cto/utils.ts b/lib/routes/51cto/utils.ts new file mode 100644 index 00000000000000..a1aba122278cf4 --- /dev/null +++ b/lib/routes/51cto/utils.ts @@ -0,0 +1,21 @@ +import ofetch from '@/utils/ofetch'; +import cache from '@/utils/cache'; +import md5 from '@/utils/md5'; + +export const getToken = () => + cache.tryGet( + '51cto:token', + async () => { + const response = await ofetch('https://api-media.51cto.com/api/token-get'); + return response.data.data.token; + }, + 3600, + false + ); + +export const sign = (requestPath: string, payload: Record = {}, timestamp: number, token: string) => { + payload.timestamp = timestamp; + payload.token = token; + const sortedParams = Object.keys(payload).sort(); + return md5(md5(requestPath) + md5(sortedParams + md5(token) + timestamp)); +};