Example #1
0
// DownloadToWriter 下载多媒体到 io.Writer.
//  对于视频素材, 先通过 GetVideo 得到 Video 信息, 然后通过 Video.DownloadURL 来下载
func DownloadToWriter(clt *core.Client, mediaId string, writer io.Writer) (written int64, err error) {
	httpClient := clt.HttpClient
	if httpClient == nil {
		httpClient = http.DefaultClient
	}

	var request = struct {
		MediaId string `json:"media_id"`
	}{
		MediaId: mediaId,
	}
	requestBodyBytes, err := json.Marshal(&request)
	if err != nil {
		return
	}
	var errorResult core.Error

	// 先读取 64bytes 内容来判断返回的是不是错误信息
	// {"errcode":40007,"errmsg":"invalid media_id"}
	var buf = make([]byte, 64)

	token, err := clt.Token()
	if err != nil {
		return
	}

	hasRetried := false
RETRY:
	finalURL := "https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=" + url.QueryEscape(token)
	written, err = httpDownloadToWriter(httpClient, finalURL, requestBodyBytes, buf, writer, &errorResult)
	if err != nil {
		return
	}
	if written > 0 {
		return
	}

	switch errorResult.ErrCode {
	case core.ErrCodeOK:
		return // 基本不会出现
	case core.ErrCodeInvalidCredential, core.ErrCodeAccessTokenExpired:
		retry.DebugPrintError(errorResult.ErrCode, errorResult.ErrMsg, token)
		if !hasRetried {
			hasRetried = true
			errorResult = core.Error{}
			if token, err = clt.RefreshToken(token); err != nil {
				return
			}
			retry.DebugPrintNewToken(token)
			goto RETRY
		}
		retry.DebugPrintFallthrough(token)
		fallthrough
	default:
		err = &errorResult
		return
	}
}
Example #2
0
// UploadVideoFromReader 上传多媒体缩视频.
//  NOTE: 参数 filename 不是文件路径, 是 multipart/form-data 里面 filename 的值.
func UploadVideoFromReader(clt *core.Client, filename string, reader io.Reader, title, introduction string) (mediaId string, err error) {
	const incompleteURL = "https://api.weixin.qq.com/cgi-bin/material/add_material?type=video&access_token="

	var description = struct {
		Title        string `json:"title"`
		Introduction string `json:"introduction"`
	}{
		Title:        title,
		Introduction: introduction,
	}
	descriptionBytes, err := json.Marshal(&description)
	if err != nil {
		return
	}

	var fields = []core.MultipartFormField{
		{
			IsFile:   true,
			Name:     "media",
			FileName: filename,
			Value:    reader,
		},
		{
			IsFile: false,
			Name:   "description",
			Value:  bytes.NewReader(descriptionBytes),
		},
	}
	var result struct {
		core.Error
		MediaId string `json:"media_id"`
	}
	if err = clt.PostMultipartForm(incompleteURL, fields, &result); err != nil {
		return
	}
	if result.ErrCode != core.ErrCodeOK {
		err = &result.Error
		return
	}
	mediaId = result.MediaId
	return
}