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}