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

新增支持流的形式上传方式 #781

Closed
wants to merge 6 commits into from
Closed
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
5 changes: 4 additions & 1 deletion miniprogram/content/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,12 @@ func (content *Content) CheckImage(media string) error {
if err != nil {
return err
}
var directory = media
response, err := util.PostFile(
"media",
media,
nil,
"",
directory,
fmt.Sprintf(checkImageURL, accessToken),
)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions miniprogram/security/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ func (security *Security) MediaCheckAsync(in *MediaCheckAsyncRequest) (traceID s
// https://developers.weixin.qq.com/miniprogram/dev/framework/security.imgSecCheck.html
// Deprecated
// 在2021年9月1日停止更新。建议使用 MediaCheckAsync
func (security *Security) ImageCheckV1(filename string) (err error) {
func (security *Security) ImageCheckV1(directory string) (err error) {
accessToken, err := security.GetAccessToken()
if err != nil {
return
}

uri := fmt.Sprintf(imageCheckURL, accessToken)
Copy link
Collaborator

@houseme houseme Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

104-106 合并定义

var(
    uri = fmt.Sprintf(imageCheckURL, accessToken)
    directory = filename
    response, err = util.PostFile("media", nil, "", directory, uri)
)

response, err := util.PostFile("media", filename, uri)
response, err := util.PostFile("media", nil, "", directory, uri)
if err != nil {
return
}
Expand Down
4 changes: 2 additions & 2 deletions officialaccount/customerservice/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,15 @@ func (csm *Manager) InviteBind(kfAccount, inviteWX string) (err error) {
}

// UploadHeadImg 上传客服头像
func (csm *Manager) UploadHeadImg(kfAccount, fileName string) (err error) {
func (csm *Manager) UploadHeadImg(kfAccount, directory string) (err error) {
var accessToken string
accessToken, err = csm.GetAccessToken()
if err != nil {
return
}
uri := fmt.Sprintf("%s?access_token=%s&kf_account=%s", customerServiceUploadHeadImg, accessToken, kfAccount)
var response []byte
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上

response, err = util.PostFile("media", fileName, uri)
response, err = util.PostFile("media", nil, "", directory, uri)
if err != nil {
return
}
Expand Down
25 changes: 14 additions & 11 deletions officialaccount/material/material.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io"
"os"
"path"

"github.com/silenceper/wechat/v2/officialaccount/context"
"github.com/silenceper/wechat/v2/util"
Expand Down Expand Up @@ -163,7 +164,7 @@ type resAddMaterial struct {
}

// AddMaterialFromReader 上传永久性素材(处理视频需要单独上传),从 io.Reader 中读取
func (material *Material) AddMaterialFromReader(mediaType MediaType, filename string, reader io.Reader) (mediaID string, url string, err error) {
func (material *Material) AddMaterialFromReader(mediaType MediaType, directory string, reader io.Reader) (mediaID string, url string, err error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filename 改成 directory 的意义是什么?或出发点是什么呢?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我是在开发企业微信客服发送消息上传临时素材获取media_id时,看上传都是以本地临时文件夹形式上传的,然后想改下可以通过流或文件传输,然后就增加了Directory字段,filename只是文件名,为了和永久素材做区分。新人第一次看开源的,可能有点菜 😭

if mediaType == MediaTypeVideo {
err = errors.New("永久视频素材上传使用 AddVideo 方法")
return
Expand All @@ -176,7 +177,7 @@ func (material *Material) AddMaterialFromReader(mediaType MediaType, filename st

uri := fmt.Sprintf("%s?access_token=%s&type=%s", addMaterialURL, accessToken, mediaType)
var response []byte
response, err = util.PostFileFromReader("media", filename, uri, reader)
response, err = util.PostFileFromReader("media", directory, uri, reader)
if err != nil {
return
}
Expand All @@ -195,14 +196,14 @@ func (material *Material) AddMaterialFromReader(mediaType MediaType, filename st
}

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

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

type reqVideo struct {
Expand All @@ -211,7 +212,7 @@ type reqVideo struct {
}

// AddVideoFromReader 永久视频素材文件上传,从 io.Reader 中读取
func (material *Material) AddVideoFromReader(filename, title, introduction string, reader io.Reader) (mediaID string, url string, err error) {
func (material *Material) AddVideoFromReader(directory, title, introduction string, reader io.Reader) (mediaID string, url string, err error) {
var accessToken string
accessToken, err = material.GetAccessToken()
if err != nil {
Expand All @@ -229,12 +230,14 @@ func (material *Material) AddVideoFromReader(filename, title, introduction strin
if err != nil {
return
}

// 获取文件名
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

233-250 合并一下

fileName := path.Base(directory)
fields := []util.MultipartFormField{
{
IsFile: true,
Fieldname: "media",
Filename: filename,
Filename: fileName,
Directory: directory,
FileReader: reader,
},
{
Expand Down Expand Up @@ -265,14 +268,14 @@ func (material *Material) AddVideoFromReader(filename, title, introduction strin
}

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

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

type reqDeleteMaterial struct {
Expand Down
34 changes: 27 additions & 7 deletions officialaccount/material/media.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package material
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"

"github.com/silenceper/wechat/v2/util"
)
Expand Down Expand Up @@ -38,16 +41,32 @@ type Media struct {
}

// MediaUpload 临时素材上传
func (material *Material) MediaUpload(mediaType MediaType, filename string) (media Media, err error) {
func (material *Material) MediaUpload(mediaType MediaType, url string) (media Media, err error) {
var accessToken string
accessToken, err = material.GetAccessToken()
if err != nil {
if accessToken, err = material.GetAccessToken(); err != nil {
return
}

uri := fmt.Sprintf("%s?access_token=%s&type=%s", mediaUploadURL, accessToken, mediaType)
// 使用strings.LastIndex函数找到最后一个斜杠的位置
lastSlashIndex := strings.LastIndex(url, "/")
// 从最后一个斜杠的位置截取到最后,获取文件名
filename := url[lastSlashIndex+1:]
// 获取资源
resp, err := http.Get(url)
if err != nil {
err = fmt.Errorf("get image error: %v", err)
return
}
// 读取响应到内存
var imageData []byte
imageData, err = io.ReadAll(resp.Body)
defer resp.Body.Close()
if err != nil {
err = fmt.Errorf("read image error: %v", err)
return
}
var response []byte
response, err = util.PostFile("media", filename, uri)
response, err = util.PostFile("media", imageData, filename, "", uri)
if err != nil {
return
}
Expand All @@ -56,7 +75,7 @@ func (material *Material) MediaUpload(mediaType MediaType, filename string) (med
return
}
if media.ErrCode != 0 {
err = fmt.Errorf("MediaUpload error : errcode=%v , errmsg=%v", media.ErrCode, media.ErrMsg)
err = fmt.Errorf("MediaUpload error : errcode=%v, errmsg=%v", media.ErrCode, media.ErrMsg)
return
}
return
Expand Down Expand Up @@ -91,7 +110,8 @@ func (material *Material) ImageUpload(filename string) (url string, err error) {

uri := fmt.Sprintf("%s?access_token=%s", mediaUploadImageURL, accessToken)
var response []byte
response, err = util.PostFile("media", filename, uri)
var directory = filename
response, err = util.PostFile("media", nil, "", directory, uri)
if err != nil {
return
}
Expand Down
56 changes: 27 additions & 29 deletions officialaccount/message/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ func (tpl *Template) Send(msg *TemplateMessage) (msgID int64, err error) {
if err != nil {
return
}
var (
uri = fmt.Sprintf("%s?access_token=%s", templateSendURL, accessToken)
response []byte
)
if response, err = util.PostJSON(uri, msg); err != nil {
uri := fmt.Sprintf("%s?access_token=%s", templateSendURL, accessToken)
Copy link
Collaborator

@houseme houseme Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

当时这样改的出发点是什么,可以分享一下不?前一个同学把这类型定义都合并了,现在又拆开了,想了解一下,您这边拆分的出发点是什么,咱们可以取其优点在代码编写中,感谢

var response []byte
response, err = util.PostJSON(uri, msg)
if err != nil {
return
}
var result resTemplateSend
if err = json.Unmarshal(response, &result); err != nil {
err = json.Unmarshal(response, &result)
if err != nil {
return
}
if result.ErrCode != 0 {
Expand Down Expand Up @@ -103,11 +103,10 @@ func (tpl *Template) List() (templateList []*TemplateItem, err error) {
if err != nil {
return
}
var (
uri = fmt.Sprintf("%s?access_token=%s", templateListURL, accessToken)
response []byte
)
if response, err = util.HTTPGet(uri); err != nil {
uri := fmt.Sprintf("%s?access_token=%s", templateListURL, accessToken)
var response []byte
response, err = util.HTTPGet(uri)
if err != nil {
return
}
var res resTemplateList
Expand All @@ -122,23 +121,22 @@ type resTemplateAdd struct {
}

// Add 添加模板.
func (tpl *Template) Add(shortID string, keyNameList []string) (templateID string, err error) {
func (tpl *Template) Add(shortID string) (templateID string, err error) {
var accessToken string
accessToken, err = tpl.GetAccessToken()
if err != nil {
return
}
var (
msg = struct {
ShortID string `json:"template_id_short"`
KeyNameList []string `json:"keyword_name_list"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keyNameList 是上一个 pr #783 添加的参数,确定一下是否要删除呢?

}{ShortID: shortID, KeyNameList: keyNameList}
uri = fmt.Sprintf("%s?access_token=%s", templateAddURL, accessToken)
response []byte
)
if response, err = util.PostJSON(uri, msg); err != nil {
var msg = struct {
ShortID string `json:"template_id_short"`
}{ShortID: shortID}
uri := fmt.Sprintf("%s?access_token=%s", templateAddURL, accessToken)
var response []byte
response, err = util.PostJSON(uri, msg)
if err != nil {
return
}

var result resTemplateAdd
err = util.DecodeWithError(response, &result, "AddTemplate")
return result.TemplateID, err
Expand All @@ -151,14 +149,14 @@ func (tpl *Template) Delete(templateID string) (err error) {
if err != nil {
return
}
var (
msg = struct {
TemplateID string `json:"template_id"`
}{TemplateID: templateID}
uri = fmt.Sprintf("%s?access_token=%s", templateDelURL, accessToken)
response []byte
)
if response, err = util.PostJSON(uri, msg); err != nil {
var msg = struct {
TemplateID string `json:"template_id"`
}{TemplateID: templateID}

uri := fmt.Sprintf("%s?access_token=%s", templateDelURL, accessToken)
var response []byte
response, err = util.PostJSON(uri, msg)
if err != nil {
return
}
return util.DecodeWithCommonError(response, "DeleteTemplate")
Expand Down
34 changes: 27 additions & 7 deletions util/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"mime/multipart"
"net/http"
"os"
"path"

"golang.org/x/crypto/pkcs12"
)
Expand Down Expand Up @@ -146,25 +147,43 @@ func PostJSONWithRespContentType(uri string, obj interface{}) ([]byte, string, e
return responseData, contentType, err
}

// PostFile 上传文件
func PostFile(fieldName, filename, uri string) ([]byte, error) {
// PostFile 支持流或文件形式上传
func PostFile(fieldName string, data []byte, fileName string, directory string, uri string) ([]byte, error) {
var fileContent []byte
var isFile bool
// 判断
if len(data) == 0 && directory != "" {
fileName = path.Base(directory)
isFile = true
} else if len(data) > 0 && fileName != "" {
fileContent = data
isFile = false
} else {
return nil, fmt.Errorf("error parameter required streamdata=%v and filename=%v or only directory=%v", data, fileName, directory)
}

fields := []MultipartFormField{
{
IsFile: true,
IsFile: isFile,
Fieldname: fieldName,
Filename: filename,
Value: fileContent,
Filename: fileName,
Directory: directory,
},
}
return PostMultipartForm(fields, uri)
}

// PostFileFromReader 上传文件,从 io.Reader 中读取
func PostFileFromReader(filedName, fileName, uri string, reader io.Reader) ([]byte, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

介绍一下这个代码删除的原因是什么?

func PostFileFromReader(filedName, directory, uri string, reader io.Reader) ([]byte, error) {
// 获取文件名
fileName := path.Base(directory)
fields := []MultipartFormField{
{
IsFile: true,
Fieldname: filedName,
Filename: fileName,
Directory: directory,
FileReader: reader,
},
}
Expand All @@ -177,6 +196,7 @@ type MultipartFormField struct {
Fieldname string
Value []byte
Filename string
Directory string
FileReader io.Reader
}

Expand All @@ -197,7 +217,7 @@ func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte
}

if field.FileReader == nil {
fh, e := os.Open(field.Filename)
fh, e := os.Open(field.Directory)
if e != nil {
err = fmt.Errorf("error opening file , err=%v", e)
return
Expand All @@ -213,7 +233,7 @@ func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte
}
}
} else {
partWriter, e := bodyWriter.CreateFormField(field.Fieldname)
partWriter, e := bodyWriter.CreateFormFile(field.Fieldname, field.Filename)
if e != nil {
err = e
return
Expand Down
Loading
Loading