转发文件上传到其他服务器



我正在尝试通过Facebook Graph API上传本地视频。

这是官方文档:https://developers.facebook.com/docs/messenger-platform/reference/attachment-upload-api/

-F 'message={"attachment":{"type":"image", "payload":{"is_reusable":true}}}' 
-F 'filedata=@/tmp/shirt.png;type=image/png' 
"https://graph.facebook.com/v12.0/me/message_attachments?access_token=<PAGE_ACCESS_TOKEN>"
这是我的Golang代码:
func uploadVideoStream(c *Context, w http.ResponseWriter, r *http.Request) {
if err := r.ParseMultipartForm(MAXIMUM_PLUGIN_FILE_SIZE); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
m := r.MultipartForm
fileArray, ok := m.File["files"]
if !ok {
c.Err = model.NewAppError("uploadPlugin", "api.plugin.upload.no_file.app_error", nil, "", http.StatusBadRequest)
return
}
if len(fileArray) <= 0 {
c.Err = model.NewAppError("uploadPlugin", "api.plugin.upload.array.app_error", nil, "", http.StatusBadRequest)
return
}
file, err := fileArray[0].Open()
if err != nil {
c.Err = model.NewAppError("uploadPlugin", "api.plugin.upload.file.app_error", nil, "", http.StatusBadRequest)
return
}
defer file.Close()
// build a form body
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
_message := uploadVideoData{
Message: uploadVideoDataMessage{
Attachment: uploadVideoDataMessageAttachment{
Type: "video",
Payload: uploadVideoDataMessageAttachmentPayload{
IsReusable: true,
},
},
},
}
// add form fields
writer.WriteField("message", _message.Message.ToJson())
// add a form file to the body
fileWriter, err := writer.CreateFormFile("filedata", fileArray[0].Filename)
if err != nil {
c.Err = model.NewAppError("upload_video", "upload_video.error", nil, "", http.StatusBadRequest)
return
}
// copy the file into the fileWriter
_, err = io.Copy(fileWriter, file)
if err != nil {
c.Err = model.NewAppError("upload_video", "upload_video.error", nil, "", http.StatusBadRequest)
return
}
// Close the body writer
writer.Close()
reqUrl := "https://graph.facebook.com/v10.0/me/message_attachments"
token := "EAAUxUcj3C64BADxxsm70hZCXTMO0eQHmSpV..."
reqUrl += "?access_token=" + token
var netTransport = &http.Transport{
Dial: (&net.Dialer{
Timeout: 120 * time.Second,
}).Dial,
TLSHandshakeTimeout:   120 * time.Second,
ResponseHeaderTimeout: 120 * time.Second, // This will fixed the i/o timeout error
}
client := &http.Client{
Timeout:   time.Second * 120,
Transport: netTransport,
}
req, _ := http.NewRequest("POST", reqUrl, body)
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", writer.FormDataContentType())
resp, err1 := client.Do(req)
if err1 != nil {
fmt.Println("error1", err1)
c.Err = model.NewAppError("EditComment", err1.Error(), nil, "", http.StatusBadRequest)
return
} else {
defer resp.Body.Close()
var bodyBytes []byte
bodyBytes, _ = ioutil.ReadAll(resp.Body)
resp.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
if resp.StatusCode != http.StatusOK {
fmt.Println("error2", resp.Body)
fbErr := facebookgraph.FacebookErrorFromJson(resp.Body)
c.Err = model.NewAppErrorFromFacebookError("EditComment", fbErr)
return
}
fmt.Println("UPLOAD VIDEO SUCCESS", resp.Body)
ReturnStatusOK(w)
}
}

这是上面代码的结构体:

type uploadVideoDataMessageAttachmentPayload struct {
IsReusable bool `json:"is_reusable"`
}
type uploadVideoDataMessageAttachment struct {
Type    string                                  `json:"type"`
Payload uploadVideoDataMessageAttachmentPayload `json:"payload"`
}
type uploadVideoDataMessage struct {
Attachment uploadVideoDataMessageAttachment `json:"attachment"`
}
type uploadVideoData struct {
Message uploadVideoDataMessage `json:"message"`
}
func (o uploadVideoData) ToJson() string {
b, _ := json.Marshal(o)
return string(b)
}
func (o uploadVideoDataMessage) ToJson() string {
b, _ := json.Marshal(o)
return string(b)
}

Facebook总是返回上述请求失败:

(#100) Upload attachment failure.

I was try CURL, and success:

curl 
-F 'message={"attachment":{"type":"video", "payload":{"is_reusable":true}}}' 
-F 'filedata=@/home/cong/Downloads/123.mp4;type=video/mp4' 
"https://graph.facebook.com/v10.0/me/message_attachments?access_token=EAAUxUcj3C64BADxxsm70hZCXTMO0eQHmSp..."
{"attachment_id":"382840319882695"}% 

谁能告诉我我错过了什么部分,以及如何使我的请求等同于CURL工作?

非常感谢!

感谢@sigkilled按照他的建议,我检查了subcode_error,发现这个错误是由于缺少匹配文件类型引起的,在我设置的文件类型之间:

_message := uploadVideoData{
Message: uploadVideoDataMessage{
Attachment: uploadVideoDataMessageAttachment{
Type: "video",
Payload: uploadVideoDataMessageAttachmentPayload{
IsReusable: true,
},
},
},
}

和Facebook服务器检测到的文件类型。然后我改变了视频";file"它成功了!

非常感谢你,你教我的不仅仅是这个问题!

最新更新