使用 Telegram 订阅 Pixiv 新图

作为一名艺术爱好者,时刻关注 Pixiv 上画师的更新是一种重要的生活习惯。然而,每天手动检查新图既费时又费力,是否有更便捷的方法来推送这些喜欢的图片,让每一张图都有机会展现它的光彩呢?

我想到了一种常用的资讯订阅方式:RSS。通过查阅 RSSHub 的文档,我发现了针对 Pixiv 关注画师的新图的订阅接口。

然而,单纯的 RSS 订阅并不方便,还需要一个单独的阅读器。与其如此,不如直接将这些资讯推送至通讯工具上。之前,我使用基于 IFTTT 的解决方案,将 RSSHub 生成的内容推送至 Telegram 频道。但由于 IFTTT 的使用策略更改,非付费用户只能创建三个小程序,因此我放弃了这个方案。作为开发者,我决定自己编写一个功能类似的处理工具,这不仅能锻炼我的代码能力,还能提供更高的自定义能力。

于是,我开始查询各种 API 接口,整理资料。思路很简单:通过 RSS 采集数据,整理后通过 Bot 的 API 接口发送至 Telegram 频道。由于我习惯使用 Node.js 进行开发,这次也选择了 Node.js 作为开发与部署平台。

第一步:RSS 采集

首先是 RSS 的采集工作。为了避免费时费力的手动分析 XML 文件,我直接使用了一个现成的组件:rss-parser。这个组件能够获取 RSS 资讯,并将其转化为一个对象,方便后续处理。

bash
npm i rss-parser –save

使用完成后的传参调用方式也非常简洁明了。虽然可以使用官方样例中的 async 与 await 异步函数处理方式,但我选择了直接传递参数。

在测试时,可以将获取的 feed 信息输出,以 RSSHub 生成的数据为例,我们不难发现其实内部是一个对象数组,因此可以直接使用相关字段进行内容处理。

第二步:数据处理

由于 RSSHub 的设计初衷是为了方便阅读,生成的内容格式以便于阅读为主,并使用了 pixiv.cat 的图片传递接口作为主要组成部分。不过,获取的内容中包含了我们需要的所有信息,因此可以使用正则表达式来提取。

对于单张图片的内容,RSSHub 将其处理成形如 ` 的链接;而对于多图内容,ArtworkID 后的-PicID` 也是我们关注的关键。因此,我们可以使用以下正则表达式进行处理:

javascript
const picIdReg = /https:\/\/pixiv.cat\/(\d+)-?(\d+)?.(jpg|png|gif)/gi;

结合这条正则表达式,可以直接生成内容数组:

javascript
const artworks = […item.content.matchAll(picIdReg)];

对于单图的输入,我们能得到如下输出:

Array [“”, “ArtworkID“, “1”, “jpg”]
Array [“”, “ArtworkID“, “2”, “jpg”]
Array [“”, “ArtworkID“, “3”, “jpg”]

考虑到 Telegram 对于图片大小的限制,选择使用预览图发送、使用完整图下载的方案。通过查看 Pixiv 前端页面的源码,预览图的地址由前缀、发布时间(UTC+9)、作品 ID 和一些固定组合搭配而成。发布时间可以由 RSS item 中的 isoDate 手动计算获取,我们可以写一个整合表达式来完成预览图地址的装配工作。

第三步:消息发送

之前在 IFTTT 中使用的是直接推送订阅内容、让 Telegram 自动获取的方式,这导致了大图片(≥5MB)无法有效获取、图片缓存请求限制等问题。因此,这次我们加入请求缓冲队列和预览图片,尝试解决以上问题。

本来打算使用 Telegraf 作为推送框架,但考虑到只需发送一个请求信息,因此直接使用 got 进行 POST 请求的发送。根据 Telegram 的 Bot API 文档,可以整理出如下请求样式:

javascript
const apiBaseUrl = https://api.telegram.org/bot${confData.bot.token};

got(‘sendPhoto’, {
method: ‘POST’,
prefixUrl: apiBaseUrl,
json: {
chat_id: confData.bot.chat,
photo: picItem.preview,
caption: picItem.text,
reply_markup: {
inline_keyboard: [
[{
text: ‘🌏’,
url: picItem.url
}, {
text: ‘⤵’,
url: picItem.pic
}]
]
}
}
});

直接调用 Telegram 的 sendPhoto 接口发送图片请求数据,其中加入了消息下的内联小键盘 inline_keyboard,提供图片的原始链接按钮和直接下载按钮,方便用户操作。Bot API Token 可以向 @BotFather 申请,Chat ID 可以使用 @频道名,而不必纠结于一长串的频道 ID。

为了避免每次启动时将所有图片加入队列等待发送,同时考虑到项目提供的所有数据都是按时间排序的,因此维护一个 timestamp,初始化为当前时间,每次将待发送的图片时间中记录最晚值,之后查询时仅发送更新的内容并更新时间戳标记即可。

为了进一步为用户提供方便,我还加入了 js-yaml 组件来读取 yml 配置文件。综合以上内容,最终整合的版本已经发布到了 GitHub 上的 PhanDream 仓库中;您可以使用 pm2 等方式进行运行:

bash
pm2 start bot.js –name phandream

当一切准备完成后,过一会就能发现频道中出现新的图片啦~

👉 野卡 | 一分钟注册,轻松订阅海外线上服务

(0)
上一篇 2025年4月6日
下一篇 2025年4月6日

相关推荐