修复大文件上传的bug 🐛

This commit is contained in:
eatMoreApple 2021-04-30 11:19:21 +08:00
parent e751e13afd
commit 2b313fe3d8
5 changed files with 77 additions and 41 deletions

View File

@ -2,6 +2,7 @@ package openwechat
import (
"errors"
"net/http"
"os"
)
@ -188,10 +189,8 @@ func (c *Caller) WebWxSync(request *BaseRequest, response *WebInitResponse, info
// 发送消息接口
func (c *Caller) WebWxSendMsg(msg *SendMessage, info *LoginInfo, request *BaseRequest) (*SentMessage, error) {
resp := NewReturnResponse(c.Client.WebWxSendMsg(msg, info, request))
sendSuccessMsg := &SentMessage{SendMessage: msg}
err := parseMessageResponseError(resp, sendSuccessMsg)
return sendSuccessMsg, err
resp, err := c.Client.WebWxSendMsg(msg, info, request)
return getSuccessSentMessage(msg, resp, err)
}
// 修改用户备注接口
@ -200,9 +199,9 @@ func (c *Caller) WebWxOplog(request *BaseRequest, remarkName, toUserName string)
return parseBaseResponseError(resp)
}
func (c *Caller) UploadMedia(file *os.File, request *BaseRequest, info *LoginInfo, fromUserName, toUserName, mediaType string) (*UploadResponse, error) {
func (c *Caller) UploadMedia(file *os.File, request *BaseRequest, info *LoginInfo, fromUserName, toUserName string) (*UploadResponse, error) {
// 首先尝试上传图片
resp := NewReturnResponse(c.Client.WebWxUploadMediaByChunk(file, request, info, fromUserName, toUserName, mediaType))
resp := NewReturnResponse(c.Client.WebWxUploadMediaByChunk(file, request, info, fromUserName, toUserName))
// 无错误上传成功之后获取请求结果,判断结果是否正常
if resp.Err() != nil {
return nil, resp.Err()
@ -226,39 +225,37 @@ func (c *Caller) UploadMedia(file *os.File, request *BaseRequest, info *LoginInf
// 发送图片消息接口
func (c *Caller) WebWxSendImageMsg(file *os.File, request *BaseRequest, info *LoginInfo, fromUserName, toUserName string) (*SentMessage, error) {
// 首先尝试上传图片
resp, err := c.UploadMedia(file, request, info, fromUserName, toUserName, "pic")
resp, err := c.UploadMedia(file, request, info, fromUserName, toUserName)
if err != nil {
return nil, err
}
// 构造新的图片类型的信息
msg := NewMediaSendMessage(ImageMessage, fromUserName, toUserName, resp.MediaId)
// 发送图片信息
return c.WebWxSendAppMsg(msg, request, info)
resp1, err := c.Client.WebWxSendMsgImg(msg, request, info)
return getSuccessSentMessage(msg, resp1, err)
}
func (c *Caller) WebWxSendFile(file *os.File, req *BaseRequest, info *LoginInfo, fromUserName, toUserName string) (*SentMessage, error) {
resp, err := c.UploadMedia(file, req, info, fromUserName, toUserName, "doc")
resp, err := c.UploadMedia(file, req, info, fromUserName, toUserName)
if err != nil {
return nil, err
}
// 构造新的图片类型的信息
msg := NewMediaSendMessage(ImageMessage, fromUserName, toUserName, resp.MediaId)
// 构造新的文件类型的信息
stat, _ := file.Stat()
appMsg := NewFileAppMessage(stat, resp.MediaId)
content, err := appMsg.XmlByte()
if err != nil {
return nil, err
}
msg.Content = string(content)
return c.WebWxSendAppMsg(msg, req, info)
msg := NewSendMessage(AppMessage, string(content), fromUserName, toUserName, "")
return c.WebWxSendAppMsg(msg, req)
}
// 发送媒体消息
func (c *Caller) WebWxSendAppMsg(msg *SendMessage, req *BaseRequest, info *LoginInfo) (*SentMessage, error) {
resp := NewReturnResponse(c.Client.WebWxSendMsgImg(msg, req, info))
sendSuccessMsg := &SentMessage{SendMessage: msg}
err := parseMessageResponseError(resp, sendSuccessMsg)
return sendSuccessMsg, err
func (c *Caller) WebWxSendAppMsg(msg *SendMessage, req *BaseRequest) (*SentMessage, error) {
resp, err := c.Client.WebWxSendAppMsg(msg, req)
return getSuccessSentMessage(msg, resp, err)
}
// 用户退出
@ -333,3 +330,10 @@ func parseMessageResponseError(resp *ReturnResponse, msg *SentMessage) error {
msg.MsgId = messageResp.MsgID
return nil
}
func getSuccessSentMessage(msg *SendMessage, resp *http.Response, err error) (*SentMessage, error) {
returnResp := NewReturnResponse(resp, err)
sendSuccessMsg := &SentMessage{SendMessage: msg}
err = parseMessageResponseError(returnResp, sendSuccessMsg)
return sendSuccessMsg, err
}

View File

@ -230,6 +230,8 @@ func (c *Client) sendMessage(request *BaseRequest, url string, msg *SendMessage)
body, _ := ToBuffer(content)
req, _ := http.NewRequest(http.MethodPost, url, body)
req.Header.Add("Content-Type", jsonContentType)
fmt.Println(6666)
fmt.Println(body.String())
return c.Do(req)
}
@ -251,7 +253,7 @@ func (c *Client) WebWxGetHeadImg(headImageUrl string) (*http.Response, error) {
return c.Do(req)
}
func (c *Client) WebWxUploadMediaByChunk(file *os.File, request *BaseRequest, info *LoginInfo, forUserName, toUserName, mediaType string) (*http.Response, error) {
func (c *Client) WebWxUploadMediaByChunk(file *os.File, request *BaseRequest, info *LoginInfo, forUserName, toUserName string) (*http.Response, error) {
// 获取文件上传的类型
contentType, err := GetFileContentType(file)
if err != nil {
@ -276,6 +278,9 @@ func (c *Client) WebWxUploadMediaByChunk(file *os.File, request *BaseRequest, in
return nil, err
}
// 获取文件的类型
mediaType := getMessageType(sate.Name())
path, _ := url.Parse(c.webWxUpLoadMediaUrl)
params := url.Values{}
params.Add("f", "json")

View File

@ -115,3 +115,12 @@ const (
)
const TimeFormat = "Mon Jan 02 2006 15:04:05 GMT+0800 (中国标准时间)"
var imageType = map[string]bool{
"bmp": true,
"png": true,
"jpeg": true,
"jpg": true,
}
var videoType = "mp4"

View File

@ -336,7 +336,7 @@ type SendMessage struct {
ToUserName string
LocalID string
ClientMsgId string
MediaId string
MediaId string `json:"MediaId,omitempty"`
}
// SendMessage的构造方法
@ -472,18 +472,17 @@ func (s *SentMessage) Revoke() error {
return s.Self.RevokeMessage(s)
}
type FileAppMessage struct {
AppMsg xml.Name `xml:"appmsg"`
Type int `xml:"type"`
AppId string `xml:"appid,attr"` // wxeb7ec651dd0aefa9
SdkVer string `xml:"sdkver,attr"`
Title string `xml:"title"`
Des string `xml:"des"`
Action string `xml:"action"`
Content string `xml:"content"`
Url string `xml:"url"`
LowUrl string `xml:"lowurl"`
ExtInfo string `xml:"extinfo"`
type appmsg struct {
Type int `xml:"type"`
AppId string `xml:"appid,attr"` // wxeb7ec651dd0aefa9
SdkVer string `xml:"sdkver,attr"`
Title string `xml:"title"`
Des string `xml:"des"`
Action string `xml:"action"`
Content string `xml:"content"`
Url string `xml:"url"`
LowUrl string `xml:"lowurl"`
ExtInfo string `xml:"extinfo"`
AppAttach struct {
TotalLen int64 `xml:"totallen"`
AttachId string `xml:"attachid"`
@ -491,14 +490,15 @@ type FileAppMessage struct {
} `xml:"appattach"`
}
func (f FileAppMessage) XmlByte() ([]byte, error) {
func (f appmsg) XmlByte() ([]byte, error) {
return xml.Marshal(f)
}
func NewFileAppMessage(stat os.FileInfo, attachId string) *FileAppMessage {
m := &FileAppMessage{AppId: "wxeb7ec651dd0aefa9", Title: stat.Name()}
func NewFileAppMessage(stat os.FileInfo, attachId string) *appmsg {
m := &appmsg{AppId: "wxeb7ec651dd0aefa9", Title: stat.Name()}
m.AppAttach.AttachId = attachId
m.AppAttach.TotalLen = stat.Size()
m.Type = 6
m.AppAttach.FileExt = getFileExt(stat.Name())
return m
}

View File

@ -12,11 +12,12 @@ import (
)
func ToBuffer(v interface{}) (*bytes.Buffer, error) {
buf, err := json.Marshal(v)
if err != nil {
return nil, err
}
return bytes.NewBuffer(buf), nil
var buffer bytes.Buffer
encoder := json.NewEncoder(&buffer)
// 这里要设置进制html转义
encoder.SetEscapeHTML(false)
err := encoder.Encode(v)
return &buffer, err
}
// 获取随机设备id
@ -67,8 +68,25 @@ func GetFileContentType(file multipart.File) (string, error) {
func getFileExt(name string) string {
results := strings.Split(name, ".")
if len(results) == 0 {
if len(results) == 1 {
return "undefined"
}
return results[len(results)-1]
}
const (
pic = "pic"
video = "video"
doc = "doc"
)
// 微信匹配文件类型策略
func getMessageType(filename string) string {
ext := getFileExt(filename)
if imageType[ext] {
return pic
} else if ext == videoType {
return video
}
return doc
}