diff options
Diffstat (limited to 'vendor/github.com/SevereCloud/vksdk/v2/api')
10 files changed, 319 insertions, 36 deletions
diff --git a/vendor/github.com/SevereCloud/vksdk/v2/api/README.md b/vendor/github.com/SevereCloud/vksdk/v2/api/README.md index 770ab025..5d2d0c76 100644 --- a/vendor/github.com/SevereCloud/vksdk/v2/api/README.md +++ b/vendor/github.com/SevereCloud/vksdk/v2/api/README.md @@ -3,7 +3,7 @@ [![PkgGoDev](https://pkg.go.dev/badge/github.com/SevereCloud/vksdk/v2/api)](https://pkg.go.dev/github.com/SevereCloud/vksdk/v2/api) [![VK](https://img.shields.io/badge/developers-%234a76a8.svg?logo=VK&logoColor=white)](https://vk.com/dev/first_guide) -Данная библиотека поддерживает версию API **5.122**. +Данная библиотека поддерживает версию API **5.131**. ## Запросы @@ -80,6 +80,54 @@ if errors.As(err, &e) { Для Execute существует отдельная ошибка `ExecuteErrors` +### Поддержка MessagePack и zstd + +> Результат перехода с gzip (JSON) на zstd (msgpack): +> +> - в 7 раз быстрее сжатие (–1 мкс); +> - на 10% меньше размер данных (8 Кбайт вместо 9 Кбайт); +> - продуктовый эффект не статзначимый :( +> +> [Как мы отказались от JPEG, JSON, TCP и ускорили ВКонтакте в два раза](https://habr.com/ru/company/vk/blog/594633/) + +VK API способно возвращать ответ в виде [MessagePack](https://msgpack.org/). +Это эффективный формат двоичной сериализации, похожий на JSON, только быстрее +и меньше по размеру. + +ВНИМАНИЕ, C MessagePack НЕКОТОРЫЕ МЕТОДЫ МОГУТ ВОЗВРАЩАТЬ +СЛОМАННУЮ КОДИРОВКУ. + +Для сжатия, вместо классического gzip, можно использовать +[zstd](https://github.com/facebook/zstd). Сейчас vksdk поддерживает zstd без +словаря. Если кто знает как получать словарь, +[отпишитесь сюда](https://github.com/SevereCloud/vksdk/issues/180). + +```go +vk := api.NewVK(os.Getenv("USER_TOKEN")) + +method := "store.getStickersKeywords" +params := api.Params{ + "aliases": true, + "all_products": true, + "need_stickers": true, +} + +r, err := vk.Request(method, params) // Content-Length: 44758 +if err != nil { + log.Fatal(err) +} +log.Println("json:", len(r)) // json: 814231 + +vk.EnableMessagePack() // Включаем поддержку MessagePack +vk.EnableZstd() // Включаем поддержку zstd + +r, err = vk.Request(method, params) // Content-Length: 35755 +if err != nil { + log.Fatal(err) +} +log.Println("msgpack:", len(r)) // msgpack: 650775 +``` + ### Запрос любого метода Пример запроса [users.get](https://vk.com/dev/users.get) diff --git a/vendor/github.com/SevereCloud/vksdk/v2/api/ads.go b/vendor/github.com/SevereCloud/vksdk/v2/api/ads.go index 529e1be4..544143b3 100644 --- a/vendor/github.com/SevereCloud/vksdk/v2/api/ads.go +++ b/vendor/github.com/SevereCloud/vksdk/v2/api/ads.go @@ -1,9 +1,11 @@ package api // import "github.com/SevereCloud/vksdk/v2/api" import ( + "bytes" "encoding/json" "github.com/SevereCloud/vksdk/v2/object" + "github.com/vmihailenco/msgpack/v5" ) // AdsAddOfficeUsersItem struct. @@ -21,6 +23,23 @@ func (r *AdsAddOfficeUsersItem) UnmarshalJSON(data []byte) (err error) { return } +// DecodeMsgpack func. +func (r *AdsAddOfficeUsersItem) DecodeMsgpack(dec *msgpack.Decoder) error { + data, err := dec.DecodeRaw() + if err != nil { + return err + } + + if msgpack.Unmarshal(data, &r.OK) != nil { + d := msgpack.NewDecoder(bytes.NewReader(data)) + d.SetCustomStructTag("json") + + return d.Decode(&r.Error) + } + + return nil +} + // AdsAddOfficeUsersResponse struct. type AdsAddOfficeUsersResponse []AdsAddOfficeUsersItem @@ -349,7 +368,7 @@ func (vk *VK) AdsGetAdsLayout(params Params) (response AdsGetAdsLayoutResponse, // AdsGetMusiciansResponse struct. type AdsGetMusiciansResponse struct { - Items []object.BaseObjectWithName + Items []object.AdsMusician } // AdsGetMusicians returns a list of musicians. diff --git a/vendor/github.com/SevereCloud/vksdk/v2/api/api.go b/vendor/github.com/SevereCloud/vksdk/v2/api/api.go index 56da7784..760bc7e0 100644 --- a/vendor/github.com/SevereCloud/vksdk/v2/api/api.go +++ b/vendor/github.com/SevereCloud/vksdk/v2/api/api.go @@ -7,9 +7,11 @@ package api // import "github.com/SevereCloud/vksdk/v2/api" import ( "bytes" + "compress/gzip" "context" "encoding/json" "fmt" + "io" "mime" "net/http" "net/url" @@ -21,6 +23,8 @@ import ( "github.com/SevereCloud/vksdk/v2" "github.com/SevereCloud/vksdk/v2/internal" "github.com/SevereCloud/vksdk/v2/object" + "github.com/klauspost/compress/zstd" + "github.com/vmihailenco/msgpack/v5" ) // Api constants. @@ -91,6 +95,9 @@ type VK struct { UserAgent string Handler func(method string, params ...Params) (Response, error) + msgpack bool + zstd bool + mux sync.Mutex lastTime time.Time rps int @@ -98,9 +105,9 @@ type VK struct { // Response struct. type Response struct { - Response json.RawMessage `json:"response"` - Error Error `json:"error"` - ExecuteErrors ExecuteErrors `json:"execute_errors"` + Response object.RawMessage `json:"response"` + Error Error `json:"error"` + ExecuteErrors ExecuteErrors `json:"execute_errors"` } // NewVK returns a new VK. @@ -121,7 +128,7 @@ func NewVK(tokens ...string) *VK { vk.accessTokens = tokens vk.Version = Version - vk.Handler = vk.defaultHandler + vk.Handler = vk.DefaultHandler vk.MethodURL = MethodURL vk.Client = http.DefaultClient @@ -207,8 +214,8 @@ func buildQuery(sliceParams ...Params) (context.Context, url.Values) { return ctx, query } -// defaultHandler provides access to VK API methods. -func (vk *VK) defaultHandler(method string, sliceParams ...Params) (Response, error) { +// DefaultHandler provides access to VK API methods. +func (vk *VK) DefaultHandler(method string, sliceParams ...Params) (Response, error) { u := vk.MethodURL + method ctx, query := buildQuery(sliceParams...) attempt := 0 @@ -243,24 +250,52 @@ func (vk *VK) defaultHandler(method string, sliceParams ...Params) (Response, er return response, err } + acceptEncoding := "gzip" + if vk.zstd { + acceptEncoding = "zstd" + } + req.Header.Set("User-Agent", vk.UserAgent) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set("Accept-Encoding", acceptEncoding) + + var reader io.Reader + resp, err := vk.Client.Do(req) if err != nil { return response, err } - mediatype, _, _ := mime.ParseMediaType(resp.Header.Get("Content-Type")) - if mediatype != "application/json" { - _ = resp.Body.Close() - return response, &InvalidContentType{mediatype} + switch resp.Header.Get("Content-Encoding") { + case "zstd": + reader, _ = zstd.NewReader(resp.Body) + case "gzip": + reader, _ = gzip.NewReader(resp.Body) + default: + reader = resp.Body } - err = json.NewDecoder(resp.Body).Decode(&response) - if err != nil { + mediatype, _, _ := mime.ParseMediaType(resp.Header.Get("Content-Type")) + switch mediatype { + case "application/json": + err = json.NewDecoder(reader).Decode(&response) + if err != nil { + _ = resp.Body.Close() + return response, err + } + case "application/x-msgpack": + dec := msgpack.NewDecoder(reader) + dec.SetCustomStructTag("json") + + err = dec.Decode(&response) + if err != nil { + _ = resp.Body.Close() + return response, err + } + default: _ = resp.Body.Close() - return response, err + return response, &InvalidContentType{mediatype} } _ = resp.Body.Close() @@ -291,6 +326,10 @@ func (vk *VK) Request(method string, sliceParams ...Params) ([]byte, error) { sliceParams = append(sliceParams, reqParams) + if vk.msgpack { + method += ".msgpack" + } + resp, err := vk.Handler(method, sliceParams...) return resp.Response, err @@ -303,7 +342,32 @@ func (vk *VK) RequestUnmarshal(method string, obj interface{}, sliceParams ...Pa return err } - return json.Unmarshal(rawResponse, &obj) + if vk.msgpack { + dec := msgpack.NewDecoder(bytes.NewReader(rawResponse)) + dec.SetCustomStructTag("json") + + err = dec.Decode(&obj) + } else { + err = json.Unmarshal(rawResponse, &obj) + } + + return err +} + +// EnableMessagePack enable using MessagePack instead of JSON. +// +// THIS IS EXPERIMENTAL FUNCTION! Broken encoding returned in some methods. +// +// See https://msgpack.org +func (vk *VK) EnableMessagePack() { + vk.msgpack = true +} + +// EnableZstd enable using zstd instead of gzip. +// +// This not use dict. +func (vk *VK) EnableZstd() { + vk.zstd = true } func fmtReflectValue(value reflect.Value, depth int) string { diff --git a/vendor/github.com/SevereCloud/vksdk/v2/api/auth.go b/vendor/github.com/SevereCloud/vksdk/v2/api/auth.go index f927a6ff..62a08c07 100644 --- a/vendor/github.com/SevereCloud/vksdk/v2/api/auth.go +++ b/vendor/github.com/SevereCloud/vksdk/v2/api/auth.go @@ -1,5 +1,9 @@ package api // import "github.com/SevereCloud/vksdk/v2/api" +import ( + "github.com/SevereCloud/vksdk/v2/object" +) + // AuthCheckPhone checks a user's phone number for correctness. // // https://vk.com/dev/auth.checkPhone @@ -24,3 +28,58 @@ func (vk *VK) AuthRestore(params Params) (response AuthRestoreResponse, err erro err = vk.RequestUnmarshal("auth.restore", &response, params) return } + +// AuthGetProfileInfoBySilentTokenResponse struct. +type AuthGetProfileInfoBySilentTokenResponse struct { + Success []object.AuthSilentTokenProfile `json:"success"` + Errors []AuthSilentTokenError `json:"errors"` +} + +// AuthGetProfileInfoBySilentToken method. +// +// https://platform.vk.com/?p=DocsDashboard&docs=tokens_silent-token +func (vk *VK) AuthGetProfileInfoBySilentToken(params Params) (response AuthGetProfileInfoBySilentTokenResponse, err error) { + err = vk.RequestUnmarshal("auth.getProfileInfoBySilentToken", &response, params) + return +} + +// ExchangeSilentTokenSource call conditions exchangeSilentToken. +// +// 0 Unknown +// 1 Silent authentication +// 2 Auth by login and password +// 3 Extended registration +// 4 Auth by exchange token +// 5 Auth by exchange token on reset password +// 6 Auth by exchange token on unblock +// 7 Auth by exchange token on reset session +// 8 Auth by exchange token on change password +// 9 Finish phone validation on authentication +// 10 Auth by code +// 11 Auth by external oauth +// 12 Reactivation +// 15 Auth by SDK temporary access-token +type ExchangeSilentTokenSource int + +// AuthExchangeSilentAuthTokenResponse struct. +type AuthExchangeSilentAuthTokenResponse struct { + AccessToken string `json:"access_token"` + AccessTokenID string `json:"access_token_id"` + UserID int `json:"user_id"` + Phone string `json:"phone"` + PhoneValidated interface{} `json:"phone_validated"` + IsPartial bool `json:"is_partial"` + IsService bool `json:"is_service"` + AdditionalSignupRequired bool `json:"additional_signup_required"` + Email string `json:"email"` + Source ExchangeSilentTokenSource `json:"source"` + SourceDescription string `json:"source_description"` +} + +// AuthExchangeSilentAuthToken method. +// +// https://platform.vk.com/?p=DocsDashboard&docs=tokens_access-token +func (vk *VK) AuthExchangeSilentAuthToken(params Params) (response AuthExchangeSilentAuthTokenResponse, err error) { + err = vk.RequestUnmarshal("auth.exchangeSilentAuthToken", &response, params) + return +} diff --git a/vendor/github.com/SevereCloud/vksdk/v2/api/errors.go b/vendor/github.com/SevereCloud/vksdk/v2/api/errors.go index 03032aa6..aa6ea509 100644 --- a/vendor/github.com/SevereCloud/vksdk/v2/api/errors.go +++ b/vendor/github.com/SevereCloud/vksdk/v2/api/errors.go @@ -598,6 +598,12 @@ const ( // This user can't be added to the work chat, as they aren't an employe. ErrMessagesAccessWorkChat ErrorType = 967 + // Message cannot be forwarded. + ErrMessagesCantForwarded ErrorType = 969 + + // Cannot pin an expiring message. + ErrMessagesPinExpiringMessage ErrorType = 970 + // Invalid phone number. ErrParamPhone ErrorType = 1000 @@ -994,3 +1000,31 @@ func (e AdsError) Is(target error) bool { return false } + +// AuthSilentTokenError struct. +type AuthSilentTokenError struct { + Token string `json:"token"` + Code ErrorType `json:"code"` + Description string `json:"description"` +} + +// Error returns the description of a AuthSilentTokenError. +func (e AuthSilentTokenError) Error() string { + return "api: " + e.Description +} + +// Is unwraps its first argument sequentially looking for an error that matches +// the second. +func (e AuthSilentTokenError) Is(target error) bool { + var tError *AuthSilentTokenError + if errors.As(target, &tError) { + return e.Code == tError.Code && e.Description == tError.Description + } + + var tErrorType ErrorType + if errors.As(target, &tErrorType) { + return e.Code == tErrorType + } + + return false +} diff --git a/vendor/github.com/SevereCloud/vksdk/v2/api/execute.go b/vendor/github.com/SevereCloud/vksdk/v2/api/execute.go index cc52cd0d..1ee04cee 100644 --- a/vendor/github.com/SevereCloud/vksdk/v2/api/execute.go +++ b/vendor/github.com/SevereCloud/vksdk/v2/api/execute.go @@ -1,6 +1,11 @@ package api -import "encoding/json" +import ( + "bytes" + "encoding/json" + + "github.com/vmihailenco/msgpack/v5" +) // ExecuteWithArgs a universal method for calling a sequence of other methods // while saving and filtering interim results. @@ -26,9 +31,19 @@ func (vk *VK) ExecuteWithArgs(code string, params Params, obj interface{}) error return err } - jsonErr := json.Unmarshal(resp.Response, &obj) - if jsonErr != nil { - return jsonErr + var decoderErr error + + if vk.msgpack { + dec := msgpack.NewDecoder(bytes.NewReader(resp.Response)) + dec.SetCustomStructTag("json") + + decoderErr = dec.Decode(&obj) + } else { + decoderErr = json.Unmarshal(resp.Response, &obj) + } + + if decoderErr != nil { + return decoderErr } if resp.ExecuteErrors != nil { diff --git a/vendor/github.com/SevereCloud/vksdk/v2/api/market.go b/vendor/github.com/SevereCloud/vksdk/v2/api/market.go index 0bb35687..6b823818 100644 --- a/vendor/github.com/SevereCloud/vksdk/v2/api/market.go +++ b/vendor/github.com/SevereCloud/vksdk/v2/api/market.go @@ -20,6 +20,7 @@ func (vk *VK) MarketAdd(params Params) (response MarketAddResponse, err error) { // MarketAddAlbumResponse struct. type MarketAddAlbumResponse struct { MarketAlbumID int `json:"market_album_id"` // Album ID + AlbumsCount int `json:"albums_count"` } // MarketAddAlbum creates new collection of items. diff --git a/vendor/github.com/SevereCloud/vksdk/v2/api/messages.go b/vendor/github.com/SevereCloud/vksdk/v2/api/messages.go index 0a8f5613..a74266fe 100644 --- a/vendor/github.com/SevereCloud/vksdk/v2/api/messages.go +++ b/vendor/github.com/SevereCloud/vksdk/v2/api/messages.go @@ -1,7 +1,10 @@ package api // import "github.com/SevereCloud/vksdk/v2/api" import ( + "strconv" + "github.com/SevereCloud/vksdk/v2/object" + "github.com/vmihailenco/msgpack/v5" ) // MessagesAddChatUser adds a new user to a chat. @@ -31,11 +34,34 @@ func (vk *VK) MessagesCreateChat(params Params) (response int, err error) { // MessagesDeleteResponse struct. type MessagesDeleteResponse map[string]int +// DecodeMsgpack funcion. +func (resp *MessagesDeleteResponse) DecodeMsgpack(dec *msgpack.Decoder) error { + data, err := dec.DecodeRaw() + if err != nil { + return err + } + + var respMap map[int]int + + err = msgpack.Unmarshal(data, &respMap) + if err != nil { + return err + } + + *resp = make(MessagesDeleteResponse) + for key, val := range respMap { + (*resp)[strconv.Itoa(key)] = val + } + + return nil +} + // MessagesDelete deletes one or more messages. // // https://vk.com/dev/messages.delete func (vk *VK) MessagesDelete(params Params) (response MessagesDeleteResponse, err error) { err = vk.RequestUnmarshal("messages.delete", &response, params) + return } diff --git a/vendor/github.com/SevereCloud/vksdk/v2/api/photos.go b/vendor/github.com/SevereCloud/vksdk/v2/api/photos.go index 714705b4..d52cbeed 100644 --- a/vendor/github.com/SevereCloud/vksdk/v2/api/photos.go +++ b/vendor/github.com/SevereCloud/vksdk/v2/api/photos.go @@ -571,12 +571,13 @@ func (vk *VK) PhotosSaveOwnerCoverPhoto(params Params) (response PhotosSaveOwner // PhotosSaveOwnerPhotoResponse struct. type PhotosSaveOwnerPhotoResponse struct { - PhotoHash string `json:"photo_hash"` - PhotoSrc string `json:"photo_src"` - PhotoSrcBig string `json:"photo_src_big"` - PhotoSrcSmall string `json:"photo_src_small"` - Saved int `json:"saved"` - PostID int `json:"post_id"` + PhotoHash string `json:"photo_hash"` + // BUG(VK): returns false + // PhotoSrc string `json:"photo_src"` + // PhotoSrcBig string `json:"photo_src_big"` + // PhotoSrcSmall string `json:"photo_src_small"` + Saved int `json:"saved"` + PostID int `json:"post_id"` } // PhotosSaveOwnerPhoto saves a profile or community photo. diff --git a/vendor/github.com/SevereCloud/vksdk/v2/api/utils.go b/vendor/github.com/SevereCloud/vksdk/v2/api/utils.go index 63508fe2..965c26f2 100644 --- a/vendor/github.com/SevereCloud/vksdk/v2/api/utils.go +++ b/vendor/github.com/SevereCloud/vksdk/v2/api/utils.go @@ -1,9 +1,8 @@ package api // import "github.com/SevereCloud/vksdk/v2/api" import ( - "encoding/json" - "github.com/SevereCloud/vksdk/v2/object" + "github.com/vmihailenco/msgpack/v5" ) // UtilsCheckLinkResponse struct. @@ -89,17 +88,34 @@ func (vk *VK) UtilsGetShortLink(params Params) (response UtilsGetShortLinkRespon // UtilsResolveScreenNameResponse struct. type UtilsResolveScreenNameResponse object.UtilsDomainResolved +// UnmarshalJSON UtilsResolveScreenNameResponse. +// +// BUG(VK): UtilsResolveScreenNameResponse return []. +func (resp *UtilsResolveScreenNameResponse) UnmarshalJSON(data []byte) error { + var p object.UtilsDomainResolved + err := p.UnmarshalJSON(data) + + *resp = UtilsResolveScreenNameResponse(p) + + return err +} + +// DecodeMsgpack UtilsResolveScreenNameResponse. +// +// BUG(VK): UtilsResolveScreenNameResponse return []. +func (resp *UtilsResolveScreenNameResponse) DecodeMsgpack(dec *msgpack.Decoder) error { + var p object.UtilsDomainResolved + err := p.DecodeMsgpack(dec) + + *resp = UtilsResolveScreenNameResponse(p) + + return err +} + // UtilsResolveScreenName detects a type of object (e.g., user, community, application) and its ID by screen name. // // https://vk.com/dev/utils.resolveScreenName func (vk *VK) UtilsResolveScreenName(params Params) (response UtilsResolveScreenNameResponse, err error) { - rawResponse, err := vk.Request("utils.resolveScreenName", params) - // Если короткое имя screen_name не занято, то будет возвращён пустой объект. - if err != nil || string(rawResponse) == "[]" { - return - } - - err = json.Unmarshal(rawResponse, &response) - + err = vk.RequestUnmarshal("utils.resolveScreenName", &response, params) return } |