新建rsshub 路由的快速入门教程

Posted by Valuex on September 7, 2024

背景

个人想利用rsshub创建一些网站的rss,但typescript/javascript 都不熟练,而官方的指南读懂还是需要一些门槛的。
网上也缺乏能够帮助路由开发者直接上手的详细说明文档,所以个人摸索实现了一个简单路由后就将操作记录了下来。
这篇文章就相当于一篇开发rsshub路由的快速入门参考吧。

开发环境搭建

  1. 安装node.sj https://nodejs.org/en/download/prebuilt-installer/current

  2. 安装git, fork 仓库
    可以免去,直接下载zip包,解压为rsshub_dir
  3. 安装pnpm
    3.1 用powershell安装pnpm
    Invoke-WebRequest https://get.pnpm.io/install.ps1 -UseBasicParsing | Invoke-Expression
    

    3.2 运行pnmp i安装依赖

    C:\Users\user_name\AppData\Local\pnpm\pnpm.exe i
    

    这个需要安装的内容比较多,等几分钟
    Progress: resolved 1272, reused 0, downloaded 161, added 147

    C:\Users\user_name\AppData\Local\pnpm\pnpm.exe dev
    
  4. 启动rsshub
    4.1 cmd 中cd到相应目录下,运行npm install

4.2 powershell 中运行npm run dev
报错:

无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本

解决办法:[https://blog.csdn.net/pro_fan/article/details/120457551]

  1. 浏览器中加载rsshub
    等2min,在浏览器中输入http://localhost:1200,即可看到rsshub成功加载的页面。

参考

  • ChatGPT
  • (https://blog.mjyai.com/2021/01/31/how-to-contribute-rsshub/)

创建第一个rsshub 路由

(rsshub)[https://docs.rsshub.app/zh/joinus/new-rss/start-code] 上的示例有点复杂,可以参照本文开发一个简单的路由。
本示例给园岭小学的公告创建一个rss路由。
概述:创建一个路由文件夹domain_dir,然后在其下定义两个文件namespace.tsaction_name.ts。保存后访问http://localhost:1200/domain_dir即可看到效果。

  1. 创建文件夹domain_dir 按照官方路由开发说明,需要创建一个二级域名的文件夹domain_dir。本示例中路由文件夹名具体为szftedu
    C:\Users\user_name\Downloads\RSSHub-master\lib\routes\szftedu
    
  2. 创建文件 namespace.ts 来定义命名空间
    创建domain_dir/namespace.ts 文件,本示例中具体为szftedu/namespace.ts

  3. namespace.ts中的内容 ``` typescript import type { Namespace } from ‘@/types’;

export const namespace: Namespace = { name: ‘园岭小学’, url: ‘ylxx.szftedu.cn)’, };


4. 定义路由动作  
   新建**domain_dir/route_action.ts**文件,本示例中具体为`szftedu/gonggao.ts`  

5. `szftedu/gonggao.ts` 中的内容
``` typescript
import { Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { load } from 'cheerio';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';

const link = 'https://computer.hdu.edu.cn';
const host = 'https://ylxx.szftedu.cn/xx_5828/xygg_5832/';


export const route: Route = {
    path: '',
    categories: ['university'],
    example: '/xx_5828/xygg_5832/',
    parameters: {},
    features: {
        requireConfig: false,
        requirePuppeteer: false,
        antiCrawler: false,
        supportBT: false,
        supportPodcast: false,
        supportScihub: false,
    },
    name: '公告',
    maintainers: ['xandery-geek'],
    handler,
    description: ``,
};

async function handler(ctx) {
    // const host = 'https://www.hitsz.edu.cn';
    // const category = ctx.req.param('category') ?? 'id-77';
    const link = `https://ylxx.szftedu.cn/xx_5828/xygg_5832/`;

    const response = await got(link);
    const $ = load(response.data);
    const category_name = '公告';

    const lists = $('div.pagenews04 div ul li')
        .toArray()
        .map((el) => ({
            title: $('a', el).text().trim(),
            link: $('a', el).attr('href'),
            pubDate: timezone(parseDate($('span[class=canedit]', el).text()), 8),
        }));

    const items = await Promise.all(
        lists.map((item) =>
            cache.tryGet(item.link, async () => {
                let str = item.link;
                let turelink='';
                if (str.includes("http")) {
                    turelink = item.link;
                  } 
                  else 
                  {
                    turelink = link + item.link;
                  }
                const response = await got.get(turelink);
                const $ = load(response.data);
                item.description = $('body').html();
                item.pubDate = timezone(parseDate($('.item').first().text().replace('发布时间:', '')), 8);
                return item;
            })
        )
    );

    return {
        title: '园岭小学公告',
        link:host,
        description: '园岭小学公告',
        item: items,
    };
}
  1. 调试
    powershell中跳转到rsshub_dir(通过cd xxx命令),运行npm run dev
    稍等1分钟后,在浏览中中输入http://localhost:1200/route_name, 本示例中具体为http://localhost:1200/szftedu
    就可以看到成功加载的内容了。
    如果有错误,可以直接在文本编辑器中对route_action.ts进行更改,并保存。保存后powershell中执行的命令会自动重新加载更新的route_action.ts。开发者只需要观察并等待powershell相关的命令重新完成加载,刷新浏览器对应的页面即可。

  2. 应用

    • 通过Fluent Reader 等rss路由器,订阅http://localhost:1200/route_name(本文具体为http://localhost:1200/szftedu)就能看到最终效果了。
    • 需要进一步跟进的问题:现在只能在开发的电脑上进行订阅,如何在其他环境(比如NAS上的Tiny Tiny RSS)中订阅?这个问题还需要进一步解决。目前看到的方案应该是将开发的路由合入到rsshub 主程序中,然后所有人都可以订阅了。貌似还不能直接放到个人部署的docker版rsshub中。