Skip to content

Commit

Permalink
feat(route): add ainvest (#13348)
Browse files Browse the repository at this point in the history
* feat(route): add ainvest

* style: fix code style

* fix: feed title
  • Loading branch information
TonyRL authored Sep 21, 2023
1 parent 81e36b8 commit 46d32af
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 0 deletions.
42 changes: 42 additions & 0 deletions lib/v2/ainvest/article.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const got = require('@/utils/got');
const { parseDate } = require('@/utils/parse-date');
const { getHeaders, randomString, encryptAES, decryptAES } = require('./utils');

module.exports = async (ctx) => {
const key = randomString(16);

const { data: response } = await got.post('https://api.ainvest.com/gw/socialcenter/v1/edu/article/listArticle', {
headers: getHeaders(key),
searchParams: {
timestamp: Date.now(),
},
data: encryptAES(
JSON.stringify({
batch: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 30,
startId: null,
tags: {
in: ['markettrends', 'premarket', 'companyinsights', 'macro'],
and: ['web', 'creationplatform'],
},
}),
key
),
});

const { data } = JSON.parse(decryptAES(response, key));

const items = data.map((item) => ({
title: item.title,
description: item.content,
link: item.sourceUrl,
pubDate: parseDate(item.postDate, 'x'),
category: [item.nickName, ...item.tags.map((tag) => tag.code)],
}));

ctx.state.data = {
title: 'AInvest - Latest Articles',
link: 'https://www.ainvest.com/news',
language: 'en',
item: items,
};
};
4 changes: 4 additions & 0 deletions lib/v2/ainvest/maintainer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
'/article': ['TonyRL'],
'/news': ['TonyRL'],
};
39 changes: 39 additions & 0 deletions lib/v2/ainvest/news.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const got = require('@/utils/got');
const { parseDate } = require('@/utils/parse-date');
const { getHeaders, randomString, decryptAES } = require('./utils');

module.exports = async (ctx) => {
const key = randomString(16);

const { data: response } = await got('https://api.ainvest.com/gw/news_f10/v1/newsFlash/getNewsData', {
headers: getHeaders(key),
searchParams: {
terminal: 'web',
tab: 'all',
page: 1,
size: ctx.query.limit ? parseInt(ctx.query.limit, 10) : 50,
lastId: '',
timestamp: Date.now(),
},
});

const { data } = JSON.parse(decryptAES(response, key));

const items = data.content.map((item) => ({
title: item.title,
description: item.content,
link: item.sourceUrl,
pubDate: parseDate(item.publishTime, 'x'),
category: item.tagList.map((tag) => tag.nameEn),
author: item.userInfo.nickname,
upvotes: item.likeCount,
comments: item.commentCount,
}));

ctx.state.data = {
title: 'AInvest - Latest News',
link: 'https://www.ainvest.com/news',
language: 'en',
item: items,
};
};
19 changes: 19 additions & 0 deletions lib/v2/ainvest/radar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module.exports = {
'ainvest.com': {
_name: 'AInvest',
'.': [
{
title: 'Latest Article',
docs: 'https://docs.rsshub.app/finance#ainvest',
source: ['/news'],
target: '/ainvest/article',
},
{
title: 'Latest News',
docs: 'https://docs.rsshub.app/finance#ainvest',
source: ['/news'],
target: '/ainvest/news',
},
],
},
};
4 changes: 4 additions & 0 deletions lib/v2/ainvest/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = (router) => {
router.get('/article', require('./article'));
router.get('/news', require('./news'));
};
73 changes: 73 additions & 0 deletions lib/v2/ainvest/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
const crypto = require('crypto');
const CryptoJS = require('crypto-js');
const { KJUR, KEYUTIL, hextob64 } = require('jsrsasign');

const publicKey =
'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCARnxLlrhTK28bEV7s2IROjT73KLSjfqpKIvV8L+Yhe4BrF0Ut4oOH728HZlbSF0C3N0vXZjLAFesoS4v1pYOjVCPXl920Lh2seCv82m0cK78WMGuqZTfA44Nv7JsQMHC3+J6IZm8YD53ft2d8mYBFgKektduucjx8sObe7eRyoQIDAQAB';

const randomString = (length) => {
if (length > 32) {
throw Error('Max length is 32.');
}
return uuidv4().replace(/-/g, '').substring(0, length);
};

const uuidv4 = () => crypto.randomUUID();

/**
* @param {string} str
* @returns {CryptoJS.lib.WordArray}
*/
const MD5 = (str) => CryptoJS.MD5(str);

const encryptAES = (data, key) => {
if (typeof key === 'string') {
key = MD5(key);
}
return CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(data), key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}).toString();
};

const decryptAES = (data, key) => {
if (typeof key === 'string') {
key = MD5(key);
}
return CryptoJS.AES.decrypt(data, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
}).toString(CryptoJS.enc.Utf8);
};

const encryptRSA = (data) => {
// Original code:
// var n = new JSEncrypt();
// n.setPublicKey(pubKey);
// return n.encrypt(message);
// Note: Server will reject the public key if it's encrypted using crypto.publicEncrypt().
let pubKey = `-----BEGIN PUBLIC KEY-----${publicKey}-----END PUBLIC KEY-----`;
pubKey = KEYUTIL.getKey(pubKey);
return hextob64(KJUR.crypto.Cipher.encrypt(data, pubKey));
};

const getHeaders = (key) => {
const fingerPrint = uuidv4();

return {
'content-type': 'application/json',
'ovse-trace': uuidv4(),
callertype: 'USER',
fingerprint: encryptAES(fingerPrint, MD5(key)),
onetimeskey: encryptRSA(key),
timestamp: encryptAES(Date.now(), key),
referer: 'https://www.ainvest.com/',
};
};

module.exports = {
randomString,
encryptAES,
decryptAES,
getHeaders,
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
"jsdom": "22.1.0",
"json-bigint": "1.0.0",
"json5": "2.2.3",
"jsrsasign": "10.8.6",
"koa": "2.14.2",
"koa-basic-auth": "4.0.0",
"koa-favicon": "2.1.0",
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions website/docs/routes/finance.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@

</Route>

## AInvest {#ainvest}

### Latest Article {#ainvest-latest-article}

<Route author="TonyRL" example="/ainvest/article" path="/ainvest/article" radar="1"/>

### Latest News {#ainvest-latest-news}

<Route author="TonyRL" example="/ainvest/news" path="/ainvest/news" radar="1"/>

## BigQuant {#bigquant}

### 专题报告 {#bigquant-zhuan-ti-bao-gao}
Expand Down

0 comments on commit 46d32af

Please sign in to comment.