mirror of
https://github.com/krau/SaveAny-Bot.git
synced 2026-05-10 17:52:44 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d035a3409e | ||
|
|
6112f6c240 | ||
|
|
18eedf2edb | ||
|
|
5f9bba9ff7 | ||
|
|
0d3d2209be |
70
README.md
70
README.md
@@ -4,28 +4,70 @@
|
|||||||
|
|
||||||
**简体中文** | [English](https://sabot.unv.app/en/)
|
**简体中文** | [English](https://sabot.unv.app/en/)
|
||||||
|
|
||||||
把 Telegram 上的文件转存到多种存储端.
|
> **把 Telegram 上的文件转存到多种存储端.**
|
||||||
|
|
||||||
|
[](https://github.com/krau/saveany-bot/releases)
|
||||||
|
[](https://github.com/krau/saveany-bot/releases)
|
||||||
|
[](https://github.com/krau/saveany-bot/actions/workflows/build-release.yml)
|
||||||
|
[](https://github.com/krau/saveany-bot/stargazers)
|
||||||
|
[](https://github.com/krau/saveany-bot/releases)
|
||||||
|
[](https://github.com/krau/saveany-bot/issues)
|
||||||
|
[](https://github.com/krau/saveany-bot/pulls)
|
||||||
|
[](./LICENSE)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## 部署
|
## 🎯 Features
|
||||||
|
|
||||||
请参考 [部署文档](https://sabot.unv.app/deployment/installation/)
|
- 支持文档/视频/图片/贴纸…甚至还有 [Telegraph](https://telegra.ph/)
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- 支持文档/视频/图片/贴纸… 甚至还有 Telegraph
|
|
||||||
- 破解禁止保存的文件
|
- 破解禁止保存的文件
|
||||||
- 批量下载
|
- 批量下载
|
||||||
- 流式传输
|
- 流式传输
|
||||||
- 多用户
|
- 多用户使用
|
||||||
- 基于存储规则的自动整理
|
- 基于存储规则的自动整理
|
||||||
- 支持多种存储端:
|
- 监听并自动转存指定聊天的消息, 支持过滤
|
||||||
|
- 使用 js 编写解析器插件以转存任意网站的文件
|
||||||
|
- 存储端支持:
|
||||||
- Alist
|
- Alist
|
||||||
- Minio (S3 兼容)
|
- S3 (MinioSDK)
|
||||||
- WebDAV
|
- WebDAV
|
||||||
- Telegram (重传回指定聊天)
|
|
||||||
- 本地磁盘
|
- 本地磁盘
|
||||||
|
- Telegram (重传回指定聊天)
|
||||||
|
|
||||||
|
## 📦 Quick Start
|
||||||
|
|
||||||
|
创建文件 `config.toml` 并填入以下内容:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[telegram]
|
||||||
|
token = "" # 你的 Bot Token, 在 @BotFather 获取
|
||||||
|
[telegram.proxy]
|
||||||
|
# 启用代理连接 telegram, 当前只支持 socks5
|
||||||
|
enable = false
|
||||||
|
url = "socks5://127.0.0.1:7890"
|
||||||
|
|
||||||
|
[[storages]]
|
||||||
|
name = "本地磁盘"
|
||||||
|
type = "local"
|
||||||
|
enable = true
|
||||||
|
base_path = "./downloads"
|
||||||
|
|
||||||
|
[[users]]
|
||||||
|
id = 114514 # 你的 Telegram 账号 id
|
||||||
|
storages = []
|
||||||
|
blacklist = true
|
||||||
|
```
|
||||||
|
|
||||||
|
使用 Docker 运行 Save Any Bot:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d --name saveany-bot \
|
||||||
|
-v ./config.toml:/app/config.toml \
|
||||||
|
-v ./downloads:/app/downloads \
|
||||||
|
ghcr.io/krau/saveany-bot:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
请 [**查看文档**](https://sabot.unv.app/) 以获取更多配置选项和使用方法.
|
||||||
|
|
||||||
## Sponsors
|
## Sponsors
|
||||||
|
|
||||||
@@ -88,3 +130,9 @@
|
|||||||
- [gotgproto](https://github.com/celestix/gotgproto)
|
- [gotgproto](https://github.com/celestix/gotgproto)
|
||||||
- [tdl](https://github.com/iyear/tdl)
|
- [tdl](https://github.com/iyear/tdl)
|
||||||
- All the dependencies
|
- All the dependencies
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
- [](https://t.me/ProjectSaveAny)
|
||||||
|
- [](https://github.com/krau/saveany-bot/discussions)
|
||||||
|
- [](https://t.me/acherkrau)
|
||||||
@@ -3,6 +3,7 @@ package msgelem
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/strutil"
|
||||||
"github.com/gotd/td/telegram/message/entity"
|
"github.com/gotd/td/telegram/message/entity"
|
||||||
"github.com/gotd/td/telegram/message/styling"
|
"github.com/gotd/td/telegram/message/styling"
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
@@ -18,7 +19,7 @@ func BuildParsedTextEntity(item parser.Item) (string, []tg.MessageEntityClass, e
|
|||||||
styling.Plain("\n作者: "),
|
styling.Plain("\n作者: "),
|
||||||
styling.Code(item.Author),
|
styling.Code(item.Author),
|
||||||
styling.Plain("\n描述: "),
|
styling.Plain("\n描述: "),
|
||||||
styling.Code(item.Description),
|
styling.Code(strutil.Ellipsis(item.Description, 233)),
|
||||||
styling.Plain("\n文件数量: "),
|
styling.Plain("\n文件数量: "),
|
||||||
styling.Code(fmt.Sprintf("%d", len(item.Resources))),
|
styling.Code(fmt.Sprintf("%d", len(item.Resources))),
|
||||||
styling.Plain("\n预计总大小: "),
|
styling.Plain("\n预计总大小: "),
|
||||||
|
|||||||
@@ -11,20 +11,22 @@ title: 介绍
|
|||||||
|
|
||||||
把 Telegram 上的文件转存到多种存储端.
|
把 Telegram 上的文件转存到多种存储端.
|
||||||
|
|
||||||
## 特性
|
## 🎯 特性
|
||||||
|
|
||||||
- 支持文档/视频/图片/贴纸... 甚至还有 Telegraph
|
- 支持文档/视频/图片/贴纸…甚至还有 [Telegraph](https://telegra.ph/)
|
||||||
- 破解禁止保存的文件
|
- 破解禁止保存的文件
|
||||||
- 批量下载
|
- 批量下载
|
||||||
- 流式传输
|
- 流式传输
|
||||||
- 多用户
|
- 多用户使用
|
||||||
- 基于存储规则的自动整理
|
- 基于存储规则的自动整理
|
||||||
- 支持多种存储端:
|
- 监听并自动转存指定聊天的消息, 支持过滤
|
||||||
- Alist
|
- 使用 js 编写解析器插件以转存任意网站的文件
|
||||||
- Minio (S3 兼容)
|
- 存储端支持:
|
||||||
- WebDAV
|
- Alist
|
||||||
- Telegram (重传回指定聊天)
|
- S3 (MinioSDK)
|
||||||
- 本地磁盘
|
- WebDAV
|
||||||
|
- 本地磁盘
|
||||||
|
- Telegram (重传回指定聊天)
|
||||||
|
|
||||||
## [贡献者](https://github.com/krau/SaveAny-Bot/graphs/contributors)
|
## [贡献者](https://github.com/krau/SaveAny-Bot/graphs/contributors)
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,30 @@ weight: 20
|
|||||||
|
|
||||||
# 参与开发
|
# 参与开发
|
||||||
|
|
||||||
|
在开始之前, 请 Fork 本项目, 并克隆到本地, 并确保 Go 版本 >= 1.23.
|
||||||
|
|
||||||
|
以下是一些贡献代码的指南或建议, 你不必完全遵守, 但将有助于快速 review 并合并你的提交:
|
||||||
|
|
||||||
|
- **新功能请先提交 Issue**, 以便讨论设计和实现细节, 并避免因与项目设计不符而被拒绝.
|
||||||
|
- **使用现代开发工具**, 确保提交前格式化代码, 并保持风格一致.
|
||||||
|
- **使用[语义化提交](https://www.conventionalcommits.org/zh-hans/v1.0.0/)**, 避免提交消息模糊或过于简单.
|
||||||
|
|
||||||
## 贡献新存储端
|
## 贡献新存储端
|
||||||
|
|
||||||
1. Fork 本项目, 克隆到本地
|
1. 在 `pkg/enums/storage/storages.go` 中添加新的存储端类型, 并运行代码生成
|
||||||
2. 在 `pkg/enums/storage/storages.go` 中添加新的存储端类型, 并运行代码生成
|
2. 在 `config/storage` 目录下定义存储端配置, 并添加到 `config/storage/factory.go` 中
|
||||||
3. 在 `config/storage` 目录下定义存储端配置, 并添加到 `config/storage/factory.go` 中
|
3. 在 `storage` 目录下新建一个包, 编写存储端实现, 然后在 `storage/storage.go` 中导入并添加它
|
||||||
4. 在 `storage` 目录下新建一个包, 编写存储端实现, 然后在 `storage/storage.go` 中导入并添加它
|
4. 更新文档, 添加配置说明
|
||||||
5. 更新文档, 添加配置说明
|
|
||||||
|
## 贡献新解析器
|
||||||
|
|
||||||
|
你可以选择使用 Go 编写原生的解析器实现(推荐), 或是使用 JavaScript 以插件的方式实现.
|
||||||
|
|
||||||
|
如果使用 Go 编写, 请:
|
||||||
|
|
||||||
|
1. 在 `parsers` 目录下新建一个包, 编写解析器实现
|
||||||
|
2. 在 `parsers/parser.go` 的 `init` 中注册解析器
|
||||||
|
|
||||||
|
如果使用 JavaScript 编写, 请参考 `plugins/example_parser.js` 的实现, 并在该文件夹下新建一个 js 文件, 实现你的解析逻辑.
|
||||||
|
|
||||||
|
需要注意, `plugins` 目录下解析器默认不会被编译到二进制文件中, 用户需要手动下载它们并放到本地指定目录下以启用它们.
|
||||||
@@ -164,6 +164,18 @@ task_fail = "curl -X POST https://example.com/api/notify -d '任务失败'"
|
|||||||
task_cancel = "bash /path/to/cancel_script.sh"
|
task_cancel = "bash /path/to/cancel_script.sh"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 解析器
|
||||||
|
|
||||||
|
解析器为 Bot 提供了处理非 Telegram 文件的能力, 例如从其他网站下载文件. 使用 `[parsers]` 配置.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[parsers]
|
||||||
|
plugin_enable = true # 是否启用解析器插件
|
||||||
|
plugin_dirs = ["./plugins"] # 插件目录, 可以是多个目录
|
||||||
|
```
|
||||||
|
|
||||||
|
上述两个配置项只用于控制以 JavaScript 编写的解析器插件, Bot 还有内置的使用 Go 实现的解析器, 目前默认开启.
|
||||||
|
|
||||||
### 杂项
|
### 杂项
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
|
|||||||
@@ -9,12 +9,11 @@ weight: 10
|
|||||||
|
|
||||||
## 转存文件
|
## 转存文件
|
||||||
|
|
||||||
Bot 接受两种消息: 文件和链接.
|
要使用 Bot 的转存 Telegram 文件功能, 需要向 Bot 发送或转发以下类型的消息.
|
||||||
|
|
||||||
对于链接, 目前支持以下类型的链接:
|
1. 文件或媒体消息, 如图片, 视频, 文档等
|
||||||
|
2. Telegram 消息链接, 例如: `https://t.me/acherkrau/1097`. **即使频道禁止了转发和保存, Bot 依然可以下载其文件.**
|
||||||
1. Telegram 消息链接, 例如: `https://t.me/acherkrau/1097`. **即使频道禁止了转发和保存, Bot 依然可以下载其文件.**
|
3. Telegra.ph 的文章链接, Bot 将下载其中的所有图片
|
||||||
2. Telegra.ph 的文章链接, Bot 将下载其中的所有图片
|
|
||||||
|
|
||||||
## 静默模式 (silent)
|
## 静默模式 (silent)
|
||||||
|
|
||||||
@@ -112,3 +111,13 @@ IS-ALBUM true MyWebdav NEW-FOR-ALBUM
|
|||||||
```
|
```
|
||||||
|
|
||||||
这将会监听 ID 为 12345678 的聊天, 并且只保存消息文本中包含 "hello" 的消息.
|
这将会监听 ID 为 12345678 的聊天, 并且只保存消息文本中包含 "hello" 的消息.
|
||||||
|
|
||||||
|
## 转存 Telegram 之外的文件
|
||||||
|
|
||||||
|
除了 Telegram 上的文件, Bot 还可通过 JavaScript 插件或内置解析器来支持转存其他网站的文件.
|
||||||
|
|
||||||
|
> 查看[贡献解析器](../contribute)文档了解详情
|
||||||
|
|
||||||
|
只需向 Bot 发送符合解析器要求的链接即可使用, 当前内置的解析器:
|
||||||
|
|
||||||
|
- Twitter
|
||||||
@@ -20,10 +20,10 @@ func GetParsers() []parser.Parser {
|
|||||||
return parsers
|
return parsers
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddParser(p parser.Parser) {
|
func AddParser(p ...parser.Parser) {
|
||||||
parsersMu.Lock()
|
parsersMu.Lock()
|
||||||
defer parsersMu.Unlock()
|
defer parsersMu.Unlock()
|
||||||
parsers = append(parsers, p)
|
parsers = append(parsers, p...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|||||||
@@ -60,9 +60,16 @@ func (p *TwitterParser) Parse(u string) (*parser.Item, error) {
|
|||||||
}
|
}
|
||||||
resources := make([]parser.Resource, 0, len(fxResp.Tweet.Media.All))
|
resources := make([]parser.Resource, 0, len(fxResp.Tweet.Media.All))
|
||||||
for _, media := range fxResp.Tweet.Media.All {
|
for _, media := range fxResp.Tweet.Media.All {
|
||||||
|
var size int64
|
||||||
|
resp, err := p.client.Get(media.URL)
|
||||||
|
if err == nil {
|
||||||
|
size = resp.ContentLength
|
||||||
|
resp.Body.Close()
|
||||||
|
}
|
||||||
resources = append(resources, parser.Resource{
|
resources = append(resources, parser.Resource{
|
||||||
URL: media.URL,
|
URL: media.URL,
|
||||||
Filename: path.Base(strings.Split(media.URL, "?")[0]),
|
Filename: path.Base(strings.Split(media.URL, "?")[0]),
|
||||||
|
Size: size,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
item := &parser.Item{
|
item := &parser.Item{
|
||||||
|
|||||||
Reference in New Issue
Block a user