如何优雅地订阅 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
语法定义。
准备工作
首先熟练掌握 yaml
、json
、jinja2
语法。
为了配置 RSS 订阅,可能需要先在本地对 RSS 链接进行分析。分析步骤如下:
首先安装好 python
和pip
。
其次安装依赖:
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_url | DATABASE | ✅ | MongoDB 数据库 URL | |
expire_time | EXPIRE_TIME | ❎ | 30d | 数据库中的数据过期时间,见 说明 3 |
user-agent | USER-AGENT | ❎ | 浏览器 UA | 请求所用的 User-Agent |
telegraph_access_token | TELEGRAPH_ACCESS_TOKEN | ❎ | 用于生成 Telegraph | |
notify_tg_chat_id | NOTIFY_TG_CHAT_ID | ❎ | 发送 RSS 链接过期、清理数据库等通知信息,见 说明 2 | |
telegram.token | TG_TOKEN | ❎ | 参考 Telegram 文档 获取 Telegram Bot Token | |
telegram.chat_id | TG_CHAT_ID | ❎ | 推送 RSS 订阅通知 | |
telegram.disable_notification | TG_DISABLE_NOTIFICATION | ❎ | false | 默认推送通知时是否静默 |
telegram.disable_web_page_preview | TG_DISABLE_WEB_PAGE_PREVIEW | ❎ | false | 默认推送通知时是否预览 |
telegram.parse_mode | TG_PARSE_MODE | ❎ | MarkdownV2 | 默认推送通知时的解析文字的格式 |
mastodon.base_url | MASTODON_BASE_URL | ❎ | Mastodon 实例 完整地址 | |
mastodon.client_id | MASTODON_CLIENT_ID | ❎ | 参考Mastodon 文档 | |
mastodon.client_secret | MASTODON_CLIENT_SECRET | ❎ | 如上 | |
mastodon.authorization_code | MASTODON_AUTHORIZATION | ❎ | 如上 |
说明:
- Sender:将发送通知的工具称为 Sender。目前仅有 Telegram 和 Mastodon,二者中至少要有一个的定义为有效的:
- Telegram:定义有效的
token
和chat_id
。 - Mastodon:定义有效的
base_url
、client_id
、client_secret
。
- Telegram:定义有效的
- 如果定义了有效的 Telegram 配置,即可使用 RSS 过期通知。建议
notify_tg_chat_id
定义为个人的 ID。 expire_time
可取值为数字 +y/m/d/h(例如1y
,2m
,15d
,10h
),分别代表年、月、日、时。该项表示执行清理时保留直到多久前的数据,没有特殊需求保持默认即可。
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
:可以是regex
或func
。dest
:处理完成的文本储存的变量。例如若其为dest_text
,则可以在text
中通过{{ dest_text }}
来使用。matcher
:(假设dest
为dest_text
)- 如果
type
为regex
,则为一个正则表达式的字符串,用()
来提取需要的文本。如果只匹配一项,则可在text
中用{{ dest_text }}
来引用;如果匹配多项,则可在text
中用{{ dest_text[数字] }}
来引用,注意此时默认{{ dest_text[0] }}
为匹配到的整个字符串。 - 如果
type
为func
,则为一个简单 python 函数的多行字符串,输入和输出仅能为 1 个变量,分别代表obj
和dest
,会将输入的变量进行处理后赋值到输出变量中。
- 如果
filters
(可选):过滤规则,可以过滤掉指定通知。过滤规则会从上至下依次匹配。具体定义如下:obj
:处理的对象,同rules
。matcher
:匹配的正则表达式字符串。type
:可为in
或out
。如果为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 后,即会自动运行。
本地运行
首先安装好 python
和pip
。
其次安装依赖:
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 等跑,只要是同一个数据库即可,谁不爱白嫖呢(