如何优雅地订阅 RSS

本文最后更新于:2023年2月20日 中午

前言

由于我用 js 重写了一遍,本文已经失效,请直接前往 仓库 查看最新的部署方法!

自从 RSSHub 让 RSS 再度成为一种流行的信息订阅方式后,有许多大佬做出了很好用的订阅 RSS 至 Telegram 的机器人,例如:

但是这些机器人无法自定义 RSS 订阅的通知格式,让我这种轻度强迫症非常难受。

为了美观考虑,我自己写了一个基于 Github Action 的、高度自定义 的 RSS 订阅通知服务,目前支持订阅至 Telegram 和 Mastodon。

项目地址:

使用配置

主要思路

  • 数据库:MongoDB,官方有 512MB 的免费额度,足够使用,建议选择 Azure 美国地区。
  • 主配置文件:config.yaml,如果是基于 Github Action 进行定时执行,所有配置都可以用环境变量来定义。
  • RSS 配置文件:rss.yaml,如果不介意可以直接上传至仓库中,否则可以用私库或者自定义文件链接。
  • 通知模板:配置于 RSS 配置文件中,由 jinja2 语法定义。

准备工作

首先熟练掌握 yamljsonjinja2 语法。

为了配置 RSS 订阅,可能需要先在本地对 RSS 链接进行分析。分析步骤如下:

首先安装好 pythonpip

其次安装依赖:

pip install pipenv
git clone https://github.com/Apocalypsor/Formatted-RSS-to-Telegram.git && cd Formatted-RSS-to-Telegram
pipenv install

项目中已经提供了分析的脚本,只需要传入 RSS 链接:

pipenv run python test/rss.py https://github.com/Apocalypsor/Formatted-RSS-to-Telegram/commits/main.atom

然后会在 test 目录下生成对应的 json 文件,例如:

[
    {
        "link": "https://github.com/Apocalypsor/Formatted-RSS-to-Telegram/commit/e62543dfe6a13eba317103d3f1f1f85f9303431e",
        "title": "Update config.yaml",
        "title_detail": {
            "type": "text/plain",
            "language": "en-US",
            "base": "https://github.com/Apocalypsor/Formatted-RSS-to-Telegram/commits/main.atom",
            "value": "Update config.yaml"
        },
        "authors": [
            {
                "name": "Apocalypsor",
                "href": "https://github.com/Apocalypsor"
            }
        ]
    }
]

以下的处理规则是针对于该数组中的 每一个元素 而言。

配置文件

主配置文件 data/config.yaml

建议 都用环境变量来定义,而不要修改data/config.yaml。环境变量优先级更高。

主配置无法自定义文件名。参考配置文件:config.yaml

具体配置如下:

配置文件项环境变量必须默认值说明
database_urlDATABASEMongoDB 数据库 URL
expire_timeEXPIRE_TIME30d数据库中的数据过期时间,见 说明 3
user-agentUSER-AGENT浏览器 UA请求所用的 User-Agent
telegraph_access_tokenTELEGRAPH_ACCESS_TOKEN用于生成 Telegraph
notify_tg_chat_idNOTIFY_TG_CHAT_ID发送 RSS 链接过期、清理数据库等通知信息,见 说明 2
telegram.tokenTG_TOKEN参考 Telegram 文档 获取 Telegram Bot Token
telegram.chat_idTG_CHAT_ID推送 RSS 订阅通知
telegram.disable_notificationTG_DISABLE_NOTIFICATIONfalse默认推送通知时是否静默
telegram.disable_web_page_previewTG_DISABLE_WEB_PAGE_PREVIEWfalse默认推送通知时是否预览
telegram.parse_modeTG_PARSE_MODEMarkdownV2默认推送通知时的解析文字的格式
mastodon.base_urlMASTODON_BASE_URLMastodon 实例 完整地址
mastodon.client_idMASTODON_CLIENT_ID参考Mastodon 文档
mastodon.client_secretMASTODON_CLIENT_SECRET如上
mastodon.authorization_codeMASTODON_AUTHORIZATION如上

说明:

  1. Sender:将发送通知的工具称为 Sender。目前仅有 Telegram 和 Mastodon,二者中至少要有一个的定义为有效的:
    • Telegram:定义有效的 tokenchat_id
    • Mastodon:定义有效的base_urlclient_idclient_secret
  2. 如果定义了有效的 Telegram 配置,即可使用 RSS 过期通知。建议 notify_tg_chat_id 定义为个人的 ID。
  3. expire_time可取值为数字 +y/m/d/h(例如1y2m15d10h),分别代表年、月、日、时。该项表示执行清理时保留直到多久前的数据,没有特殊需求保持默认即可。

RSS 订阅配置文件 data/rss.yaml

可以通过定义环境变量 RSS_CONFIG 来定义读取的文件(默认读取data/rss.yaml)。

例如将其定义为 rss2.yaml,则会读取data/rss2.yaml 文件。

也可以将其定义为一个链接(必须以 http 开头),例如 https://raw.githubusercontent.com/Apocalypsor/Formatted-RSS-to-Telegram/main/data/rss_example.yaml

如果链接需要 Bearer Authentication(例如 Github),可以定义环境变量 AUTHORIZATION_TOKEN 来验证。

配置文件仅读取 rss 项,其包含一个数组。以下是该配置文件的主要格式:

rss:
  - name:
    url:
    rules:
      - obj:
        type:
        matcher:
        dest:
    filters:
      - obj:
        type:
        matcher:
    # fulltext:
    # telegraph:
    # content:
    #   obj: summary
    #   matcher:
    # sender:
    #   telegram:
    #   mastodon:
    sendto:
    text:

❗注意:首次添加进配置文件的 RSS 订阅项不会推送通知,以免被通知轰炸。

以下进行逐一解释:

订阅定义

  • name:订阅名称。用于数据库的记录,也可以在 text 中通过 {{ rss_name }} 来使用。

    name: RSS 订阅
  • url:RSS 订阅链接。可以在 text 中通过 {{ rss_url }} 来使用。

    请注意 每一个订阅链接在配置文件中最好是唯一的

    url: https://sspai.com/feed
    
    url:
      - https://github.com/Fndroid/clash_for_windows_pkg/releases.atom
      - https://github.com/Dreamacro/clash/commits/dev.atom

订阅处理

  • rules(可选):处理规则,可以对文本进行一定的处理。具体定义如下:
    • obj:处理的对象,以 . 相隔代表子项,例如 a.0.c 代表["a"][0]["c"]
    • type:可以是 regexfunc
    • dest:处理完成的文本储存的变量。例如若其为 dest_text,则可以在text 中通过 {{ dest_text }} 来使用。
    • matcher:(假设 destdest_text
      • 如果 typeregex,则为一个正则表达式的字符串,用 () 来提取需要的文本。如果只匹配一项,则可在 text 中用 {{ dest_text }} 来引用;如果匹配多项,则可在 text 中用 {{ dest_text[数字] }} 来引用,注意此时默认 {{ dest_text[0] }} 为匹配到的整个字符串
      • 如果 typefunc,则为一个简单 python 函数的多行字符串,输入和输出仅能为 1 个变量,分别代表 objdest,会将输入的变量进行处理后赋值到输出变量中。
  • filters(可选):过滤规则,可以过滤掉指定通知。过滤规则会从上至下依次匹配。具体定义如下:
    • obj:处理的对象,同rules
    • matcher:匹配的正则表达式字符串。
    • type:可为 inout。如果为in,则匹配到的项可以被推送;如果为out,则未匹配到的项可以被推送。
  • fulltext(可选):true或者false,是否对 rss 获取全文。

Telegraph

  • telegraph(可选):true或者 false,是否针对内容生成 Telegraph 文章。生成的Telegraph 链接 可以在 text 中用 {{ telegraph }} 来引用。

  • content(可选):为了避免 RSS 中没有所需的内容,以及一些特别的需求,用于处理文本以生成 Telegraph 文章,便于即使预览。可以在 text 中通过 {{ rss_content }} 来使用。

    应包含:

    • obj:处理的对象,同上。
    • matcher:为一个简单 python 函数的多行字符串,输入和输出仅能为 1 个变量,输入代表obj,输出处理完的文本。

通知订阅

  • sender(可选):对于单个 RSS,可以对其定制化的配置通知,覆盖主配置文件中的配置。

    sender:
      telegram:
        parse_mode:

    配置方式与主配置文件完全相同。

  • sendto:如果 仅配置了一个有效的 Sender,则无需配置改项 ,仅会通过该 Sender 发送通知;否则需要在 每个 RSS 配置 中指定。

    sendto: telegram
    
    sendto:
      - telegram
      - mastodon

通知模板

  • text:推送通知的模板,可以用 jinja2 语法。特别注意,此中可引用的变量包括 RSS 中的内容、rules中处理的文本的 dest、{{ rss_name }}(表示上述 name 的值)、{{ rss_url }}(表示对应 RSS 的 URL)、{{ telegraph }}(Telegraph 链接)、{{ rss_content }}(上述 content 中的输出文本,若无content,则在 RSS 中自动提取)

使用方法

Github Action

请手动 clone 后上传到 Github 上,然后进行对应的配置并开启 Action 后,即会自动运行。

本地运行

首先安装好 pythonpip

其次安装依赖:

pip install pipenv
git clone https://github.com/Apocalypsor/Formatted-RSS-to-Telegram.git && cd Formatted-RSS-to-Telegram
pipenv install

最后执行:

# 推送通知
pipenv run python main.py

# 清理数据库
pipenv run python clean.py

后记

本项目完全是自娱自乐,配置十分复杂,不建议小白使用。

但是通过一通操作实现了 完全 0 成本的白嫖,即使 Github Action 封了也能用 Vercel、Heroku 等跑,只要是同一个数据库即可,谁不爱白嫖呢(


如何优雅地订阅 RSS
https://blog.dov.moe/posts/56849/
作者
Dov
发布于
2021年8月7日
许可协议