update @2021.12.24:
由于Todoist限制免费用户项目数量、IFTTT限制免费用户任务数,不适合后续对有价值视频的存档,因此作者用Cubox替代了Todoist的功能:监控脚本直接通过Cubox的API创建记录,可以不使用IFTTT和Todoist
现状
作为一个B站重度使用用户,曾经关注里躺着几百UP,每天睡前会无数次下拉首页刷新防止错过更新,视频列表刷不到尽头,动态里面更是天天99+。
实际上,B站的视频我只想按照UP的维度来获取更新,或者喜欢的只是UP的某一个系列,除此之外最多加上每周必看,然而几百的关注严重干扰了视频更新时间线,我又不可能靠首页推荐算法随机捕捉,加上平时洗漱的无聊时间又不想错过更新,于是,我需要一个简明扼要的方式,告诉我谁什么时间更新了什么
核心诉求和思路
UP的名字、投稿时间和投稿标题基本上可以确认我要不要看;
根据视频内容或者UP来源,分类到不同优先级的列表下;
可以快速记录看、看过和不看。
总体上看,我需要的是一个实时监控UP投稿并且分类成不同的列表的方案,简单拆分下。
监控部分,关心的是UP的投稿。可以直接轮询B站的API、可以用第三方RSS。这里选择RSSHub,优点是不用重复开发,也不用关心B站的API,缺点是被墙和有一定的延迟。
记录部分,我们把一个投稿看成TODO类应用的Inbox事件,这个问题就简单多了。这里直接用todoist的列表就可以解决分类和记录问题。为了更好的分类,这里引入IFTTT的Webhook
实现和一些细节
先上结果
左边是项目,根据我的规则,这是按照UP来分类的,右边是投稿内容,如果不看,直接点小圆点就会消失,如果要现在看,点开项目,点击bilibili://video/[ID]这个URLSchema即可在iOS平台下面直接拉起bilibili并播放(我刷B站的主力是iPad)
下面一步一步说明它是怎么实现的
0. 基础组件
可以访问RSSHub(有墙)和IFTTT的WebhookURL的服务,可以是墙外的VPS,可以是云函数等服务
另外,写好从RSSHub拉取更新的代码,以及推送到IFTTT WebHookURL的代码(如果你想用我的也可以,下拉到最后贴了地址)
下面我们用一个🌰来说下我的完整的流程,其中,通过DB记录是可选的,你完全可以用本地文件(xml,json)的方式来实现
1. 核心流程
例如我想收到TESTV的投稿通知,首先我要知道他的UID,访问其B站主页https://space.bilibili.com/11336264,后面的这个11336264就是UID。
然后去https://todoist.com/app/#start上添加一个项目,记住它的名字,比如评测区
在IFTTT上创建(https://ifttt.com/create)一个将Webhook转发到Todoist的Applets,这里详细描述一下:
点击+This后,在搜索框中输入Webhooks,点击后会出现Receive a web request选项(也是唯一的选项),选它
之后会让你输入event_name,这个event_name会出现在你的WebhookURL中,建议与你想要做的分类相关,我们最后会用不同的WebhookURL推送到不同的Todoist项目。
比如我这里填:bili_tech_test
点击Create trigger后,就会回到/create的界面,我们继续点击+That
这次我们找到Todoist,表示被做的事情,同样,它应该也只有一个选项,叫做Create Task
project就是我们在Todoist上的项目,选择它表示在这里创建任务
重点是TaskContent,这个是标题,ValueN这三个模板变量,是你发给WebhookURL的参数,可控(点Add ingredient来输入这种模板变量,或者用双大括号)
最后点击Create action,再点击Finish
那么,往哪里发送Webhook请求呢?点开https://ifttt.com/maker_webhooks,这里有与你Webhook有关的所有Applets,点击右上角的Documentation,你会得到一个与Key和Event有关的URL,这里Event就是上面第一步填的EventName,Key是与用户有关的字符串,可以看到,这里valueN都是可以指定的
3. 同步数据
我创建了一个DB(代码里有),用于表示我从哪个URL拉取内容,推送到哪个URL
另外一张表,记录拉取到的投稿,这两步骤是分开的
在代码中,这个流程就是:
1. 从fetcher表中按上次运行时间时间获取RSSHub的地址
2. 拿到RSSHub中的更新内容,如果不存在,就放到bilivideo表中,新创建的记录标记为未推送
3. 遍历Bilivideo没有推送的投稿,向IFTTT的WebHookURL发送请求,返回成功后,在DB中更新状态表示已经推送过
3. 定时
将同步代码放到VPS上,crontab配个1min执行一次,就等着数据上门就好了,或者使用云函数方式也可替代这个步骤
*/1 *
*
* *
/usr/bin/python3.6 /root/scf/bili2ifttt.py >> /root/scf/bili2iftt.log &
4. 细节和注意事项
理论上,你可以随意指定来源,例如非Webhook来源的URL,根据fetch_method做区分就可以了。
不同的分类需要创建不同的IFTTT Event Name,用不同的WebHookURL来区分。
同样,DB也不是最佳方案,它显得笨重了,如果仅仅是需要几个更新,完全可以用XML/JSON保存到本地文件的方式来完成,本质上,这里只是需要一个存储+去重方案,XML/JSON本身也是DB的一种形式,大家都一样。
bilibili://这种唤起方式叫做URLSchema,理论上其他设备有类似的方案,不过我没有安卓和Win设备,不太清楚。
你还有可能遇到一些问题,比如脚本执行太快,且数据获取的时候没有加锁,导致未推送的内容推送了多次,这个解决方案很多,各人按照情况来吧,只要你的脚本执行时间小于运行间隔时间就好。
IFTTT的所有步骤,可以在APP上操作,但是,建议在Web上创建,手机上用于修改Project和启用停用。
Todoist有每个项目300的上限,如果到了300,就会导致推送失败,IFTTT会把这个Applets关掉,这时候需要删掉一些任务,然后重新启用。
最后不知道大家有没有注意到,crontab的这个任务的执行目录中是有一个scf的,这是之前跑脚本是用的scf(腾讯云云函数),它替代了vps的这个步骤(crontab),要不是它每小时2块钱的扣费(请求量太大了)和一些奇奇怪怪的bug我还会继续用它QwQ
最后
工具是为需求服务的,不要本末倒置,这里用了RSSHub+IFTTT纯属个人选择较为熟悉的工具,并不代表这个方案最佳。
这个工作流已经正常运行大半年了,从我个人的体验上看,我可以每天下班回来打开iPad就看到谁更新了什么,根据自己的喜好点开看,看完就接着点下一个,也不需要关心是否错过投稿,它实现了一个按照分类查看未看投稿的功能。
这期间,我把关注从400+降到了10-,动态也干净了很多,之前用来拖延、下拉首页的时间可以用来睡觉。
最后回顾来看,将关心的内容明确,最重要的是减少了算法推送的触达率,起码我个人认为这些算法推荐的基本上没什么营养,顶多也就是乐呵乐呵,与其这样,不如把关心的内容看完就走,把这些时间拿去刷刷网课(shui)看看书(jiao),它不香吗?
代码在这里: lc4t's GitHub