Skip to content

Commit b47cbba

Browse files
committed
add stream_upload_source
1 parent 05ac714 commit b47cbba

File tree

4 files changed

+73
-23
lines changed

4 files changed

+73
-23
lines changed

officialaccount/material/material.go

+13-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"io"
88
"os"
9+
"path"
910

1011
"github.com/silenceper/wechat/v2/officialaccount/context"
1112
"github.com/silenceper/wechat/v2/util"
@@ -163,7 +164,7 @@ type resAddMaterial struct {
163164
}
164165

165166
// AddMaterialFromReader 上传永久性素材(处理视频需要单独上传),从 io.Reader 中读取
166-
func (material *Material) AddMaterialFromReader(mediaType MediaType, filename string, reader io.Reader) (mediaID string, url string, err error) {
167+
func (material *Material) AddMaterialFromReader(mediaType MediaType, directory string, reader io.Reader) (mediaID string, url string, err error) {
167168
if mediaType == MediaTypeVideo {
168169
err = errors.New("永久视频素材上传使用 AddVideo 方法")
169170
return
@@ -175,8 +176,10 @@ func (material *Material) AddMaterialFromReader(mediaType MediaType, filename st
175176
}
176177

177178
uri := fmt.Sprintf("%s?access_token=%s&type=%s", addMaterialURL, accessToken, mediaType)
179+
// 获取文件名
180+
filename := path.Base(directory)
178181
var response []byte
179-
response, err = util.PostFileFromReader("media", filename, uri, reader)
182+
response, err = util.PostFileFromReader("media", directory, filename, uri, reader)
180183
if err != nil {
181184
return
182185
}
@@ -211,7 +214,7 @@ type reqVideo struct {
211214
}
212215

213216
// AddVideoFromReader 永久视频素材文件上传,从 io.Reader 中读取
214-
func (material *Material) AddVideoFromReader(filename, title, introduction string, reader io.Reader) (mediaID string, url string, err error) {
217+
func (material *Material) AddVideoFromReader(directory, title, introduction string, reader io.Reader) (mediaID string, url string, err error) {
215218
var accessToken string
216219
accessToken, err = material.GetAccessToken()
217220
if err != nil {
@@ -229,17 +232,19 @@ func (material *Material) AddVideoFromReader(filename, title, introduction strin
229232
if err != nil {
230233
return
231234
}
232-
235+
fileName := path.Base(directory)
233236
fields := []util.MultipartFormField{
234237
{
235238
IsFile: true,
236239
Fieldname: "media",
237-
Filename: filename,
240+
Directory: directory,
241+
Filename: fileName,
238242
FileReader: reader,
239243
},
240244
{
241245
IsFile: false,
242246
Fieldname: "description",
247+
Filename: fileName,
243248
Value: fieldValue,
244249
},
245250
}
@@ -265,14 +270,14 @@ func (material *Material) AddVideoFromReader(filename, title, introduction strin
265270
}
266271

267272
// AddVideo 永久视频素材文件上传
268-
func (material *Material) AddVideo(filename, title, introduction string) (mediaID string, url string, err error) {
269-
f, err := os.Open(filename)
273+
func (material *Material) AddVideo(directory, title, introduction string) (mediaID string, url string, err error) {
274+
f, err := os.Open(directory)
270275
if err != nil {
271276
return "", "", err
272277
}
273278
defer func() { _ = f.Close() }()
274279

275-
return material.AddVideoFromReader(filename, title, introduction, f)
280+
return material.AddVideoFromReader(directory, title, introduction, f)
276281
}
277282

278283
type reqDeleteMaterial struct {

officialaccount/material/media.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package material
33
import (
44
"encoding/json"
55
"fmt"
6-
76
"github.com/silenceper/wechat/v2/util"
87
)
98

@@ -38,16 +37,20 @@ type Media struct {
3837
}
3938

4039
// MediaUpload 临时素材上传
41-
func (material *Material) MediaUpload(mediaType MediaType, filename string) (media Media, err error) {
40+
func (material *Material) MediaUpload(mediaType MediaType, url string) (media Media, err error) {
4241
var accessToken string
4342
accessToken, err = material.GetAccessToken()
4443
if err != nil {
4544
return
4645
}
4746

4847
uri := fmt.Sprintf("%s?access_token=%s&type=%s", mediaUploadURL, accessToken, mediaType)
48+
filename, byteData, err := util.GetFileSourceByURL(url)
49+
if err != nil {
50+
return
51+
}
4952
var response []byte
50-
response, err = util.PostFile("media", filename, uri)
53+
response, err = util.PostFileByStream("media", filename, uri, byteData)
5154
if err != nil {
5255
return
5356
}

util/http.go

+41-7
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import (
88
"encoding/pem"
99
"encoding/xml"
1010
"fmt"
11+
"golang.org/x/crypto/pkcs12"
1112
"io"
1213
"log"
1314
"mime/multipart"
1415
"net/http"
1516
"os"
16-
17-
"golang.org/x/crypto/pkcs12"
17+
"path"
1818
)
1919

2020
// URIModifier URI修改器
@@ -146,24 +146,57 @@ func PostJSONWithRespContentType(uri string, obj interface{}) ([]byte, string, e
146146
return responseData, contentType, err
147147
}
148148

149+
// PostFileByStream 上传文件
150+
func PostFileByStream(fieldName, fileName, uri string, byteData []byte) ([]byte, error) {
151+
fields := []MultipartFormField{
152+
{
153+
IsFile: false,
154+
Fieldname: fieldName,
155+
Filename: fileName,
156+
Value: byteData,
157+
},
158+
}
159+
return PostMultipartForm(fields, uri)
160+
}
161+
162+
// GetFileSourceByURL 从给定的 URL 获取文件名和文件字节数据
163+
func GetFileSourceByURL(url string) (filename string, byteData []byte, err error) {
164+
// 获取文件名
165+
filename = path.Base(url)
166+
// 获取资源
167+
resp, err := http.Get(url)
168+
if err != nil {
169+
err = fmt.Errorf("get resp error: %v", err)
170+
return
171+
}
172+
byteData, err = io.ReadAll(resp.Body)
173+
defer func() { _ = resp.Body.Close() }()
174+
if err != nil {
175+
err = fmt.Errorf("read resp error: %v", err)
176+
return
177+
}
178+
return
179+
}
180+
149181
// PostFile 上传文件
150-
func PostFile(fieldName, filename, uri string) ([]byte, error) {
182+
func PostFile(fieldName, directory, uri string) ([]byte, error) {
151183
fields := []MultipartFormField{
152184
{
153185
IsFile: true,
154186
Fieldname: fieldName,
155-
Filename: filename,
187+
Directory: directory,
156188
},
157189
}
158190
return PostMultipartForm(fields, uri)
159191
}
160192

161193
// PostFileFromReader 上传文件,从 io.Reader 中读取
162-
func PostFileFromReader(filedName, fileName, uri string, reader io.Reader) ([]byte, error) {
194+
func PostFileFromReader(filedName, directory, fileName, uri string, reader io.Reader) ([]byte, error) {
163195
fields := []MultipartFormField{
164196
{
165197
IsFile: true,
166198
Fieldname: filedName,
199+
Directory: directory,
167200
Filename: fileName,
168201
FileReader: reader,
169202
},
@@ -176,6 +209,7 @@ type MultipartFormField struct {
176209
IsFile bool
177210
Fieldname string
178211
Value []byte
212+
Directory string
179213
Filename string
180214
FileReader io.Reader
181215
}
@@ -197,7 +231,7 @@ func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte
197231
}
198232

199233
if field.FileReader == nil {
200-
fh, e := os.Open(field.Filename)
234+
fh, e := os.Open(field.Directory)
201235
if e != nil {
202236
err = fmt.Errorf("error opening file , err=%v", e)
203237
return
@@ -213,7 +247,7 @@ func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte
213247
}
214248
}
215249
} else {
216-
partWriter, e := bodyWriter.CreateFormField(field.Fieldname)
250+
partWriter, e := bodyWriter.CreateFormFile(field.Fieldname, field.Filename)
217251
if e != nil {
218252
err = e
219253
return

work/material/media.go

+13-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package material
22

33
import (
44
"fmt"
5-
65
"github.com/silenceper/wechat/v2/util"
76
)
87

@@ -59,16 +58,21 @@ func (r *Client) UploadImg(filename string) (*UploadImgResponse, error) {
5958
// UploadTempFile 上传临时素材
6059
// @see https://developer.work.weixin.qq.com/document/path/90253
6160
// @mediaType 媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file)
62-
func (r *Client) UploadTempFile(filename string, mediaType string) (*UploadTempFileResponse, error) {
61+
// 临时素材一般都是存储在oss上的,可以直接传递url
62+
func (r *Client) UploadTempFile(url string, mediaType string) (*UploadTempFileResponse, error) {
6363
var (
6464
accessToken string
6565
err error
6666
)
6767
if accessToken, err = r.GetAccessToken(); err != nil {
6868
return nil, err
6969
}
70+
filename, byteData, err := util.GetFileSourceByURL(url)
71+
if err != nil {
72+
return nil, err
73+
}
7074
var response []byte
71-
if response, err = util.PostFile("media", filename, fmt.Sprintf(uploadTempFile, accessToken, mediaType)); err != nil {
75+
if response, err = util.PostFileByStream("media", filename, fmt.Sprintf(uploadTempFile, accessToken, mediaType), byteData); err != nil {
7276
return nil, err
7377
}
7478
result := &UploadTempFileResponse{}
@@ -80,16 +84,20 @@ func (r *Client) UploadTempFile(filename string, mediaType string) (*UploadTempF
8084
// @see https://developer.work.weixin.qq.com/document/path/95098
8185
// @mediaType 媒体文件类型,分别有图片(image)、视频(video)、普通文件(file)
8286
// @attachment_type 附件类型,不同的附件类型用于不同的场景。1:朋友圈;2:商品图册
83-
func (r *Client) UploadAttachment(filename string, mediaType string, attachmentType int) (*UploadAttachmentResponse, error) {
87+
func (r *Client) UploadAttachment(url string, mediaType string, attachmentType int) (*UploadAttachmentResponse, error) {
8488
var (
8589
accessToken string
8690
err error
8791
)
8892
if accessToken, err = r.GetAccessToken(); err != nil {
8993
return nil, err
9094
}
95+
filename, byteData, err := util.GetFileSourceByURL(url)
96+
if err != nil {
97+
return nil, err
98+
}
9199
var response []byte
92-
if response, err = util.PostFile("media", filename, fmt.Sprintf(uploadAttachment, accessToken, mediaType, attachmentType)); err != nil {
100+
if response, err = util.PostFileByStream("media", filename, fmt.Sprintf(uploadAttachment, accessToken, mediaType, attachmentType), byteData); err != nil {
93101
return nil, err
94102
}
95103
result := &UploadAttachmentResponse{}

0 commit comments

Comments
 (0)