diff --git a/lib/config.js b/lib/config.js index eac901a4246f65..ca99d6f6124a0a 100644 --- a/lib/config.js +++ b/lib/config.js @@ -1,5 +1,6 @@ require('dotenv').config(); const randUserAgent = require('./utils/rand-user-agent'); +const got = require('got'); let envs = process.env; let value; const TRUE_UA = 'RSSHub/1.0 (+http://github.com/DIYgod/RSSHub; like FeedFetcher-Google)'; @@ -329,6 +330,21 @@ const calculateValue = () => { }; calculateValue(); +if (envs.REMOTE_CONFIG) { + got.get(envs.REMOTE_CONFIG) + .then((response) => { + const data = JSON.parse(response.body); + if (data) { + envs = Object.assign(envs, data); + calculateValue(); + require('@/utils/logger').info('Remote config loaded.'); + } + }) + .catch((error) => { + require('@/utils/logger').error('Remote config load failed.', error); + }); +} + module.exports = { set: (env) => { envs = Object.assign(process.env, env); diff --git a/test/config.js b/test/config.js index 3fcf7da3d6ec21..f0a80c792814c9 100644 --- a/test/config.js +++ b/test/config.js @@ -1,3 +1,5 @@ +const nock = require('nock'); + afterEach(() => { jest.resetModules(); }); @@ -86,4 +88,18 @@ describe('config', () => { const config = require('../lib/config').value; expect(config.ua).not.toBe('RSSHub/1.0 (+http://github.com/DIYgod/RSSHub; like FeedFetcher-Google)'); }); + + it('remote config', async () => { + process.env.REMOTE_CONFIG = 'http://rsshub.test/config'; + + nock(/rsshub\.test/) + .get('/config') + .reply(200, { + UA: 'test', + }); + let config = require('../lib/config').value; + await new Promise((resolve) => setTimeout(resolve, 100)); + config = require('../lib/config').value; + expect(config.ua).toBe('test'); + }); }); diff --git a/website/docs/install/config.md b/website/docs/install/config.md index d731061404a333..7d5642cdb00a30 100644 --- a/website/docs/install/config.md +++ b/website/docs/install/config.md @@ -235,6 +235,8 @@ Configs in this sections are in beta stage, and **are turn off by default**. Ple `OPENAI_PROMPT`: OpenAI prompt, used for using ChatGPT to summarize articles, see [OpenAI API reference](https://platform.openai.com/docs/api-reference/chat) for details +`REMOTE_CONFIG`: Remote configuration URL, used for dynamically updating configurations. The address should return a JSON with an environment variable name as the key. It will be loaded and merged with local configurations when the application starts. In case of conflicts with local configurations, remote configurations will take precedence. But please note that some basic configuration items do not support remote retrieval. + ## Route-specific Configurations {#route-specific-configurations} :::tip diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/install/config.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/install/config.md index 55245669fd1c98..0c0aa11e2d8c84 100644 --- a/website/i18n/zh/docusaurus-plugin-content-docs/current/install/config.md +++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/install/config.md @@ -235,6 +235,8 @@ RSSHub 支持使用访问密钥 / 码,允许清单和拒绝清单三种方式 `OPENAI_PROMPT`: OpenAI 提示语,用于使用 ChatGPT 总结文章,详见 [OpenAI API 文档](https://platform.openai.com/docs/api-reference/chat) +`REMOTE_CONFIG`: 远程配置地址,用于动态更新配置,地址应返回一个环境变量名作为 key 的 JSON,会在应用启动时加载并合并本地配置,与本地配置冲突时以远程配置为准,但请注意部分基础配置项不支持从远程获取 + ## 部分 RSS 模块配置 {#route-specific-configurations} :::tip