作为一名练习时长两年半的业余编程爱好者,平时真正能写代码的机会并不多。然而众所周知编程语言和自然语言一样,长时间不练习就会自然遗忘,所以有时还是会硬整点需求随便写一写。于是便有了本次所开发的 TG 网盘机器人,代码已经完全开发完毕,仅作为学习目的开源共享。毕竟个人水平有限,欢迎各路大佬 PR 或是 Fork 。
因为安装部署说明在 WiKi 里已经写得很详细了,这边就只是做个大致记录和说明。
项目地址:https://github.com/reizhi/tg-media-link-hoster (含 DEMO)
0.开发背景
TG 虽然是一款聊天软件,但与众不同的是所有聊天文件和媒体都存储在云端,不会像某小而美一样存在文件过期的问题。再加上 2GB(会员 4GB )的单文件限制,使得 TG 在某种程度上很适合用来提供文件存储、共享服务。
但与此同时作为一款聊天软件,想要公开上传、分享文件却并不是太容易。虽然这多少有违一款聊天软件的初衷,但事实现状就是当下很多 TG 频道、群组被作为文件共享服务而使用。于是最终便有了这个项目,这个机器人能够像常规的网盘一样使用:上传一个文件,获得一个(特殊)链接。或是提交一个链接,获得对应的文件。
如果你觉得这个项目存在滥用嫌疑,请不要使用。
1.主要功能
文件分享:
- 向机器人发送媒体或媒体组,获得两个特殊的链接:“主分享 KEY”(下简称 mkey )和“一次性 KEY”(下简称skey)
- 向机器人发送 mkey ,无限制的取回对应的媒体或媒体组
- 向机器人发送skey ,取回对应的媒体或媒体组,对应 skey 随即失效
文件管理:
- 资源上传者,可以向机器人发送 mkey 来获取最新的 skey
- 资源上传者, 可以对资源进行命名
- 资源上传者, 可以搜索主动命名过的自己上传的资源
可选功能:
- 资源多份备份,避免机器人被封禁导致链接失效
已预留功能:
- 展示资源被获取的次数(已做后端存储,未做前端展示)
2.运行逻辑
机器人收到媒体或媒体组时,通过多因素随机生成三组字符串:
- 资源索引:64位
- 主密钥:12位
- 单次密钥:12位
在写数据库后,向上传者返回拼接后的分享链接:mlk 资源索引 主密钥
和单次链接:mlk 资源索引 单次密钥
。
机器人收到文本消息时,通过正则匹配尝试分享链接提取。如果提取成功,再使用资源索引进行数据库索引。如没有匹配不返回任何内容,如匹配成功则进一步比对密钥。
- 如果用户所提交的密钥与主密钥相同,返回对应的媒体并进行计数。同时检查当前用户是否为资源上传者,如是则一并返回该资源的当前单次密钥。
- 如果用户所提交的密钥与单次密钥相同,随机轮换单次密钥,返回对应媒体并进行计数。
机器人收到包含 /name
命令的回复类型消息时,首先检查被回复消息内分享链接的创建者是否与当前用户一致。如一致,接受命名指令并写数据库。如不一致,拒绝命名指令。
机器人收到 /s
命令时,通过当前用户 id 和搜索关键词在数据库中检索符合的记录。记录不为空时,返回对应的分享链接。
3.容灾备份
为了应对可能的账号、群组消失事件,网盘配备了可选的备份功能,用于将媒体复制存储到多个群组中。
机器人在收到媒体消息后,会将其复制到存储群组,并记录对应的消息 ID 。此时在数据库中会记录下资源密钥所对应的消息 ID,以供取回媒体时使用。该媒体的发送者身份为 BOT 自身。
如果启用了容灾备份功能,账号2(或账号3,下同)会定时扫描数据库中未做备份的资源记录,并根据对应的群组 ID 和消息 ID,将存储群组中的媒体复制到备份群组。该媒体的发送者身份为账号2。
在遭遇 BOT 账号或资源存储群组消失事件时,只需对脚本代码进行极少的修改,使新的 BOT 在备份群组中取回原有资源即可。由于数据库中记录了媒体密钥在各群组中的储存位置,故其中一份或两份丢失并不影响整体可用性。
4.运行截图
5.后记
Pyrogram 好久不更新了,PR 也没人处理,TG-PY 库还是优先考虑 Telethon 吧。
关于一次性密钥:因为是2个协程并发处理取回请求,可能会出现一次性密钥被两个用户同时获取的情况。不是什么严重 bugs,懒得改了。