### Install RSSHub with Helm and Custom Values File Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md Install RSSHub using a custom YAML configuration file with Helm. ```yaml # custom-values.yml 文件 ## 使用 "helm install my-release nsl/rsshub -f ./custom-values.yml" 安装 image: tag: "2023-12-04" replicaCount: 2 ``` -------------------------------- ### Install RSSHub with Helm CLI and Custom Values Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md Install RSSHub using the Helm CLI, specifying image tag and replica count directly. ```bash helm install my-release nsl/rsshub \ --set="image.tag=2023-12-04" \ --set="replicaCount=2" ``` -------------------------------- ### Example Routes for Pull Request Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/submit-route.md Provide specific examples of the routes you are adding or modifying in your pull request. Do not use placeholder parameters like `:user/:repo`. ```routes /github/issue/DIYgod /github/issue/DIYgod/RSSHub /github/issue/DIYgod/RSSHub-Radar /github/issue/flutter/flutter ``` -------------------------------- ### Basic HTML Retrieval Setup Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/start-code.md Initialize a route handler for retrieving data directly from HTML content. This setup includes necessary imports for `ofetch` and `cheerio` for HTML parsing. ```typescript import { Route } from '@/types'; import ofetch from '@/utils/ofetch'; // Unified request library used import { load } from 'cheerio'; // An HTML parser with an API similar to jQuery export const route: Route = { // Write the routing information introduced in the previous text here. handler: (ctx) => { // Write the routing handler function here. }, }; ``` -------------------------------- ### Install RSSHub with Custom Helm Values (File) Source: https://github.com/rssnext/rsshub-docs/blob/main/src/deploy/index.md Install RSSHub using a custom values YAML file to configure image tag and replica count. ```yaml # File custom-values.yml ## Install with "helm install my-release nsl/rsshub -f ./custom-values.yml image: tag: "2023-12-04" replicaCount: 2 ``` -------------------------------- ### Start RSSHub Development Server Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/before-start.md Start the RSSHub development server for debugging. This command allows you to see changes reflected in the browser at http://localhost:1200. ```bash pnpm dev ``` -------------------------------- ### Install RSSHub Dependencies Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/before-start.md Install all necessary project dependencies for RSSHub using the pnpm package manager. Run this command in the root directory of your RSSHub project. ```bash pnpm i ``` -------------------------------- ### Install RSSHub with Ansible Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md Install RSSHub, Redis, browserless, and Caddy 2 using an Ansible playbook. Requires sudo privileges and virtualization capabilities. Supports Ubuntu 20.04. ```bash sudo apt update sudo apt install ansible git clone https://github.com/DIYgod/RSSHub.git ~/RSSHub cd ~/RSSHub/scripts/ansible sudo ansible-playbook rsshub.yaml # 当提示输入 domain name 的时候,输入该主机所使用的域名 # 举例:如果您的 RSSHub 用户使用 https://rsshub.example.com 访问您的 RSSHub 实例,输入 rsshub.example.com(去掉 https://) ``` -------------------------------- ### Install RSSHub as npm Package Source: https://github.com/rssnext/rsshub-docs/blob/main/src/guide/index.md Install the RSSHub package using your preferred package manager. This is the first step to using RSSHub programmatically in Node.js projects. ```sh pnpm add rsshub ``` ```sh bun add rsshub ``` ```sh yarn add rsshub ``` ```sh npm install rsshub --save ``` -------------------------------- ### Install RSSHub with Ansible Source: https://github.com/rssnext/rsshub-docs/blob/main/src/deploy/index.md Install RSSHub, Redis, browserless (via Docker), and Caddy 2 on Ubuntu 20.04 using an Ansible playbook. Requires sudo privileges and virtualization. ```bash sudo apt update sudo apt install ansible git clone https://github.com/DIYgod/RSSHub.git ~/RSSHub cd ~/RSSHub/scripts/ansible sudo ansible-playbook rsshub.yaml # When prompt to enter a domain name, enter the domain name that this machine/VM will use # For example, if your users use https://rsshub.example.com to access your RSSHub instance, enter rsshub.example.com (remove the https://) ``` -------------------------------- ### Launch RSSHub with pnpm or pm2 Source: https://github.com/rssnext/rsshub-docs/blob/main/src/deploy/index.md Use pnpm to start RSSHub for development or pm2 for process management in production. Access the server at http://{Server IP}:1200. ```bash pnpm start ``` ```bash pm2 start dist/index.mjs --name rsshub ``` -------------------------------- ### Pull Request Template Example Routes Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/submit-route.md When submitting a new route, list the full route addresses in the `routes` section of the pull request template. Include all required and optional parameters. If the changes are not route-related, use `NOROUTE`. ```routes /some/route /some/other/route /dont/use/this/or/modify/it /use/the/fenced/code/block/below ``` -------------------------------- ### Configure Puppeteer on ARM Source: https://github.com/rssnext/rsshub-docs/blob/main/src/deploy/index.md On ARM/ARM64, install Chromium from your distribution's repositories and set the CHROMIUM_EXECUTABLE_PATH environment variable in a .env file to use Puppeteer. ```bash $ apt install chromium $ echo >> .env $ echo 'CHROMIUM_EXECUTABLE_PATH=chromium' >> .env ``` ```bash $ apt install chromium-browser $ echo >> .env $ echo 'CHROMIUM_EXECUTABLE_PATH=chromium-browser' >> .env ``` -------------------------------- ### Fetching Data from GitHub API Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/start-code.md Demonstrates how to use `ofetch` to make a GET request to the GitHub Issues API, including setting necessary headers. This is used after obtaining user input. ```typescript export const route = { // ... handler: async (ctx) => { const { user, repo = 'RSSHub' } = ctx.req.param(); // Send an HTTP GET request to the API and destructure the returned data object. const data = await ofetch(`https://api.github.com/repos/${user}/${repo}/issues`, { headers: { accept: 'application/vnd.github.html+json', }, }); }, }; ``` -------------------------------- ### 使用 ofetch 获取 HTML 响应 Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/joinus/new-rss/start-code.md 使用 ofetch 向指定 URL 发送 HTTP GET 请求以获取 HTML 内容。此代码片段是后续使用 Cheerio 解析 HTML 的第一步。 ```typescript export const route: Route = { // ... handler: (ctx) => { const { user, repo = 'RSSHub' } = ctx.req.param(); const response = await ofetch(`https://github.com/${user}/${repo}/issues`); const $ = load(response); }, }; ``` -------------------------------- ### Pull Request Template - NOROUTE Example Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/submit-route.md If your pull request is not related to a route, specify `NOROUTE` in the `routes` section of the pull request template. Do not leave this section empty or delete it. ```routes NOROUTE ``` -------------------------------- ### Define Namespace Configuration Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/start-code.md Use this TypeScript code to define the configuration for a new namespace. Ensure the `name` and `url` properties accurately reflect the website you are creating the feed for. The `description` can include helpful tips or official RSS feed examples. ```typescript import type { Namespace } from '@/types'; export const namespace: Namespace = { name: 'GitHub', url: 'github.com', description: ` :::tip GitHub provides some official RSS feeds: - Repo releases: - Repo commits: - User activities: - Private feed: (You can find **Subscribe to your news feed** in [dashboard](https://github.com) page after login) - Wiki history: ::: `, zh: { name: '给他哈不', }, }; ``` -------------------------------- ### 下载 Docker Compose 配置文件 Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md 使用 wget 命令下载官方提供的 docker-compose.yml 文件,这是推荐的 Docker Compose 部署方式的起点。 ```bash $ wget https://raw.githubusercontent.com/DIYgod/RSSHub/master/docker-compose.yml ``` -------------------------------- ### 更新文档以支持播客 Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/joinus/advanced/advanced-feed.md 将 `Route` 导出对象的 `features` 中的 `supportPodcast` 属性设置为 `true`,以在路由文档中反映对播客订阅的支持。 ```typescript export const route: Route = { // ... features: { // ... supportPodcast: true, }, }; ``` -------------------------------- ### 启动 Docker Compose 服务 Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md 在下载并配置好 docker-compose.yml 文件后,使用此命令在后台启动 RSSHub 服务。 ```bash $ docker-compose up -d ``` -------------------------------- ### Initialize and Request Feed with RSSHub Package Source: https://github.com/rssnext/rsshub-docs/blob/main/src/guide/index.md Initialize the RSSHub package with configuration and then make a request to fetch data for a specific feed. Ensure you handle potential errors during the request. ```js import * as RSSHub from 'rsshub'; await RSSHub.init({ // config }); RSSHub.request('/youtube/user/JFlaMusic') .then((data) => { console.log(data); }) .catch((e) => { console.log(e); }); ``` -------------------------------- ### Nix 用户配置环境 Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md 为 Nix 用户提供的配置,用于简化 Node.js、Yarn 和 Jieba 的安装。 ```nix let pkgs = import {}; node = pkgs.nodejs-12_x; in pkgs.stdenv.mkDerivation { name = "nodejs-yarn-jieba"; buildInputs = [node pkgs.yarn pkgs.pythonPackages.jieba]; } ``` -------------------------------- ### Cache Assignment Caveat Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/advanced/use-cache.md Assignments to variables declared outside of `cache.tryGet()` will not be processed during a cache hit. The example demonstrates this behavior. ```javascript let x = '1'; const z = await cache.tryGet('cache:key', async () => { x = '2'; const y = '3'; return y; }) console.log(x); // cache miss: '2', cache hit: '1' console.log(z): // '3' ``` -------------------------------- ### 使用 Docker 运行 RSSHub (无 Puppeteer) Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md 直接使用 Docker 命令运行 RSSHub 容器,此命令不包含 Puppeteer 依赖。 ```bash $ docker run -d --name rsshub -p 1200:1200 diygod/rsshub ``` -------------------------------- ### HA Mode RSSHub Installation (With Autoscaling) Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md Configure RSSHub for High Availability (HA) mode with autoscaling enabled for both the main deployment and puppeteer. ```yaml autoscaling: enabled: true minReplicas: 3 puppeteer: autoscaling: enabled: true minReplicas: 2 ``` -------------------------------- ### Stop and Remove RSSHub Docker Container Source: https://github.com/rssnext/rsshub-docs/blob/main/src/deploy/index.md Manually update the RSSHub Docker image by stopping and removing the existing container before re-running the installation command. ```bash $ docker stop rsshub $ docker rm rsshub ``` -------------------------------- ### Deploy RSSHub to Fly.io (Fork Method) Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md Steps to deploy RSSHub to Fly.io by forking the repository, cloning it, launching the app, setting secrets, and configuring continuous deployment. ```bash git clone https://github.com//RSSHub.git cd RSSHub fly launch, 并选择一个唯一的名称和实例地区 fly secrets set KEY=VALUE [对部分模块进行配置](config#route-specific-configurations) (可选)利用 `fly certs add 你的域名` 来配置自定义域名,并根据指引在你的 DNS 服务商配置相关域名解析(你可在 Dashboard Certificate 页面查看域名的配置状态) ``` -------------------------------- ### Pull Request Template - Completed Checklist Item Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/submit-route.md Example of a completed checklist item in the pull request template, indicating that the new route requirement has been met. ```markdown - [x] 新的路由 New Route ``` -------------------------------- ### 使用 Docker 运行 RSSHub (含 Puppeteer) Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md 使用 Docker 命令运行 RSSHub 容器,并指定使用包含 Puppeteer 的镜像,以支持更多路由。 ```bash $ docker run -d --name rsshub -p 1200:1200 diygod/rsshub:chromium-bundled ``` -------------------------------- ### Define a New RSS Route Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/start-code.md Register a new RSS route with its path, categories, example URL, parameters, features, radar rules, name, maintainers, and handler. ```typescript import { Route } from '@/types'; export const route: Route = { path: '/issue/:user/:repo/:state?/:labels?', categories: ['programming'], example: '/github/issue/vuejs/core/all/wontfix', parameters: { user: 'GitHub username', repo: 'GitHub repo name', state: 'the state of the issues. Can be either `open`, `closed`, or `all`. Default: `open`.', labels: 'a list of comma separated label names' }, features: { requireConfig: false, requirePuppeteer: false, antiCrawler: false, supportBT: false, supportPodcast: false, supportScihub: false, }, radar: [ { source: ['github.com/:user/:repo/issues', 'github.com/:user/:repo/issues/:id', 'github.com/:user/:repo'], target: '/issue/:user/:repo', }, ], name: 'Repo Issues', maintainers: ['HenryQW', 'AndreyMZ'], handler, }; ``` -------------------------------- ### Accessing a Route with an Access Code Source: https://github.com/rssnext/rsshub-docs/blob/main/src/deploy/config.md Routes can be accessed using a generated access code, which is an MD5 hash of the route and the access key. This example shows the URL format. ```plaintext https://rsshub.app/qdaily/column/59?code=0f820530128805ffc10351f22b5fd121 ``` -------------------------------- ### Create Redis Instance with Fly.io Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md Use this command to create a new Redis database on Fly.io. Ensure the region matches your RSSHub app's region. Eviction is recommended. ```bash $ fly redis create ``` -------------------------------- ### 配置 Docker 运行的 RSSHub (环境变量) Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md 通过 Docker 运行命令中的 -e 参数设置环境变量,例如修改缓存时间或 GitHub 访问令牌。 ```bash $ docker run -d --name rsshub -p 1200:1200 -e CACHE_EXPIRE=3600 -e GITHUB_ACCESS_TOKEN=example diygod/rsshub ``` -------------------------------- ### HA Mode RSSHub Installation (No Autoscaling) Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md Configure RSSHub for High Availability (HA) mode without enabling autoscaling, specifying replica counts for the main deployment and puppeteer. ```yaml replicaCount: 3 puppeteer: replicaCount: 2 ``` -------------------------------- ### 更新 Docker Compose 镜像 Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md 拉取最新的 RSSHub Docker 镜像,为手动更新做准备。 ```bash $ docker-compose pull ``` -------------------------------- ### 更新 Helm Chart 仓库 Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md 更新本地 Helm Chart 仓库的配置,以获取最新的 Chart 信息。 ```bash helm repo update ``` -------------------------------- ### Define Radar Rules for a Route Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/start-code.md Specify source URLs and a target RSSHub route for RSSHub Radar to automatically generate subscription links. This example shows rules for GitHub repository issues. ```typescript import { Route } from '@/types'; export const route: Route = { // ... radar: [ { source: ['github.com/:user/:repo/issues', 'github.com/:user/:repo/issues/:id', 'github.com/:user/:repo'], target: '/issue/:user/:repo', }, ], }; ``` -------------------------------- ### Enable BitTorrent/Magnet Feed Support in Documentation Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/advanced/advanced-feed.md Set `supportBT` to `true` in the `features` object of your `Route` export to indicate support for BitTorrent/Magnet feeds in your route's documentation. ```typescript export const route: Route = { // ... features: { // ... supportBT: true, }, }; ``` -------------------------------- ### Avoid Redundant Selectors Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/advanced/script-standard.md When selecting elements, avoid redundant selectors that check for the same element multiple times. This example shows how to use a Set to track seen elements and avoid processing duplicates. ```javascript const seen = new Set(); $('a[href="some/url"]').each((_, a) => { // ... if (seen.has(a.href)) { return; } seen.add(a.href); // ... }); ``` -------------------------------- ### Route Maintainer Declaration Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/joinus/advanced/script-standard.md Declare route maintainers using their GitHub IDs. Ensure you have explicit consent before listing another developer's ID. This example shows the structure for defining a route with its maintainers. ```typescript export const route: Route = { // ... name: '某路由', maintainers: ['未经同意的其他开发者'], handler, }; ``` -------------------------------- ### 添加 RSSHub Helm Chart 仓库 Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md 将 NaturalSelection Labs 的 Helm Chart 仓库添加到 Helm 配置中。 ```bash helm repo add nsl https://naturalselectionlabs.github.io/helm-charts ``` -------------------------------- ### Configure Healthcheck with Access Key (Docker Compose) Source: https://github.com/rssnext/rsshub-docs/blob/main/src/deploy/config.md When an ACCESS_KEY is enabled, the healthcheck endpoint also requires authentication. This example shows how to update a Docker Compose file to include the access key in the healthcheck command. ```diff healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:1200/healthz"] + test: ["CMD", "curl", "-f", "http://localhost:1200/healthz?key=${ACCESS_KEY}"] ``` -------------------------------- ### 更新文档以支持 Sci-Hub Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/joinus/advanced/advanced-feed.md 将 `Route` 导出对象的 `features` 中的 `supportScihub` 属性设置为 `true`,以在路由文档中反映对 Sci-Hub 功能的支持。 ```typescript export const route: Route = { // ... features: { // ... supportScihub: true, }, }; ``` -------------------------------- ### Create a Podcast Feed Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/advanced/advanced-feed.md Include podcast-specific fields like `itunes_author`, `itunes_category`, `image`, `itunes_item_image`, `itunes_duration`, `enclosure_url`, `enclosure_length`, and `enclosure_type` for podcast feed compatibility. ```javascript return { itunes_author: '', // This field is **required** and should specify the podcast author's name itunes_category: '', // This field specifies the channel category image: '', // This field specifies the channel's cover image or album art item: [ { itunes_item_image: '', // This field specifies the item's cover image itunes_duration: '', // This field is optional and specifies the length of the audio in seconds or the format H:mm:ss enclosure_url: '', // This should be the item's direct audio link enclosure_length: '', // This field is optional and specifies the size of the file in **bytes** enclosure_type: '', // This field specifies the MIME type of the audio file (common types are 'audio/mpeg' for .mp3, 'audio/x-m4a' for .m4a, and 'video/mp4' for .mp4) }, ], }; ``` -------------------------------- ### Play with Docker - Deploy RSSHub Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md This button deploys RSSHub using Play with Docker. It's suitable for testing and validating routing rules, but not for persistent solutions. ```docker version: "3.7" services: rsshub: image: diygod/rsshub:latest ports: - "1200:1200" restart: always ``` -------------------------------- ### Fetch Full Article Text with Puppeteer and Cheerio Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/start-code.md Use this code to fetch the full text of articles from a list of links. It utilizes Puppeteer for page navigation and content retrieval, and Cheerio for parsing the HTML. Ensure Puppeteer is installed and configured. ```typescript import { Route } from '@/types'; import { load } from 'cheerio'; import { parseDate } from '@/utils/parse-date'; import logger from '@/utils/logger'; import puppeteer from '@/utils/puppeteer'; import cache from '@/utils/cache'; export const route: Route = { // ... handler: (ctx) => { const baseUrl = 'https://github.com'; const { user, repo = 'RSSHub' } = ctx.req.param(); const browser = await puppeteer(); const page = await browser.newPage(); await page.setRequestInterception(true); page.on('request', (request) => { request.resourceType() === 'document' ? request.continue() : request.abort(); }); const link = `${baseUrl}/${user}/${repo}/issues`; logger.http(`Requesting ${link}`); await page.goto(link, { waitUntil: 'domcontentloaded', }); const response = await page.content(); page.close(); const $ = load(response); const list = $('ul[class^="ListView-module__ul__"] li[class^="ListItem-module__listItem__"]') .toArray() .map((item) => { const $item = $(item); const a = $item.find('a').first(); return { title: a.text(), link: `${baseUrl}${a.attr('href')}`, pubDate: parseDate($item.find('relative-time').attr('datetime')), author: $item.find('div[data-testid="created-at"] a').text(), category: $item .find('a[class^="prc-Link-Link-"] span[class^="prc-Text-Text-"]') .toArray() .map((item) => $(item).text()), }; }); const items = await Promise.all( list.map((item) => cache.tryGet(item.link, async () => { // reuse the browser instance and open a new tab const page = await browser.newPage(); // set up request interception to only allow document requests await page.setRequestInterception(true); page.on('request', (request) => { request.resourceType() === 'document' ? request.continue() : request.abort(); }); logger.http(`Requesting ${item.link}`); await page.goto(item.link, { waitUntil: 'domcontentloaded', }); const response = await page.content(); // close the tab after retrieving the HTML content page.close(); const $ = load(response); item.description = $('[class^="markdown-body"][class*="NewMarkdownViewer-module__safe-html-box__"]').first().html(); return item; }) ) ); // close the browser instance after all requests are done browser.close(); return { title: `${user}/${repo} issues`, link: `https://github.com/${user}/${repo}/issues`, item: items, }; }, }; ``` -------------------------------- ### Scrape Web Page Content with Puppeteer Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/start-code.md Use this snippet to fetch HTML content from a given URL using Puppeteer. It demonstrates setting up request interception to only allow document resources and logging the request URL. Ensure Puppeteer is properly installed and configured. ```typescript import { Route } from '@/types'; import { load } from 'cheerio'; import { parseDate } from '@/utils/parse-date'; import logger from '@/utils/logger'; import puppeteer from '@/utils/puppeteer'; export const route: Route = { // ... handler: (ctx) => { const baseUrl = 'https://github.com'; const { user, repo = 'RSSHub' } = ctx.req.param(); // require puppeteer utility class and initialise a browser instance const browser = await puppeteer(); // open a new tab const page = await browser.newPage(); // intercept all requests await page.setRequestInterception(true); // only allow certain types of requests to proceed page.on('request', (request) => { // in this case, we only allow document requests to proceed request.resourceType() === 'document' ? request.continue() : request.abort(); }); // visit the target link const link = `${baseUrl}/${user}/${repo}/issues`; // ofetch requests will be logged automatically // but puppeteer requests are not // so we need to log them manually logger.http(`Requesting ${link}`); await page.goto(link, { // specify how long to wait for the page to load waitUntil: 'domcontentloaded', }); // retrieve the HTML content of the page const response = await page.content(); // close the tab page.close(); const $ = load(response); // const item = ...; // don't forget to close the browser instance at the end of the function browser.close(); return { // Your RSS output here }; }, } ``` -------------------------------- ### Create a BitTorrent/Magnet Feed Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/advanced/advanced-feed.md Include `enclosure_url` (Magnet URI), `enclosure_length` (optional file size), and `enclosure_type` ('application/x-bittorrent') in your item to create a BitTorrent/Magnet feed. ```javascript return { item: [ { enclosure_url: '', // This should be the Magnet URI enclosure_length: '', // The file size in bytes (this field is optional) enclosure_type: 'application/x-bittorrent', // This field should be fixed to 'application/x-bittorrent' }, ], }; ``` -------------------------------- ### Configure Upstash Redis Cache Source: https://github.com/rssnext/rsshub-docs/blob/main/src/deploy/index.md Create a Redis database using flyctl and configure the connection URL with the necessary 'family=6' parameter. Then, set the environment variables or secrets for RSSHub. ```bash $ flyctl redis create ``` ```bash $ fly secrets set CACHE_TYPE=redis REDIS_URL='' ``` -------------------------------- ### Deploy to Google App Engine Source: https://github.com/rssnext/rsshub-docs/blob/main/src/zh/deploy/index.md Command to deploy your RSSHub project to Google App Engine. Refer to the documentation for deploying services with custom names or project IDs. ```bash gcloud app deploy ``` -------------------------------- ### Fetch Full Article Text with Caching Source: https://github.com/rssnext/rsshub-docs/blob/main/src/joinus/new-rss/start-code.md Fetches a list of issues from a GitHub repository and then, for each issue, fetches its full content to extract the description. Uses `ofetch` for HTTP requests and `cheerio` for parsing HTML. Caching is employed to manage multiple requests. ```typescript import ofetch from '@/utils/ofetch'; import cache from '@/utils/cache'; import { load } from 'cheerio'; import { parseDate } from '@/utils/parse-date'; export const route: Route = { // Write the routing information introduced in the previous text here. handler: (ctx) => { const baseUrl = 'https://github.com'; const { user, repo = 'RSSHub' } = ctx.req.param(); const response = await ofetch(`${baseUrl}/${user}/${repo}/issues`); const $ = load(response); const list = $('ul[class^="ListView-module__ul__"] li[class^="ListItem-module__listItem__"]') .toArray() .map((item) => { const $item = $(item); const a = $item.find('a').first(); return { title: a.text(), link: `${baseUrl}${a.attr('href')}`, pubDate: parseDate($item.find('relative-time').attr('datetime')), author: $item.find('div[data-testid="created-at"] a').text(), category: $item .find('a[class^="prc-Link-Link-"] span[class^="prc-Text-Text-"]') .toArray() .map((item) => $(item).text()), }; }); const items = await Promise.all( list.map((item) => cache.tryGet(item.link, async () => { const response = await ofetch(item.link); const $ = load(response); // Select the first comment body as there are multiple comment bodies in each issue page, // and we need to specify which one we want to use. item.description = $('[class^="markdown-body"][class*="NewMarkdownViewer-module__safe-html-box__"]').first().html(); // Every property of a list item defined above is reused here // and we add a new property 'description' return item; }) ) ); return { title: `${user}/${repo} issues`, link: `https://github.com/${user}/${repo}/issues`, item: items, }; }, }; ```