Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Material 增加 AddMaterialFromReader 与 AddVideoFromReader 方法 #780

Merged
merged 2 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 33 additions & 8 deletions officialaccount/material/material.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"os"

"github.com/silenceper/wechat/v2/officialaccount/context"
"github.com/silenceper/wechat/v2/util"
Expand Down Expand Up @@ -160,8 +162,8 @@ type resAddMaterial struct {
URL string `json:"url"`
}

// AddMaterial 上传永久性素材(处理视频需要单独上传)
func (material *Material) AddMaterial(mediaType MediaType, filename string) (mediaID string, url string, err error) {
// AddMaterialFromReader 上传永久性素材(处理视频需要单独上传),从 io.Reader 中读取
func (material *Material) AddMaterialFromReader(mediaType MediaType, filename string, reader io.Reader) (mediaID string, url string, err error) {
if mediaType == MediaTypeVideo {
err = errors.New("永久视频素材上传使用 AddVideo 方法")
return
Expand All @@ -174,7 +176,7 @@ func (material *Material) AddMaterial(mediaType MediaType, filename string) (med

uri := fmt.Sprintf("%s?access_token=%s&type=%s", addMaterialURL, accessToken, mediaType)
var response []byte
response, err = util.PostFile("media", filename, uri)
response, err = util.PostFileFromReader("media", filename, uri, reader)
if err != nil {
return
}
Expand All @@ -192,13 +194,24 @@ func (material *Material) AddMaterial(mediaType MediaType, filename string) (med
return
}

// AddMaterial 上传永久性素材(处理视频需要单独上传)
func (material *Material) AddMaterial(mediaType MediaType, filename string) (mediaID string, url string, err error) {
f, err := os.Open(filename)
if err != nil {
return
}
defer func() { _ = f.Close() }()

return material.AddMaterialFromReader(mediaType, filename, f)
}

type reqVideo struct {
Title string `json:"title"`
Introduction string `json:"introduction"`
}

// AddVideo 永久视频素材文件上传
func (material *Material) AddVideo(filename, title, introduction string) (mediaID string, url string, err error) {
// AddVideoFromReader 永久视频素材文件上传,从 io.Reader 中读取
func (material *Material) AddVideoFromReader(filename, title, introduction string, reader io.Reader) (mediaID string, url string, err error) {
var accessToken string
accessToken, err = material.GetAccessToken()
if err != nil {
Expand All @@ -219,9 +232,10 @@ func (material *Material) AddVideo(filename, title, introduction string) (mediaI

fields := []util.MultipartFormField{
{
IsFile: true,
Fieldname: "media",
Filename: filename,
IsFile: true,
Fieldname: "media",
Filename: filename,
FileReader: reader,
},
{
IsFile: false,
Expand Down Expand Up @@ -250,6 +264,17 @@ func (material *Material) AddVideo(filename, title, introduction string) (mediaI
return
}

// AddVideo 永久视频素材文件上传
func (material *Material) AddVideo(filename, title, introduction string) (mediaID string, url string, err error) {
f, err := os.Open(filename)
if err != nil {
return "", "", err
}
defer func() { _ = f.Close() }()

return material.AddVideoFromReader(filename, title, introduction, f)
}

type reqDeleteMaterial struct {
MediaID string `json:"media_id"`
}
Expand Down
48 changes: 34 additions & 14 deletions util/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,26 @@ func PostFile(fieldName, filename, uri string) ([]byte, error) {
return PostMultipartForm(fields, uri)
}

// PostFileFromReader 上传文件,从 io.Reader 中读取
func PostFileFromReader(filedName, fileName, uri string, reader io.Reader) ([]byte, error) {
fields := []MultipartFormField{
{
IsFile: true,
Fieldname: filedName,
Filename: fileName,
FileReader: reader,
},
}
return PostMultipartForm(fields, uri)
}

// MultipartFormField 保存文件或其他字段信息
type MultipartFormField struct {
IsFile bool
Fieldname string
Value []byte
Filename string
IsFile bool
Fieldname string
Value []byte
Filename string
FileReader io.Reader
}

// PostMultipartForm 上传文件或其他多个字段
Expand All @@ -182,15 +196,21 @@ func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte
return
}

fh, e := os.Open(field.Filename)
if e != nil {
err = fmt.Errorf("error opening file , err=%v", e)
return
}
defer fh.Close()

if _, err = io.Copy(fileWriter, fh); err != nil {
return
if field.FileReader == nil {
fh, e := os.Open(field.Filename)
if e != nil {
err = fmt.Errorf("error opening file , err=%v", e)
return
}
_, err = io.Copy(fileWriter, fh)
_ = fh.Close()
if err != nil {
return
}
} else {
if _, err = io.Copy(fileWriter, field.FileReader); err != nil {
return
}
}
} else {
partWriter, e := bodyWriter.CreateFormField(field.Fieldname)
Expand All @@ -215,7 +235,7 @@ func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, err
return nil, fmt.Errorf("http code error : uri=%v , statusCode=%v", uri, resp.StatusCode)
}
respBody, err = io.ReadAll(resp.Body)
return
Expand Down
Loading