diff --git a/caller.go b/caller.go index 0a08f07..ac39870 100644 --- a/caller.go +++ b/caller.go @@ -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 +} diff --git a/client.go b/client.go index 2eef103..23d975a 100644 --- a/client.go +++ b/client.go @@ -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") diff --git a/global.go b/global.go index 1fc90bd..ac7e7a7 100644 --- a/global.go +++ b/global.go @@ -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" diff --git a/message.go b/message.go index 105ddf8..37d5c80 100644 --- a/message.go +++ b/message.go @@ -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 } diff --git a/parser.go b/parser.go index 1fb625c..556097a 100644 --- a/parser.go +++ b/parser.go @@ -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 +}