github.com/chanxuehong/wechat@v0.0.0-20230222024006-36f0325263cd/mp/media/upload.go (about) 1 package media 2 3 import ( 4 "io" 5 "os" 6 "path/filepath" 7 8 "github.com/chanxuehong/wechat/mp/core" 9 ) 10 11 const ( 12 MediaTypeImage = "image" 13 MediaTypeVoice = "voice" 14 MediaTypeVideo = "video" 15 MediaTypeThumb = "thumb" 16 MediaTypeNews = "news" 17 ) 18 19 type MediaInfo struct { 20 MediaType string `json:"type"` // 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb,主要用于视频与音乐格式的缩略图) 21 MediaId string `json:"media_id"` // 媒体文件上传后,获取时的唯一标识 22 CreatedAt int64 `json:"created_at"` // 媒体文件上传时间戳 23 } 24 25 // UploadImage 上传多媒体图片 26 func UploadImage(clt *core.Client, filepath string) (info *MediaInfo, err error) { 27 return upload(clt, MediaTypeImage, filepath) 28 } 29 30 // UploadImageFromReader 上传多媒体图片 31 // 32 // NOTE: 参数 filename 不是文件路径, 是 multipart/form-data 里面 filename 的值. 33 func UploadImageFromReader(clt *core.Client, filename string, reader io.Reader) (info *MediaInfo, err error) { 34 return uploadFromReader(clt, MediaTypeImage, filename, reader) 35 } 36 37 // UploadVoice 上传多媒体语音 38 func UploadVoice(clt *core.Client, filepath string) (info *MediaInfo, err error) { 39 return upload(clt, MediaTypeVoice, filepath) 40 } 41 42 // UploadVoiceFromReader 上传多媒体语音 43 // 44 // NOTE: 参数 filename 不是文件路径, 是 multipart/form-data 里面 filename 的值. 45 func UploadVoiceFromReader(clt *core.Client, filename string, reader io.Reader) (info *MediaInfo, err error) { 46 return uploadFromReader(clt, MediaTypeVoice, filename, reader) 47 } 48 49 // UploadVideo 上传多媒体视频 50 func UploadVideo(clt *core.Client, filepath string) (info *MediaInfo, err error) { 51 return upload(clt, MediaTypeVideo, filepath) 52 } 53 54 // UploadVideoFromReader 上传多媒体视频 55 // 56 // NOTE: 参数 filename 不是文件路径, 是 multipart/form-data 里面 filename 的值. 57 func UploadVideoFromReader(clt *core.Client, filename string, reader io.Reader) (info *MediaInfo, err error) { 58 return uploadFromReader(clt, MediaTypeVideo, filename, reader) 59 } 60 61 // ===================================================================================================================== 62 63 func upload(clt *core.Client, mediaType, _filepath string) (info *MediaInfo, err error) { 64 file, err := os.Open(_filepath) 65 if err != nil { 66 return 67 } 68 defer file.Close() 69 70 return uploadFromReader(clt, mediaType, filepath.Base(_filepath), file) 71 } 72 73 func uploadFromReader(clt *core.Client, mediaType, filename string, reader io.Reader) (info *MediaInfo, err error) { 74 var incompleteURL = "https://api.weixin.qq.com/cgi-bin/media/upload?type=" + mediaType + "&access_token=" 75 76 var fields = []core.MultipartFormField{ 77 { 78 IsFile: true, 79 Name: "media", 80 FileName: filename, 81 Value: reader, 82 }, 83 } 84 var result struct { 85 core.Error 86 MediaInfo 87 } 88 if err = clt.PostMultipartForm(incompleteURL, fields, &result); err != nil { 89 return 90 } 91 if result.ErrCode != core.ErrCodeOK { 92 err = &result.Error 93 return 94 } 95 info = &result.MediaInfo 96 return 97 } 98 99 // ===================================================================================================================== 100 101 // UploadThumb 上传多媒体缩略图 102 func UploadThumb(clt *core.Client, _filepath string) (info *MediaInfo, err error) { 103 file, err := os.Open(_filepath) 104 if err != nil { 105 return 106 } 107 defer file.Close() 108 109 return UploadThumbFromReader(clt, filepath.Base(_filepath), file) 110 } 111 112 // UploadThumbFromReader 上传多媒体缩略图. 113 // 114 // NOTE: 参数 filename 不是文件路径, 是 multipart/form-data 里面 filename 的值. 115 func UploadThumbFromReader(clt *core.Client, filename string, reader io.Reader) (info *MediaInfo, err error) { 116 const incompleteURL = "https://api.weixin.qq.com/cgi-bin/media/upload?type=thumb&access_token=" 117 118 var fields = []core.MultipartFormField{ 119 { 120 IsFile: true, 121 Name: "media", 122 FileName: filename, 123 Value: reader, 124 }, 125 } 126 var result struct { 127 core.Error 128 MediaType string `json:"type"` 129 MediaId string `json:"thumb_media_id"` 130 CreatedAt int64 `json:"created_at"` 131 } 132 if err = clt.PostMultipartForm(incompleteURL, fields, &result); err != nil { 133 return 134 } 135 if result.ErrCode != core.ErrCodeOK { 136 err = &result.Error 137 return 138 } 139 info = &MediaInfo{ 140 MediaType: result.MediaType, 141 MediaId: result.MediaId, 142 CreatedAt: result.CreatedAt, 143 } 144 return 145 }