mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
fix(qq): preserve filenames in file uploads (#1913)
This commit is contained in:
@@ -357,6 +357,7 @@ type qqMediaUpload struct {
|
||||
FileType uint64 `json:"file_type"`
|
||||
URL string `json:"url,omitempty"`
|
||||
FileData string `json:"file_data,omitempty"`
|
||||
FileName string `json:"file_name,omitempty"`
|
||||
SrvSendMsg bool `json:"srv_send_msg,omitempty"`
|
||||
}
|
||||
|
||||
@@ -393,6 +394,7 @@ func (c *QQChannel) buildMediaUpload(part bus.MediaPart) (*qqMediaUpload, error)
|
||||
if isHTTPURL(mediaRef) {
|
||||
payload.FileType = qqFileType(c.outboundMediaType(part, ""))
|
||||
payload.URL = mediaRef
|
||||
payload.FileName = qqUploadFilename(part, mediaRef, payload.FileType)
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
@@ -415,9 +417,11 @@ func (c *QQChannel) buildMediaUpload(part bus.MediaPart) (*qqMediaUpload, error)
|
||||
if isHTTPURL(resolved) {
|
||||
payload.FileType = qqFileType(c.outboundMediaType(part, ""))
|
||||
payload.URL = resolved
|
||||
payload.FileName = qqUploadFilename(part, resolved, payload.FileType)
|
||||
return payload, nil
|
||||
}
|
||||
payload.FileType = qqFileType(c.outboundMediaType(part, resolved))
|
||||
payload.FileName = qqUploadFilename(part, resolved, payload.FileType)
|
||||
|
||||
if limitBytes := c.maxBase64FileSizeBytes(); limitBytes > 0 {
|
||||
info, statErr := os.Stat(resolved)
|
||||
@@ -444,6 +448,28 @@ func (c *QQChannel) buildMediaUpload(part bus.MediaPart) (*qqMediaUpload, error)
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
func qqUploadFilename(part bus.MediaPart, resolved string, fileType uint64) string {
|
||||
if fileType != qqFileType("file") {
|
||||
return ""
|
||||
}
|
||||
if part.Filename != "" {
|
||||
return part.Filename
|
||||
}
|
||||
if isHTTPURL(resolved) {
|
||||
if parsed, err := url.Parse(resolved); err == nil {
|
||||
if base := path.Base(parsed.Path); base != "" && base != "." && base != "/" {
|
||||
return base
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
if base := filepath.Base(resolved); base != "" && base != "." {
|
||||
return base
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *QQChannel) outboundMediaType(part bus.MediaPart, localPath string) string {
|
||||
if part.Type != "audio" {
|
||||
return part.Type
|
||||
|
||||
@@ -444,6 +444,9 @@ func TestSendMedia_UsesRemoteURLUploadForC2C(t *testing.T) {
|
||||
if upload.body.FileType != 4 {
|
||||
t.Fatalf("upload file_type = %d, want 4", upload.body.FileType)
|
||||
}
|
||||
if upload.body.FileName != "report.pdf" {
|
||||
t.Fatalf("upload file_name = %q, want report.pdf", upload.body.FileName)
|
||||
}
|
||||
|
||||
if len(api.c2cMessages) != 1 {
|
||||
t.Fatalf("c2cMessages = %d, want 1", len(api.c2cMessages))
|
||||
@@ -460,6 +463,59 @@ func TestSendMedia_UsesRemoteURLUploadForC2C(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendMedia_LocalFileUploadIncludesStoredFilename(t *testing.T) {
|
||||
messageBus := bus.NewMessageBus()
|
||||
store := media.NewFileMediaStore()
|
||||
|
||||
localPath := writeTempFile(t, t.TempDir(), "report.pdf", []byte("fake-pdf"))
|
||||
ref, err := store.Store(localPath, media.MediaMeta{
|
||||
Filename: "report.pdf",
|
||||
ContentType: "application/pdf",
|
||||
}, "qq:test")
|
||||
if err != nil {
|
||||
t.Fatalf("Store() error = %v", err)
|
||||
}
|
||||
|
||||
api := &fakeQQAPI{
|
||||
transportResp: mustJSON(t, dto.Message{FileInfo: []byte("local-file-info")}),
|
||||
}
|
||||
ch := &QQChannel{
|
||||
BaseChannel: channels.NewBaseChannel("qq", nil, messageBus, nil),
|
||||
api: api,
|
||||
dedup: make(map[string]time.Time),
|
||||
done: make(chan struct{}),
|
||||
ctx: context.Background(),
|
||||
}
|
||||
ch.SetRunning(true)
|
||||
ch.SetMediaStore(store)
|
||||
ch.chatType.Store("user-1", "direct")
|
||||
|
||||
err = ch.SendMedia(context.Background(), bus.OutboundMediaMessage{
|
||||
ChatID: "user-1",
|
||||
Parts: []bus.MediaPart{{
|
||||
Type: "file",
|
||||
Ref: ref,
|
||||
}},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("SendMedia() error = %v", err)
|
||||
}
|
||||
|
||||
if len(api.transportCalls) != 1 {
|
||||
t.Fatalf("transportCalls = %d, want 1", len(api.transportCalls))
|
||||
}
|
||||
upload := api.transportCalls[0]
|
||||
if upload.body.FileType != 4 {
|
||||
t.Fatalf("upload file_type = %d, want 4", upload.body.FileType)
|
||||
}
|
||||
if upload.body.FileName != "report.pdf" {
|
||||
t.Fatalf("upload file_name = %q, want report.pdf", upload.body.FileName)
|
||||
}
|
||||
if upload.body.FileData == "" {
|
||||
t.Fatal("upload file_data = empty, want base64 payload")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendMedia_ReturnsSendFailedWithoutMediaStore(t *testing.T) {
|
||||
messageBus := bus.NewMessageBus()
|
||||
ch := &QQChannel{
|
||||
|
||||
Reference in New Issue
Block a user