Skip to content

Commit b09f7fb

Browse files
authored
Merge pull request #12 from Cosr-Backup/dev
update @coderabbitai
2 parents 2fd7d26 + de79b7d commit b09f7fb

File tree

19 files changed

+346
-115
lines changed

19 files changed

+346
-115
lines changed

.github/ISSUE_TEMPLATE/bug.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@ body:
2323
description: "Please provide your config file"
2424
placeholder: "请自行隐去密钥信息"
2525
render: toml
26+
validations:
27+
required: true
2628
- type: textarea
2729
attributes:
2830
label: "🔍 日志"
2931
description: "Please provide logs"
3032
placeholder: "可删除隐私信息"
3133
render: shell
34+
validations:
35+
required: true
3236
- type: markdown
3337
attributes:
3438
value: |
35-
## Thank you for contributing to the project :slightly_smiling_face:
39+
## Thank you for contributing to the project :slightly_smiling_face:

bot/handle_link.go

Lines changed: 129 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package bot
22

33
import (
4+
"errors"
45
"fmt"
6+
"net/url"
57
"regexp"
68
"strconv"
79
"strings"
@@ -16,39 +18,99 @@ import (
1618
)
1719

1820
var (
19-
linkRegexString = `t.me/.*/\d+`
21+
linkRegexString = `https?://t\.me/(?:c/\d+|[a-zA-Z0-9_]+)/\d+(?:\?[^\s]*)?`
2022
linkRegex = regexp.MustCompile(linkRegexString)
2123
)
2224

23-
func parseLink(ctx *ext.Context, link string) (chatID int64, messageID int, err error) {
24-
strSlice := strings.Split(link, "/")
25+
type parseResult struct {
26+
ChatID int64
27+
MessageID int
28+
Files []*types.File
29+
UserClient bool
30+
}
31+
32+
func parseLink(ctx *ext.Context, link string) (*parseResult, error) {
33+
u, err := url.Parse(link)
34+
if err != nil {
35+
return nil, fmt.Errorf("无法解析链接: %s", err)
36+
}
37+
strSlice := strings.Split(u.Path, "/")
2538
if len(strSlice) < 3 {
26-
return 0, 0, fmt.Errorf("链接格式错误: %s", link)
39+
return nil, fmt.Errorf("链接格式错误: %s", link)
2740
}
28-
messageID, err = strconv.Atoi(strSlice[len(strSlice)-1])
41+
messageID, err := strconv.Atoi(strSlice[len(strSlice)-1])
2942
if err != nil {
30-
return 0, 0, fmt.Errorf("无法解析消息 ID: %s", err)
43+
return nil, fmt.Errorf("无法解析消息 ID: %s", err)
3144
}
45+
var chatID int64
3246
if len(strSlice) == 3 {
3347
chatUsername := strSlice[1]
34-
linkChat, err := ctx.ResolveUsername(chatUsername)
35-
if err != nil {
36-
return 0, 0, fmt.Errorf("解析用户名失败: %s", err)
37-
}
38-
if linkChat == nil {
39-
return 0, 0, fmt.Errorf("找不到该聊天: %s", chatUsername)
48+
peer := ctx.PeerStorage.GetPeerByUsername(chatUsername)
49+
if peer != nil {
50+
chatID = peer.ID
51+
} else {
52+
linkChat, err := ctx.ResolveUsername(chatUsername)
53+
if err != nil {
54+
return nil, fmt.Errorf("解析用户名失败: %s", err)
55+
}
56+
if linkChat == nil {
57+
return nil, fmt.Errorf("找不到该聊天: %s", chatUsername)
58+
}
59+
chatID = linkChat.GetID()
4060
}
41-
chatID = linkChat.GetID()
4261
} else if len(strSlice) == 4 {
4362
chatIDInt, err := strconv.Atoi(strSlice[2])
4463
if err != nil {
45-
return 0, 0, fmt.Errorf("无法解析 Chat ID: %s", err)
64+
return nil, fmt.Errorf("无法解析 Chat ID: %s", err)
4665
}
4766
chatID = int64(chatIDInt)
4867
} else {
49-
return 0, 0, fmt.Errorf("无效的链接: %s", link)
68+
return nil, errors.New("链接格式不正确,无法解析 Chat ID")
69+
}
70+
if chatID == 0 || messageID == 0 {
71+
return nil, fmt.Errorf("链接中缺少 Chat ID 或 Message ID: %s", link)
72+
}
73+
msg, _, err := tryFetchMessage(ctx, chatID, messageID)
74+
if err != nil {
75+
return nil, fmt.Errorf("获取消息失败: %s", err)
76+
}
77+
mediaGroup, isGroup := msg.GetGroupedID()
78+
if u.Query().Has("single") || !isGroup || (mediaGroup == 0) || userclient.UC == nil {
79+
file, useUserClient, err := tryFetchFileFromMessage(ctx, chatID, messageID, "")
80+
if err != nil {
81+
return nil, fmt.Errorf("获取文件失败: %s", err)
82+
}
83+
if file.FileName == "" {
84+
file.FileName = GenFileNameFromMessage(*msg, file)
85+
}
86+
return &parseResult{
87+
ChatID: chatID,
88+
MessageID: messageID,
89+
Files: []*types.File{file},
90+
UserClient: useUserClient,
91+
}, nil
92+
}
93+
groupMessages, isUserClient, err := tryGetMediaGroup(chatID, messageID, mediaGroup)
94+
if err != nil {
95+
return nil, fmt.Errorf("获取媒体组消息失败: %s", err)
96+
}
97+
var files []*types.File
98+
for _, groupMsg := range groupMessages {
99+
file, err := FileFromMedia(groupMsg.Media, "")
100+
if err != nil {
101+
return nil, fmt.Errorf("获取媒体文件失败: %s", err)
102+
}
103+
if file.FileName == "" {
104+
file.FileName = GenFileNameFromMessage(*groupMsg, file)
105+
}
106+
files = append(files, file)
50107
}
51-
return chatID, messageID, nil
108+
return &parseResult{
109+
ChatID: chatID,
110+
MessageID: messageID,
111+
Files: files,
112+
UserClient: isUserClient,
113+
}, nil
52114
}
53115

54116
// use passed ctx client to fetch file from message,
@@ -62,18 +124,50 @@ func tryFetchFileFromMessage(ctx *ext.Context, chatID int64, messageID int, file
62124
if (strings.Contains(err.Error(), "peer not found") || strings.Contains(err.Error(), "unexpected message type")) && userclient.UC != nil {
63125
common.Log.Warnf("无法获取文件 %d:%d, 尝试使用 userbot: %s", chatID, messageID, err)
64126
uctx := userclient.GetCtx()
65-
// TODO: 群组支持
66-
file, err = FileFromMessage(uctx, chatID, messageID, fileName)
67-
if err == nil {
68-
return file, true, nil
127+
peer := uctx.PeerStorage.GetInputPeerById(chatID)
128+
if peer == nil {
129+
return nil, true, fmt.Errorf("failed to get peer for chat %d: %w", chatID, err)
130+
}
131+
msg, err := GetSingleHistoryMessage(uctx, uctx.Raw, peer, messageID)
132+
if err != nil {
133+
return nil, true, err
69134
}
70-
return nil, true, err
135+
file, err = FileFromMedia(msg.Media, fileName)
136+
if err != nil {
137+
return nil, true, fmt.Errorf("failed to get file from userbot message %d:%d: %w", chatID, messageID, err)
138+
}
139+
return file, true, nil
71140
}
72141
return nil, false, err
73142
}
74143

75-
func tryFetchMessage(ctx *ext.Context, chatID int64, messageID int) (*tg.Message, error) {
76-
return GetTGMessage(ctx, chatID, messageID)
144+
func tryGetMediaGroup(chatID int64, messageID int, mediaGroupID int64) ([]*tg.Message, bool, error) {
145+
if userclient.UC != nil {
146+
uctx := userclient.GetCtx()
147+
messages, err := GetMediaGroup(uctx, chatID, messageID, mediaGroupID)
148+
if err != nil {
149+
return nil, true, fmt.Errorf("failed to get media group from userbot: %w", err)
150+
}
151+
return messages, true, nil
152+
}
153+
return nil, false, errors.New("userclient is not available, cannot fetch media group")
154+
}
155+
156+
func tryFetchMessage(ctx *ext.Context, chatID int64, messageID int) (*tg.Message, bool, error) {
157+
msg, err := GetTGMessage(ctx, chatID, messageID)
158+
if err == nil {
159+
return msg, false, nil
160+
}
161+
if userclient.UC != nil && (strings.Contains(err.Error(), "peer not found") || strings.Contains(err.Error(), "unexpected message type")) {
162+
common.Log.Warnf("无法获取消息 %d:%d, 尝试使用 userbot: %s", chatID, messageID, err)
163+
uctx := userclient.GetCtx()
164+
msg, err := GetTGMessage(uctx, chatID, messageID)
165+
if err == nil {
166+
return msg, true, nil
167+
}
168+
return nil, true, fmt.Errorf("获取消息失败: %w", err)
169+
}
170+
return nil, false, fmt.Errorf("获取消息失败: %s", err)
77171
}
78172

79173
func handleLinkMessage(ctx *ext.Context, update *ext.Update) error {
@@ -82,10 +176,10 @@ func handleLinkMessage(ctx *ext.Context, update *ext.Update) error {
82176
if link == "" {
83177
return dispatcher.ContinueGroups
84178
}
85-
linkChatID, messageID, err := parseLink(ctx, link)
179+
result, err := parseLink(ctx, link)
86180
if err != nil {
87181
common.Log.Errorf("解析链接失败: %s", err)
88-
ctx.Reply(update, ext.ReplyTextString("解析链接失败: "+err.Error()), nil)
182+
ctx.Reply(update, ext.ReplyTextString("解析链接失败"), nil)
89183
return dispatcher.EndGroups
90184
}
91185

@@ -102,29 +196,15 @@ func handleLinkMessage(ctx *ext.Context, update *ext.Update) error {
102196
return dispatcher.EndGroups
103197
}
104198

105-
file, useUserClient, err := tryFetchFileFromMessage(ctx, linkChatID, messageID, "")
106-
if err != nil {
107-
common.Log.Errorf("获取文件失败: %s", err)
108-
ctx.Reply(update, ext.ReplyTextString("获取文件失败: "+err.Error()), nil)
109-
return dispatcher.EndGroups
110-
}
111-
if file.FileName == "" {
112-
msg, err := tryFetchMessage(ctx, linkChatID, messageID)
113-
if err != nil {
114-
file.FileName = fmt.Sprintf("%d_%d", linkChatID, messageID)
115-
} else {
116-
file.FileName = GenFileNameFromMessage(*msg, file)
117-
}
118-
}
119-
199+
// TODO: handle group files
120200
receivedFile := &dao.ReceivedFile{
121201
Processing: false,
122-
FileName: file.FileName,
123-
ChatID: linkChatID,
124-
MessageID: messageID,
202+
FileName: result.Files[0].FileName,
203+
ChatID: result.ChatID,
204+
MessageID: result.MessageID,
125205
ReplyMessageID: replied.ID,
126206
ReplyChatID: update.GetUserChat().GetID(),
127-
UseUserClient: useUserClient,
207+
UseUserClient: result.UserClient,
128208
}
129209
record, err := dao.SaveReceivedFile(receivedFile)
130210
if err != nil {
@@ -135,19 +215,20 @@ func handleLinkMessage(ctx *ext.Context, update *ext.Update) error {
135215
})
136216
return dispatcher.EndGroups
137217
}
218+
file := result.Files[0]
138219
if !user.Silent || user.DefaultStorage == "" {
139-
return ProvideSelectMessage(ctx, update, file.FileName, linkChatID, messageID, replied.ID)
220+
return ProvideSelectMessage(ctx, update, file.FileName, result.ChatID, result.MessageID, replied.ID)
140221
}
141222
return HandleSilentAddTask(ctx, update, user, &types.Task{
142223
Ctx: ctx,
143224
Status: types.Pending,
144225
FileDBID: record.ID,
145-
UseUserClient: useUserClient,
226+
UseUserClient: result.UserClient,
146227
File: file,
147228
StorageName: user.DefaultStorage,
148229
UserID: user.ChatID,
149-
FileChatID: linkChatID,
150-
FileMessageID: messageID,
230+
FileChatID: result.ChatID,
231+
FileMessageID: result.MessageID,
151232
ReplyMessageID: replied.ID,
152233
ReplyChatID: update.GetUserChat().GetID(),
153234
})

bot/middlewares.go

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"github.com/gotd/contrib/middleware/floodwait"
1010
"github.com/gotd/contrib/middleware/ratelimit"
1111
"github.com/gotd/td/telegram"
12-
"github.com/krau/SaveAny-Bot/common"
1312
"github.com/krau/SaveAny-Bot/config"
1413
"golang.org/x/time/rate"
1514
)
@@ -31,44 +30,8 @@ const noPermissionText string = `
3130
func checkPermission(ctx *ext.Context, update *ext.Update) error {
3231
userID := update.GetUserChat().GetID()
3332
if !slice.Contain(config.Cfg.GetUsersID(), userID) {
34-
if config.Cfg.AsPublicCopyMediaBot {
35-
tryCopyMedia(ctx, update)
36-
return dispatcher.EndGroups
37-
}
3833
ctx.Reply(update, ext.ReplyTextString(noPermissionText), nil)
3934
return dispatcher.EndGroups
4035
}
4136
return dispatcher.ContinueGroups
42-
}
43-
44-
func tryCopyMedia(ctx *ext.Context, update *ext.Update) {
45-
if !config.Cfg.AsPublicCopyMediaBot {
46-
return
47-
}
48-
if update.EffectiveMessage == nil || update.EffectiveMessage.Message == nil {
49-
return
50-
}
51-
msg := update.EffectiveMessage.Message
52-
if link := linkRegex.FindString(update.EffectiveMessage.Text); link != "" {
53-
linkChatID, messageID, err := parseLink(ctx, link)
54-
if err != nil {
55-
return
56-
}
57-
fileMessage, err := GetTGMessage(ctx, linkChatID, messageID)
58-
if err != nil {
59-
return
60-
}
61-
if fileMessage == nil || fileMessage.Media == nil {
62-
return
63-
}
64-
msg = fileMessage
65-
}
66-
if _, ok := msg.GetMedia(); !ok || msg.Media == nil {
67-
ctx.Reply(update, ext.ReplyTextString("消息中没有文件或媒体"), nil)
68-
return
69-
}
70-
common.Log.Tracef("Got copy media request from %d", update.EffectiveChat().GetID())
71-
if _, err := copyMediaToChat(ctx, msg, update.EffectiveChat().GetID()); err != nil {
72-
common.Log.Errorf("Failed to copy media: %v", err)
73-
}
74-
}
37+
}

0 commit comments

Comments
 (0)