package api // import "github.com/SevereCloud/vksdk/v2/api" import ( "bytes" "encoding/json" "io" "mime/multipart" "github.com/SevereCloud/vksdk/v2/object" ) // UploadFile uploading file. func (vk *VK) UploadFile(url string, file io.Reader, fieldname, filename string) (bodyContent []byte, err error) { body := new(bytes.Buffer) writer := multipart.NewWriter(body) part, err := writer.CreateFormFile(fieldname, filename) if err != nil { return } _, err = io.Copy(part, file) if err != nil { return } contentType := writer.FormDataContentType() _ = writer.Close() resp, err := vk.Client.Post(url, contentType, body) if err != nil { return } defer resp.Body.Close() bodyContent, err = io.ReadAll(resp.Body) return } // uploadPhoto uploading Photos into Album. // // Supported formats: JPG, PNG, GIF. // // Limits: width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) uploadPhoto(params Params, file io.Reader) (response PhotosSaveResponse, err error) { uploadServer, err := vk.PhotosGetUploadServer(params) if err != nil { return } bodyContent, err := vk.UploadFile(uploadServer.UploadURL, file, "file1", "file1.jpeg") if err != nil { return } var handler object.PhotosPhotoUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return } response, err = vk.PhotosSave(Params{ "server": handler.Server, "photos_list": handler.PhotosList, "aid": handler.AID, "hash": handler.Hash, "album_id": params["album_id"], "group_id": params["group_id"], }) return } // UploadPhoto uploading Photos into User Album. // // Supported formats: JPG, PNG, GIF. // // Limits: width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) UploadPhoto(albumID int, file io.Reader) (response PhotosSaveResponse, err error) { response, err = vk.uploadPhoto(Params{ "album_id": albumID, }, file) return } // UploadPhotoGroup uploading Photos into Group Album. // // Supported formats: JPG, PNG, GIF. // // Limits: width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) UploadPhotoGroup(groupID, albumID int, file io.Reader) (response PhotosSaveResponse, err error) { response, err = vk.uploadPhoto(Params{ "album_id": albumID, "group_id": groupID, }, file) return } // uploadWallPhoto uploading Photos on Wall. // // Supported formats: JPG, PNG, GIF. // // Limits: width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) uploadWallPhoto(params Params, file io.Reader) (response PhotosSaveWallPhotoResponse, err error) { uploadServer, err := vk.PhotosGetWallUploadServer(params) if err != nil { return } bodyContent, err := vk.UploadFile(uploadServer.UploadURL, file, "photo", "photo.jpeg") if err != nil { return } var handler object.PhotosWallUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return } response, err = vk.PhotosSaveWallPhoto(Params{ "server": handler.Server, "photo": handler.Photo, "hash": handler.Hash, "group_id": params["group_id"], }) return } // UploadWallPhoto uploading Photos on User Wall. // // Supported formats: JPG, PNG, GIF. // // Limits: width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) UploadWallPhoto(file io.Reader) (response PhotosSaveWallPhotoResponse, err error) { response, err = vk.uploadWallPhoto(Params{}, file) return } // UploadGroupWallPhoto uploading Photos on Group Wall. // // Supported formats: JPG, PNG, GIF. // // Limits: width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) UploadGroupWallPhoto(groupID int, file io.Reader) (response PhotosSaveWallPhotoResponse, err error) { response, err = vk.uploadWallPhoto(Params{ "group_id": groupID, }, file) return } // uploadOwnerPhoto uploading Photos into User Profile or Community // To upload a photo to a community send its negative id in the owner_id parameter. // // Following parameters can be sent in addition: // squareCrop in x,y,w (no quotes) format where x and y are the coordinates of // the preview upper-right corner and w is square side length. // That will create a square preview for a photo. // // Supported formats: JPG, PNG, GIF. // // Limits: size not less than 200x200px, aspect ratio from 0.25 to 3, // width+height not more than 14000 px, file size up to 50 Mb. func (vk *VK) uploadOwnerPhoto(params Params, squareCrop string, file io.Reader) ( response PhotosSaveOwnerPhotoResponse, err error, ) { uploadServer, err := vk.PhotosGetOwnerPhotoUploadServer(params) if err != nil { return response, err } body := new(bytes.Buffer) writer := multipart.NewWriter(body) part, err := writer.CreateFormFile("photo", "photo.jpeg") if err != nil { return response, err } _, err = io.Copy(part, file) if err != nil { return response, err } contentType := writer.FormDataContentType() if squareCrop != "" { err = writer.WriteField("_square_crop", squareCrop) if err != nil { return response, err } } _ = writer.Close() resp, err := vk.Client.Post(uploadServer.UploadURL, contentType, body) if err != nil { return response, err } defer resp.Body.Close() bodyContent, err := io.ReadAll(resp.Body) if err != nil { return response, err } var handler object.PhotosOwnerUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return response, err } response, err = vk.PhotosSaveOwnerPhoto(Params{ "server": handler.Server, "photo": handler.Photo, "hash": handler.Hash, }) return response, err } // UploadUserPhoto uploading Photos into User Profile. // // Supported formats: JPG, PNG, GIF. // // Limits: size not less than 200x200px, aspect ratio from 0.25 to 3, // width+height not more than 14000 px, file size up to 50 Mb. func (vk *VK) UploadUserPhoto(file io.Reader) (response PhotosSaveOwnerPhotoResponse, err error) { response, err = vk.uploadOwnerPhoto(Params{}, "", file) return } // UploadOwnerPhoto uploading Photos into User Profile or Community // To upload a photo to a community send its negative id in the owner_id parameter. // // Following parameters can be sent in addition: // squareCrop in x,y,w (no quotes) format where x and y are the coordinates of // the preview upper-right corner and w is square side length. // That will create a square preview for a photo. // // Supported formats: JPG, PNG, GIF. // // Limits: size not less than 200x200px, aspect ratio from 0.25 to 3, // width+height not more than 14000 px, file size up to 50 Mb. func (vk *VK) UploadOwnerPhoto(ownerID int, squareCrop string, file io.Reader) ( response PhotosSaveOwnerPhotoResponse, err error, ) { response, err = vk.uploadOwnerPhoto(Params{ "owner_id": ownerID, }, squareCrop, file) return } // UploadMessagesPhoto uploading Photos into a Private Message. // // Supported formats: JPG, PNG, GIF. // // Limits: width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) UploadMessagesPhoto(peerID int, file io.Reader) (response PhotosSaveMessagesPhotoResponse, err error) { uploadServer, err := vk.PhotosGetMessagesUploadServer(Params{ "peer_id": peerID, }) if err != nil { return } bodyContent, err := vk.UploadFile(uploadServer.UploadURL, file, "photo", "photo.jpeg") if err != nil { return } var handler object.PhotosMessageUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return } response, err = vk.PhotosSaveMessagesPhoto(Params{ "server": handler.Server, "photo": handler.Photo, "hash": handler.Hash, }) return } // uploadChatPhoto uploading a Main Photo to a Group Chat. // // Supported formats: JPG, PNG, GIF. // // Limits: size not less than 200x200px, // width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) uploadChatPhoto(params Params, file io.Reader) (response MessagesSetChatPhotoResponse, err error) { uploadServer, err := vk.PhotosGetChatUploadServer(params) if err != nil { return } bodyContent, err := vk.UploadFile(uploadServer.UploadURL, file, "file", "photo.jpeg") if err != nil { return } var handler object.PhotosChatUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return } response, err = vk.MessagesSetChatPhoto(Params{ "file": handler.Response, }) return } // UploadChatPhoto uploading a Main Photo to a Group Chat without crop. // // Supported formats: JPG, PNG, GIF. // // Limits: size not less than 200x200px, // width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) UploadChatPhoto(chatID int, file io.Reader) (response MessagesSetChatPhotoResponse, err error) { response, err = vk.uploadChatPhoto(Params{ "chat_id": chatID, }, file) return } // UploadChatPhotoCrop uploading a Main Photo to a Group Chat with crop. // // Supported formats: JPG, PNG, GIF. // // Limits: size not less than 200x200px, // width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) UploadChatPhotoCrop(chatID, cropX, cropY, cropWidth int, file io.Reader) ( response MessagesSetChatPhotoResponse, err error, ) { response, err = vk.uploadChatPhoto(Params{ "chat_id": chatID, "crop_x": cropX, "crop_y": cropY, "crop_width": cropWidth, }, file) return } // uploadMarketPhoto uploading a Market Item Photo. // // Supported formats: JPG, PNG, GIF. // // Limits: size not less than 400x400px, // width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) uploadMarketPhoto(params Params, file io.Reader) (response PhotosSaveMarketPhotoResponse, err error) { uploadServer, err := vk.PhotosGetMarketUploadServer(params) if err != nil { return } bodyContent, err := vk.UploadFile(uploadServer.UploadURL, file, "file", "photo.jpeg") if err != nil { return } var handler object.PhotosMarketUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return } response, err = vk.PhotosSaveMarketPhoto(Params{ "group_id": params["group_id"], "server": handler.Server, "photo": handler.Photo, "hash": handler.Hash, "crop_data": handler.CropData, "crop_hash": handler.CropHash, }) return } // UploadMarketPhoto uploading a Market Item Photo without crop. // // Supported formats: JPG, PNG, GIF. // // Limits: size not less than 400x400px, // width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) UploadMarketPhoto(groupID int, mainPhoto bool, file io.Reader) ( response PhotosSaveMarketPhotoResponse, err error, ) { response, err = vk.uploadMarketPhoto(Params{ "group_id": groupID, "main_photo": mainPhoto, }, file) return } // UploadMarketPhotoCrop uploading a Market Item Photo with crop. // // Supported formats: JPG, PNG, GIF. // // Limits: size not less than 400x400px, // width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) UploadMarketPhotoCrop(groupID, cropX, cropY, cropWidth int, file io.Reader) ( response PhotosSaveMarketPhotoResponse, err error, ) { response, err = vk.uploadMarketPhoto(Params{ "group_id": groupID, "main_photo": true, "crop_x": cropX, "crop_y": cropY, "crop_width": cropWidth, }, file) return } // UploadMarketAlbumPhoto uploading a Main Photo to a Group Chat. // // Supported formats: JPG, PNG, GIF. // // Limits: size not less than 1280x720px, // width+height not more than 14000 px, file size up to 50 Mb, // aspect ratio of at least 1:20. func (vk *VK) UploadMarketAlbumPhoto(groupID int, file io.Reader) ( response PhotosSaveMarketAlbumPhotoResponse, err error, ) { uploadServer, err := vk.PhotosGetMarketAlbumUploadServer(Params{ "group_id": groupID, }) if err != nil { return } bodyContent, err := vk.UploadFile(uploadServer.UploadURL, file, "file", "photo.jpeg") if err != nil { return } var handler object.PhotosMarketAlbumUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return } return vk.PhotosSaveMarketAlbumPhoto(Params{ "group_id": groupID, "server": handler.Server, "photo": handler.Photo, "hash": handler.Hash, }) } // UploadVideo uploading Video Files. // // Supported formats: AVI, MP4, 3GP, MPEG, MOV, FLV, WMV. func (vk *VK) UploadVideo(params Params, file io.Reader) (response VideoSaveResponse, err error) { response, err = vk.VideoSave(params) if err != nil { return } bodyContent, err := vk.UploadFile(response.UploadURL, file, "video_file", "video.mp4") if err != nil { return } var videoUploadError UploadError err = json.Unmarshal(bodyContent, &videoUploadError) if err != nil { return } if videoUploadError.Code != 0 { err = &videoUploadError } return } // uploadDoc uploading Documents. // // Supported formats: any formats excepting mp3 and executable files. // // Limits: file size up to 200 MB. func (vk *VK) uploadDoc(url, title, tags string, file io.Reader) (response DocsSaveResponse, err error) { bodyContent, err := vk.UploadFile(url, file, "file", title) if err != nil { return response, err } var docUploadError UploadError err = json.Unmarshal(bodyContent, &docUploadError) if err != nil { return response, err } if docUploadError.Err != "" { err = &docUploadError return response, err } var handler object.DocsDocUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return response, err } response, err = vk.DocsSave(Params{ "file": handler.File, "title": title, "tags": tags, }) return response, err } // UploadDoc uploading Documents. // // Supported formats: any formats excepting mp3 and executable files. // // Limits: file size up to 200 MB. func (vk *VK) UploadDoc(title, tags string, file io.Reader) (response DocsSaveResponse, err error) { uploadServer, err := vk.DocsGetUploadServer(nil) if err != nil { return response, err } response, err = vk.uploadDoc(uploadServer.UploadURL, title, tags, file) return response, err } // UploadGroupDoc uploading Documents into Community. // // Supported formats: any formats excepting mp3 and executable files. // // Limits: file size up to 200 MB. func (vk *VK) UploadGroupDoc(groupID int, title, tags string, file io.Reader) (response DocsSaveResponse, err error) { uploadServer, err := vk.DocsGetUploadServer(Params{ "group_id": groupID, }) if err != nil { return response, err } response, err = vk.uploadDoc(uploadServer.UploadURL, title, tags, file) return response, err } // UploadWallDoc uploading Documents on Wall. // // Supported formats: any formats excepting mp3 and executable files. // // Limits: file size up to 200 MB. func (vk *VK) UploadWallDoc(title, tags string, file io.Reader) (response DocsSaveResponse, err error) { uploadServer, err := vk.DocsGetWallUploadServer(nil) if err != nil { return response, err } response, err = vk.uploadDoc(uploadServer.UploadURL, title, tags, file) return response, err } // UploadGroupWallDoc uploading Documents on Group Wall. // // Supported formats: any formats excepting mp3 and executable files. // // Limits: file size up to 200 MB. func (vk *VK) UploadGroupWallDoc(groupID int, title, tags string, file io.Reader) ( response DocsSaveResponse, err error, ) { uploadServer, err := vk.DocsGetWallUploadServer(Params{ "group_id": groupID, }) if err != nil { return response, err } response, err = vk.uploadDoc(uploadServer.UploadURL, title, tags, file) return response, err } // UploadMessagesDoc uploading Documents into a Private Message. // // Supported formats: any formats excepting mp3 and executable files. // // Limits: file size up to 200 MB. func (vk *VK) UploadMessagesDoc(peerID int, typeDoc, title, tags string, file io.Reader) ( response DocsSaveResponse, err error, ) { uploadServer, err := vk.DocsGetMessagesUploadServer(Params{ "peer_id": peerID, "type": typeDoc, }) if err != nil { return response, err } response, err = vk.uploadDoc(uploadServer.UploadURL, title, tags, file) return response, err } // UploadOwnerCoverPhoto uploading a Main Photo to a Group Chat. // // Supported formats: JPG, PNG, GIF. // // Limits: minimum photo size 795x200px, width+height not more than 14000px, // file size up to 50 MB. Recommended size: 1590x400px. func (vk *VK) UploadOwnerCoverPhoto(groupID, cropX, cropY, cropX2, cropY2 int, file io.Reader) ( response PhotosSaveOwnerCoverPhotoResponse, err error, ) { uploadServer, err := vk.PhotosGetOwnerCoverPhotoUploadServer(Params{ "group_id": groupID, "crop_x": cropX, "crop_y": cropY, "crop_x2": cropX2, "crop_y2": cropY2, }) if err != nil { return response, err } bodyContent, err := vk.UploadFile(uploadServer.UploadURL, file, "photo", "photo.jpeg") if err != nil { return response, err } var handler object.PhotosOwnerUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return response, err } return vk.PhotosSaveOwnerCoverPhoto(Params{ "photo": handler.Photo, "hash": handler.Hash, }) } // UploadStories struct. type UploadStories struct { UploadResult string `json:"upload_result"` Sig string `json:"_sig"` } type rawUploadStoriesPhoto struct { Response UploadStories `json:"response"` Error struct { ErrorCode int `json:"error_code"` Type string `json:"type"` } `json:"error"` } type rawUploadStoriesVideo struct { Response UploadStories `json:"response"` UploadError } // UploadStoriesPhoto uploading Story. // // Supported formats: JPG, PNG, GIF. // Limits: sum of with and height no more than 14000px, file size no // more than 10 MB. Video format: h264 video, aac audio, // maximum 720х1280, 30fps. // // https://dev.vk.com/method/stories.getPhotoUploadServer func (vk *VK) UploadStoriesPhoto(params Params, file io.Reader) (response StoriesSaveResponse, err error) { uploadServer, err := vk.StoriesGetPhotoUploadServer(params) if err != nil { return response, err } bodyContent, err := vk.UploadFile(uploadServer.UploadURL, file, "file", "file.jpeg") if err != nil { return response, err } var handler rawUploadStoriesPhoto err = json.Unmarshal(bodyContent, &handler) if err != nil { return response, err } if handler.Error.ErrorCode != 0 { err = &UploadError{ Code: handler.Error.ErrorCode, Err: handler.Error.Type, } return response, err } response, err = vk.StoriesSave(Params{ "upload_results": handler.Response.UploadResult, }) return response, err } // UploadStoriesVideo uploading Story. // // Video format: h264 video, aac audio, maximum 720х1280, 30fps. func (vk *VK) UploadStoriesVideo(params Params, file io.Reader) (response StoriesSaveResponse, err error) { uploadServer, err := vk.StoriesGetVideoUploadServer(params) if err != nil { return response, err } bodyContent, err := vk.UploadFile(uploadServer.UploadURL, file, "video_file", "video.mp4") if err != nil { return response, err } var handler rawUploadStoriesVideo err = json.Unmarshal(bodyContent, &handler) if err != nil { return response, err } if handler.UploadError.Code != 0 { return response, &handler.UploadError } response, err = vk.StoriesSave(Params{ "upload_results": handler.Response.UploadResult, }) return response, err } // uploadPollsPhoto uploading a Poll Photo. // // Supported formats: JPG, PNG, GIF. // // Limits: minimum photo size 795x200px, width+height not more than 14000px, // file size up to 50 MB. Recommended size: 1590x400px. func (vk *VK) uploadPollsPhoto(params Params, file io.Reader) (response PollsSavePhotoResponse, err error) { uploadServer, err := vk.PollsGetPhotoUploadServer(params) if err != nil { return response, err } bodyContent, err := vk.UploadFile(uploadServer.UploadURL, file, "photo", "photo.jpeg") if err != nil { return response, err } var handler object.PollsPhotoUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return response, err } response, err = vk.PollsSavePhoto(Params{ "photo": handler.Photo, "hash": handler.Hash, }) return response, err } // UploadPollsPhoto uploading a Poll Photo. // // Supported formats: JPG, PNG, GIF. // // Limits: minimum photo size 795x200px, width+height not more than 14000px, // file size up to 50 MB. Recommended size: 1590x400px. func (vk *VK) UploadPollsPhoto(file io.Reader) (response PollsSavePhotoResponse, err error) { return vk.uploadPollsPhoto(Params{}, file) } // UploadOwnerPollsPhoto uploading a Poll Photo. // // Supported formats: JPG, PNG, GIF. // // Limits: minimum photo size 795x200px, width+height not more than 14000px, // file size up to 50 MB. Recommended size: 1590x400px. func (vk *VK) UploadOwnerPollsPhoto(ownerID int, file io.Reader) (response PollsSavePhotoResponse, err error) { return vk.uploadPollsPhoto(Params{"owner_id": ownerID}, file) } type uploadPrettyCardsPhotoHandler struct { Photo string `json:"photo"` ErrCode int `json:"errcode"` } // UploadPrettyCardsPhoto uploading a Pretty Card Photo. // // Supported formats: JPG, PNG, GIF. func (vk *VK) UploadPrettyCardsPhoto(file io.Reader) (response string, err error) { uploadURL, err := vk.PrettyCardsGetUploadURL(nil) if err != nil { return response, err } bodyContent, err := vk.UploadFile(uploadURL, file, "file", "photo.jpg") if err != nil { return response, err } var handler uploadPrettyCardsPhotoHandler err = json.Unmarshal(bodyContent, &handler) if err != nil { return response, err } response = handler.Photo if handler.ErrCode != 0 { err = &UploadError{Code: handler.ErrCode} } return response, err } type uploadLeadFormsPhotoHandler struct { Photo string `json:"photo"` ErrCode int `json:"errcode"` } // UploadLeadFormsPhoto uploading a Pretty Card Photo. // // Supported formats: JPG, PNG, GIF. func (vk *VK) UploadLeadFormsPhoto(file io.Reader) (response string, err error) { uploadURL, err := vk.LeadFormsGetUploadURL(nil) if err != nil { return response, err } bodyContent, err := vk.UploadFile(uploadURL, file, "file", "photo.jpg") if err != nil { return response, err } var handler uploadLeadFormsPhotoHandler err = json.Unmarshal(bodyContent, &handler) if err != nil { return response, err } response = handler.Photo if handler.ErrCode != 0 { err = &UploadError{Code: handler.ErrCode} } return response, err } // UploadAppImage uploading a Image into App collection for community app widgets. func (vk *VK) UploadAppImage(imageType string, file io.Reader) (response object.AppWidgetsImage, err error) { uploadServer, err := vk.AppWidgetsGetAppImageUploadServer(Params{ "image_type": imageType, }) if err != nil { return response, err } bodyContent, err := vk.UploadFile(uploadServer.UploadURL, file, "image", "photo.jpeg") if err != nil { return response, err } var handler object.AppWidgetsAppImageUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return response, err } response, err = vk.AppWidgetsSaveAppImage(Params{ "image": handler.Image, "hash": handler.Hash, }) return response, err } // UploadGroupImage uploading a Image into Community collection for community app widgets. func (vk *VK) UploadGroupImage(imageType string, file io.Reader) (response object.AppWidgetsImage, err error) { uploadServer, err := vk.AppWidgetsGetGroupImageUploadServer(Params{ "image_type": imageType, }) if err != nil { return response, err } bodyContent, err := vk.UploadFile(uploadServer.UploadURL, file, "image", "photo.jpeg") if err != nil { return response, err } var handler object.AppWidgetsGroupImageUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return response, err } response, err = vk.AppWidgetsSaveGroupImage(Params{ "image": handler.Image, "hash": handler.Hash, }) return response, err } // UploadMarusiaPicture uploading picture. // // Limits: height not more than 600 px, // aspect ratio of at least 2:1. func (vk *VK) UploadMarusiaPicture(file io.Reader) (response MarusiaSavePictureResponse, err error) { uploadServer, err := vk.MarusiaGetPictureUploadLink(nil) if err != nil { return response, err } bodyContent, err := vk.UploadFile(uploadServer.PictureUploadLink, file, "photo", "photo.jpg") if err != nil { return response, err } var handler object.MarusiaPictureUploadResponse err = json.Unmarshal(bodyContent, &handler) if err != nil { return response, err } photo, _ := json.Marshal(handler.Photo) response, err = vk.MarusiaSavePicture(Params{ "server": handler.Server, "photo": string(photo), "hash": handler.Hash, }) return response, err } // UploadMarusiaAudio uploading audio. // // https://dev.vk.com/ru/marusia/media-api func (vk *VK) UploadMarusiaAudio(file io.Reader) (response MarusiaCreateAudioResponse, err error) { uploadServer, err := vk.MarusiaGetAudioUploadLink(nil) if err != nil { return response, err } bodyContent, err := vk.UploadFile(uploadServer.AudioUploadLink, file, "file", "audio.mp3") if err != nil { return response, err } response, err = vk.MarusiaCreateAudio(Params{ "audio_meta": string(bodyContent), }) return response, err }