diff --git a/lib/config.js b/lib/config.js index 2acce777a1..4e76cf06d8 100644 --- a/lib/config.js +++ b/lib/config.js @@ -10,6 +10,7 @@ const calculateValue = () => { const email_config = {}; const discuz_cookies = {}; const medium_cookies = {}; + const discourse_config = {}; for (const name in envs) { if (name.startsWith('BILIBILI_COOKIE_')) { @@ -27,6 +28,9 @@ const calculateValue = () => { } else if (name.startsWith('MEDIUM_COOKIE_')) { const username = name.slice(14).toLowerCase(); medium_cookies[username] = envs[name]; + } else if (name.startsWith('DISCOURSE_CONFIG_')) { + const id = name.slice('DISCOURSE_CONFIG_'.length); + discourse_config[id] = JSON.parse(envs[name]); } } @@ -136,6 +140,9 @@ const calculateValue = () => { discord: { authorization: envs.DISCORD_AUTHORIZATION, }, + discourse: { + config: discourse_config, + }, discuz: { cookies: discuz_cookies, }, diff --git a/lib/radar.js b/lib/radar.js index 0766e3ab9d..09f24e6e8e 100644 --- a/lib/radar.js +++ b/lib/radar.js @@ -3,7 +3,8 @@ const fs = require('fs'); const toSource = require('tosource'); const { join } = require('path'); -const allowNamespace = ['ehentai', 'test']; +// Namespaces that do not require radar.js +const allowNamespace = ['discourse', 'ehentai', 'test']; // Check if a radar.js file is exist under each folder of dirname for (const dir of fs.readdirSync(dirname)) { const dirPath = join(dirname, dir); diff --git a/lib/v2/discourse/maintainer.js b/lib/v2/discourse/maintainer.js new file mode 100644 index 0000000000..6d6c640d8e --- /dev/null +++ b/lib/v2/discourse/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/:configId/posts': ['dzx-dzx'], +}; diff --git a/lib/v2/discourse/posts.js b/lib/v2/discourse/posts.js new file mode 100644 index 0000000000..0dc8317be9 --- /dev/null +++ b/lib/v2/discourse/posts.js @@ -0,0 +1,28 @@ +const config = require('@/config').value; +const got = require('@/utils/got'); +const RSSParser = require('@/utils/rss-parser'); + +module.exports = async (ctx) => { + if (!config.discourse.config[ctx.params.configId]) { + throw Error('Discourse RSS is disabled due to the lack of relevant config'); + } + const { link, key } = config.discourse.config[ctx.params.configId]; + + const feed = await RSSParser.parseString( + ( + await got(`${link}/posts.rss`, { + headers: { + 'User-Api-Key': key, + }, + }) + ).data + ); + + feed.items = feed.items.map((e) => ({ + description: e.content, + author: e.creator, + ...e, + })); + + ctx.state.data = { item: feed.items, ...feed }; +}; diff --git a/lib/v2/discourse/router.js b/lib/v2/discourse/router.js new file mode 100644 index 0000000000..b59d0004f6 --- /dev/null +++ b/lib/v2/discourse/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/:configId/posts', require('./posts')); +}; diff --git a/test/config.js b/test/config.js index f82a9ea5d0..145068ee0f 100644 --- a/test/config.js +++ b/test/config.js @@ -73,6 +73,20 @@ describe('config', () => { delete process.env.MEDIUM_COOKIE_34; }); + it('discourse config', () => { + process.env.DISCOURSE_CONFIG_12 = JSON.stringify({ a: 1 }); + process.env.DISCOURSE_CONFIG_34 = JSON.stringify({ b: 2 }); + + const config = require('../lib/config').value; + expect(config.discourse.config).toMatchObject({ + 12: { a: 1 }, + 34: { b: 2 }, + }); + + delete process.env.DISCOURSE_CONFIG_12; + delete process.env.DISCOURSE_CONFIG_34; + }); + it('no random ua', () => { process.env.NO_RANDOM_UA = true; diff --git a/website/docs/install/README.md b/website/docs/install/README.md index ccd0fabe02..ea25ad0e7e 100644 --- a/website/docs/install/README.md +++ b/website/docs/install/README.md @@ -792,6 +792,11 @@ See docs of the specified route and `lib/config.js` for detailed information. - `DISCORD_AUTHORIZATION`: Discord authorization token, can be found in the header of XHR requests after logging in Discord web client +- Discourse + - `DISCOURSE_CONFIG_{id}`: `id` could be arbitrary number or string, while the value should be the format of `{"link":link,"key":key}`, where: + - `link` is the link to the forum. + - `key` is the access key for the forum API, which you can refer to [this snippet](https://pastebin.com/YbLCgdWW) to obtain one. Ensure that this key is granted sufficient permission. + - Discuz cookie - `DISCUZ_COOKIE_{cid}`: Cookie of a forum powered by Discuz, cid can be anything from 00 to 99. When visiting a Discuz route, use cid to specify this cookie. diff --git a/website/docs/routes/bbs.md b/website/docs/routes/bbs.md index 7376e85254..9136f178c8 100644 --- a/website/docs/routes/bbs.md +++ b/website/docs/routes/bbs.md @@ -140,6 +140,18 @@ +## Discourse {#discourse} + +:::caution + +You need to set the environment variable `DISCOURSE_CONFIG_{id}` before using it. Please refer to Configuration section in the Deploy page of the documentation. + +::: + +### Latest posts {#discourse-latest-posts} + + + ## Discuz {#discuz} ### General Subforum - Auto detection {#discuz-general-subforum---auto-detection}