media.go
author Mikael Berthe <mikael@lilotux.net>
Wed, 10 May 2017 20:12:26 +0200
changeset 179 fbe21b4aabda
parent 162 68df3a01e1a7
child 207 301d5b94be3f
permissions -rw-r--r--
Version 1.5.0

/*
Copyright 2017 Mikael Berthe

Licensed under the MIT license.  Please see the LICENSE file is this directory.
*/

package madon

import (
	"bytes"
	"encoding/json"
	"io"
	"mime/multipart"
	"os"
	"path/filepath"

	"github.com/pkg/errors"
	"github.com/sendgrid/rest"
)

// UploadMedia uploads the given file and returns an attachment
func (mc *Client) UploadMedia(filePath string) (*Attachment, error) {
	var b bytes.Buffer

	if filePath == "" {
		return nil, ErrInvalidParameter
	}

	f, err := os.Open(filePath)
	if err != nil {
		return nil, errors.Wrap(err, "cannot read file")
	}
	defer f.Close()

	w := multipart.NewWriter(&b)
	formWriter, err := w.CreateFormFile("file", filepath.Base(filePath))
	if err != nil {
		return nil, errors.Wrap(err, "media upload")
	}
	if _, err = io.Copy(formWriter, f); err != nil {
		return nil, errors.Wrap(err, "media upload")
	}

	w.Close()

	req, err := mc.prepareRequest("media", rest.Post, nil)
	if err != nil {
		return nil, errors.Wrap(err, "media prepareRequest failed")
	}
	req.Headers["Content-Type"] = w.FormDataContentType()
	req.Body = b.Bytes()

	// Make API call
	r, err := restAPI(req)
	if err != nil {
		return nil, errors.Wrap(err, "media upload failed")
	}

	// Check for error reply
	var errorResult Error
	if err := json.Unmarshal([]byte(r.Body), &errorResult); err == nil {
		// The empty object is not an error
		if errorResult.Text != "" {
			return nil, errors.New(errorResult.Text)
		}
	}

	// Not an error reply; let's unmarshal the data
	var attachment Attachment
	err = json.Unmarshal([]byte(r.Body), &attachment)
	if err != nil {
		return nil, errors.Wrap(err, "cannot decode API response (media)")
	}
	return &attachment, nil
}