github.com/chanxuehong/wechat@v0.0.0-20230222024006-36f0325263cd/mp/material/upload.go (about)

     1  package material
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"io"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/chanxuehong/wechat/mp/core"
    11  )
    12  
    13  const (
    14  	MaterialTypeImage = "image"
    15  	MaterialTypeVoice = "voice"
    16  	MaterialTypeVideo = "video"
    17  	MaterialTypeThumb = "thumb"
    18  	MaterialTypeNews  = "news"
    19  )
    20  
    21  // image ===============================================================================================================
    22  
    23  // UploadImage 上传多媒体图片
    24  func UploadImage(clt *core.Client, _filepath string) (mediaId, url string, err error) {
    25  	file, err := os.Open(_filepath)
    26  	if err != nil {
    27  		return
    28  	}
    29  	defer file.Close()
    30  
    31  	return UploadImageFromReader(clt, filepath.Base(_filepath), file)
    32  }
    33  
    34  // UploadImageFromReader 上传多媒体图片
    35  //
    36  //	NOTE: 参数 filename 不是文件路径, 是 multipart/form-data 里面 filename 的值.
    37  func UploadImageFromReader(clt *core.Client, filename string, reader io.Reader) (mediaId, url string, err error) {
    38  	const incompleteURL = "https://api.weixin.qq.com/cgi-bin/material/add_material?type=image&access_token="
    39  
    40  	var fields = []core.MultipartFormField{
    41  		{
    42  			IsFile:   true,
    43  			Name:     "media",
    44  			FileName: filename,
    45  			Value:    reader,
    46  		},
    47  	}
    48  	var result struct {
    49  		core.Error
    50  		MediaId string `json:"media_id"`
    51  		URL     string `json:"url"`
    52  	}
    53  	if err = clt.PostMultipartForm(incompleteURL, fields, &result); err != nil {
    54  		return
    55  	}
    56  	if result.ErrCode != core.ErrCodeOK {
    57  		err = &result.Error
    58  		return
    59  	}
    60  	mediaId = result.MediaId
    61  	url = result.URL
    62  	return
    63  }
    64  
    65  // thumb ===============================================================================================================
    66  
    67  // UploadThumb 上传多媒体缩略图
    68  func UploadThumb(clt *core.Client, _filepath string) (mediaId, url string, err error) {
    69  	file, err := os.Open(_filepath)
    70  	if err != nil {
    71  		return
    72  	}
    73  	defer file.Close()
    74  
    75  	return UploadThumbFromReader(clt, filepath.Base(_filepath), file)
    76  }
    77  
    78  // UploadThumbFromReader 上传多媒体缩略图
    79  //
    80  //	NOTE: 参数 filename 不是文件路径, 是 multipart/form-data 里面 filename 的值.
    81  func UploadThumbFromReader(clt *core.Client, filename string, reader io.Reader) (mediaId, url string, err error) {
    82  	const incompleteURL = "https://api.weixin.qq.com/cgi-bin/material/add_material?type=thumb&access_token="
    83  
    84  	var fields = []core.MultipartFormField{
    85  		{
    86  			IsFile:   true,
    87  			Name:     "media",
    88  			FileName: filename,
    89  			Value:    reader,
    90  		},
    91  	}
    92  	var result struct {
    93  		core.Error
    94  		MediaId string `json:"media_id"`
    95  		URL     string `json:"url"`
    96  	}
    97  	if err = clt.PostMultipartForm(incompleteURL, fields, &result); err != nil {
    98  		return
    99  	}
   100  	if result.ErrCode != core.ErrCodeOK {
   101  		err = &result.Error
   102  		return
   103  	}
   104  	mediaId = result.MediaId
   105  	url = result.URL
   106  	return
   107  }
   108  
   109  // voice ===============================================================================================================
   110  
   111  // UploadVoice 上传多媒体语音
   112  func UploadVoice(clt *core.Client, _filepath string) (mediaId string, err error) {
   113  	file, err := os.Open(_filepath)
   114  	if err != nil {
   115  		return
   116  	}
   117  	defer file.Close()
   118  
   119  	return UploadVoiceFromReader(clt, filepath.Base(_filepath), file)
   120  }
   121  
   122  // UploadVoiceFromReader 上传多媒体语音
   123  //
   124  //	NOTE: 参数 filename 不是文件路径, 是 multipart/form-data 里面 filename 的值.
   125  func UploadVoiceFromReader(clt *core.Client, filename string, reader io.Reader) (mediaId string, err error) {
   126  	const incompleteURL = "https://api.weixin.qq.com/cgi-bin/material/add_material?type=voice&access_token="
   127  
   128  	var fields = []core.MultipartFormField{
   129  		{
   130  			IsFile:   true,
   131  			Name:     "media",
   132  			FileName: filename,
   133  			Value:    reader,
   134  		},
   135  	}
   136  	var result struct {
   137  		core.Error
   138  		MediaId string `json:"media_id"`
   139  	}
   140  	if err = clt.PostMultipartForm(incompleteURL, fields, &result); err != nil {
   141  		return
   142  	}
   143  	if result.ErrCode != core.ErrCodeOK {
   144  		err = &result.Error
   145  		return
   146  	}
   147  	mediaId = result.MediaId
   148  	return
   149  }
   150  
   151  // video ===============================================================================================================
   152  
   153  // UploadVideo 上传多媒体视频.
   154  func UploadVideo(clt *core.Client, _filepath string, title, introduction string) (mediaId string, err error) {
   155  	file, err := os.Open(_filepath)
   156  	if err != nil {
   157  		return
   158  	}
   159  	defer file.Close()
   160  
   161  	return UploadVideoFromReader(clt, filepath.Base(_filepath), file, title, introduction)
   162  }
   163  
   164  // UploadVideoFromReader 上传多媒体缩视频.
   165  //
   166  //	NOTE: 参数 filename 不是文件路径, 是 multipart/form-data 里面 filename 的值.
   167  func UploadVideoFromReader(clt *core.Client, filename string, reader io.Reader, title, introduction string) (mediaId string, err error) {
   168  	const incompleteURL = "https://api.weixin.qq.com/cgi-bin/material/add_material?type=video&access_token="
   169  
   170  	buffer := bytes.NewBuffer(make([]byte, 0, 256))
   171  	encoder := json.NewEncoder(buffer)
   172  	encoder.SetEscapeHTML(false)
   173  
   174  	var description = struct {
   175  		Title        string `json:"title"`
   176  		Introduction string `json:"introduction"`
   177  	}{
   178  		Title:        title,
   179  		Introduction: introduction,
   180  	}
   181  	if err = encoder.Encode(&description); err != nil {
   182  		return
   183  	}
   184  	descriptionBytes := buffer.Bytes()
   185  
   186  	var fields = []core.MultipartFormField{
   187  		{
   188  			IsFile:   true,
   189  			Name:     "media",
   190  			FileName: filename,
   191  			Value:    reader,
   192  		},
   193  		{
   194  			IsFile: false,
   195  			Name:   "description",
   196  			Value:  bytes.NewReader(descriptionBytes),
   197  		},
   198  	}
   199  	var result struct {
   200  		core.Error
   201  		MediaId string `json:"media_id"`
   202  	}
   203  	if err = clt.PostMultipartForm(incompleteURL, fields, &result); err != nil {
   204  		return
   205  	}
   206  	if result.ErrCode != core.ErrCodeOK {
   207  		err = &result.Error
   208  		return
   209  	}
   210  	mediaId = result.MediaId
   211  	return
   212  }