2024-04-10 22:18:44 +03:00
/ *
2024-05-12 12:36:47 +03:00
* Monobank open API
*
* API для отримання інформації про виписки та стан особистого рахунку та рахунків ФОП . Для надання доступу потрібно пройти авторизацію у особистому кабінеті https : //api.monobank.ua/ та отримати токен для персонального використання. Якщо у вас є запитання щодо роботи API, запрошуємо до ком'юніті у [Telegram-групі](https://t.me/joinchat/FiAEWhDf-QzTqM4wzEtffw). API недоступне для клієнтів до 16 років, дані за дитячими рахунками доступні з батьківського акаунту. Якщо у вас є сервіс і ви хочете централізовано приєднатися до API для надання послуг клієнтам, потрібно підключитися до [API для провайдерів послуг](/docs/corporate.html), що має більше можливостей. Якщо дані клієнтів не будуть надходити на ваші сервери а б о ви робите сервіс для своєї родини, використання корпоративного API необов'язкове. Розробка бібліотек а б о програм, які будуть використовувати клієнти особисто (дані клієнта не будуть проходити че р eз вузли розробника), також не потребують використання корпоративного API. Це надасть змогу клієнтам monobank авторизуватись у вашому сервісі (наприклад, у фінансовому менеджері) для надання інформації про стан рахунку а б о виписки. У разі виявлення експлуатації цього API в якості корпоративного, банк залишає за собою право накласти санкції на компанію.
*
* API version : v2303
* Generated by : Swagger Codegen ( https : //github.com/swagger-api/swagger-codegen.git)
* /
2024-04-10 22:18:44 +03:00
package monobank
import (
"bytes"
"context"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/url"
"os"
"path/filepath"
"reflect"
"regexp"
"strconv"
"strings"
"time"
"unicode/utf8"
2024-05-12 12:36:47 +03:00
"golang.org/x/oauth2"
2024-04-10 22:18:44 +03:00
)
var (
2024-05-12 12:36:47 +03:00
jsonCheck = regexp . MustCompile ( "(?i:[application|text]/json)" )
xmlCheck = regexp . MustCompile ( "(?i:[application|text]/xml)" )
2024-04-10 22:18:44 +03:00
)
// APIClient manages communication with the Monobank open API API vv2303
// In most cases there should be only one, shared, APIClient.
type APIClient struct {
cfg * Configuration
common service // Reuse a single struct instead of allocating one for each service on the heap.
// API Services
2024-05-12 12:36:47 +03:00
Api * ApiService
2024-04-10 22:18:44 +03:00
}
type service struct {
client * APIClient
}
// NewAPIClient creates a new API client. Requires a userAgent string describing your application.
// optionally a custom http.Client to allow for advanced features such as caching.
func NewAPIClient ( cfg * Configuration ) * APIClient {
if cfg . HTTPClient == nil {
cfg . HTTPClient = http . DefaultClient
}
c := & APIClient { }
c . cfg = cfg
c . common . client = c
// API Services
2024-05-12 12:36:47 +03:00
c . Api = ( * ApiService ) ( & c . common )
2024-04-10 22:18:44 +03:00
return c
}
func atoi ( in string ) ( int , error ) {
return strconv . Atoi ( in )
}
// selectHeaderContentType select a content type from the available list.
func selectHeaderContentType ( contentTypes [ ] string ) string {
if len ( contentTypes ) == 0 {
return ""
}
if contains ( contentTypes , "application/json" ) {
return "application/json"
}
return contentTypes [ 0 ] // use the first content type specified in 'consumes'
}
// selectHeaderAccept join all accept types and return
func selectHeaderAccept ( accepts [ ] string ) string {
if len ( accepts ) == 0 {
return ""
}
if contains ( accepts , "application/json" ) {
return "application/json"
}
return strings . Join ( accepts , "," )
}
2024-05-12 12:36:47 +03:00
// contains is a case insenstive match, finding needle in a haystack
2024-04-10 22:18:44 +03:00
func contains ( haystack [ ] string , needle string ) bool {
for _ , a := range haystack {
2024-05-12 12:36:47 +03:00
if strings . ToLower ( a ) == strings . ToLower ( needle ) {
2024-04-10 22:18:44 +03:00
return true
}
}
return false
}
// Verify optional parameters are of the correct type.
func typeCheckParameter ( obj interface { } , expected string , name string ) error {
// Make sure there is an object.
if obj == nil {
return nil
}
// Check the type is as expected.
if reflect . TypeOf ( obj ) . String ( ) != expected {
2024-05-12 12:36:47 +03:00
return fmt . Errorf ( "Expected %s to be of type %s but received %s." , name , expected , reflect . TypeOf ( obj ) . String ( ) )
2024-04-10 22:18:44 +03:00
}
return nil
}
2024-05-12 12:36:47 +03:00
// parameterToString convert interface{} parameters to string, using a delimiter if format is provided.
func parameterToString ( obj interface { } , collectionFormat string ) string {
var delimiter string
2024-04-10 22:18:44 +03:00
2024-05-12 12:36:47 +03:00
switch collectionFormat {
case "pipes" :
delimiter = "|"
case "ssv" :
delimiter = " "
case "tsv" :
delimiter = "\t"
case "csv" :
delimiter = ","
2024-04-10 22:18:44 +03:00
}
2024-05-12 12:36:47 +03:00
if reflect . TypeOf ( obj ) . Kind ( ) == reflect . Slice {
return strings . Trim ( strings . Replace ( fmt . Sprint ( obj ) , " " , delimiter , - 1 ) , "[]" )
2024-04-10 22:18:44 +03:00
}
2024-05-12 12:36:47 +03:00
return fmt . Sprintf ( "%v" , obj )
2024-04-10 22:18:44 +03:00
}
// callAPI do the request.
func ( c * APIClient ) callAPI ( request * http . Request ) ( * http . Response , error ) {
2024-05-12 12:36:47 +03:00
return c . cfg . HTTPClient . Do ( request )
2024-04-10 22:18:44 +03:00
}
2024-05-12 12:36:47 +03:00
// Change base path to allow switching to mocks
func ( c * APIClient ) ChangeBasePath ( path string ) {
c . cfg . BasePath = path
2024-04-10 22:18:44 +03:00
}
// prepareRequest build the request
func ( c * APIClient ) prepareRequest (
ctx context . Context ,
path string , method string ,
postBody interface { } ,
headerParams map [ string ] string ,
queryParams url . Values ,
formParams url . Values ,
2024-05-12 12:36:47 +03:00
fileName string ,
fileBytes [ ] byte ) ( localVarRequest * http . Request , err error ) {
2024-04-10 22:18:44 +03:00
var body * bytes . Buffer
// Detect postBody type and post.
if postBody != nil {
contentType := headerParams [ "Content-Type" ]
if contentType == "" {
contentType = detectContentType ( postBody )
headerParams [ "Content-Type" ] = contentType
}
body , err = setBody ( postBody , contentType )
if err != nil {
return nil , err
}
}
// add form parameters and file if available.
2024-05-12 12:36:47 +03:00
if strings . HasPrefix ( headerParams [ "Content-Type" ] , "multipart/form-data" ) && len ( formParams ) > 0 || ( len ( fileBytes ) > 0 && fileName != "" ) {
2024-04-10 22:18:44 +03:00
if body != nil {
return nil , errors . New ( "Cannot specify postBody and multipart form at the same time." )
}
body = & bytes . Buffer { }
w := multipart . NewWriter ( body )
for k , v := range formParams {
for _ , iv := range v {
if strings . HasPrefix ( k , "@" ) { // file
err = addFile ( w , k [ 1 : ] , iv )
if err != nil {
return nil , err
}
} else { // form value
w . WriteField ( k , iv )
}
}
}
2024-05-12 12:36:47 +03:00
if len ( fileBytes ) > 0 && fileName != "" {
w . Boundary ( )
//_, fileNm := filepath.Split(fileName)
part , err := w . CreateFormFile ( "file" , filepath . Base ( fileName ) )
if err != nil {
return nil , err
}
_ , err = part . Write ( fileBytes )
if err != nil {
return nil , err
2024-04-10 22:18:44 +03:00
}
2024-05-12 12:36:47 +03:00
// Set the Boundary in the Content-Type
headerParams [ "Content-Type" ] = w . FormDataContentType ( )
2024-04-10 22:18:44 +03:00
}
// Set Content-Length
headerParams [ "Content-Length" ] = fmt . Sprintf ( "%d" , body . Len ( ) )
w . Close ( )
}
if strings . HasPrefix ( headerParams [ "Content-Type" ] , "application/x-www-form-urlencoded" ) && len ( formParams ) > 0 {
if body != nil {
return nil , errors . New ( "Cannot specify postBody and x-www-form-urlencoded form at the same time." )
}
body = & bytes . Buffer { }
body . WriteString ( formParams . Encode ( ) )
// Set Content-Length
headerParams [ "Content-Length" ] = fmt . Sprintf ( "%d" , body . Len ( ) )
}
// Setup path and query parameters
url , err := url . Parse ( path )
if err != nil {
return nil , err
}
// Adding Query Param
query := url . Query ( )
for k , v := range queryParams {
for _ , iv := range v {
query . Add ( k , iv )
}
}
// Encode the parameters.
2024-05-12 12:36:47 +03:00
url . RawQuery = query . Encode ( )
2024-04-10 22:18:44 +03:00
// Generate a new request
if body != nil {
localVarRequest , err = http . NewRequest ( method , url . String ( ) , body )
} else {
localVarRequest , err = http . NewRequest ( method , url . String ( ) , nil )
}
if err != nil {
return nil , err
}
// add header parameters, if any
if len ( headerParams ) > 0 {
headers := http . Header { }
for h , v := range headerParams {
2024-05-12 12:36:47 +03:00
headers . Set ( h , v )
2024-04-10 22:18:44 +03:00
}
localVarRequest . Header = headers
}
2024-05-12 12:36:47 +03:00
// Override request host, if applicable
if c . cfg . Host != "" {
localVarRequest . Host = c . cfg . Host
}
2024-04-10 22:18:44 +03:00
// Add the user agent to the request.
localVarRequest . Header . Add ( "User-Agent" , c . cfg . UserAgent )
if ctx != nil {
// add context to the request
localVarRequest = localVarRequest . WithContext ( ctx )
// Walk through any authentication.
2024-05-12 12:36:47 +03:00
// OAuth2 authentication
if tok , ok := ctx . Value ( ContextOAuth2 ) . ( oauth2 . TokenSource ) ; ok {
// We were able to grab an oauth2 token from the context
var latestToken * oauth2 . Token
if latestToken , err = tok . Token ( ) ; err != nil {
return nil , err
}
latestToken . SetAuthHeader ( localVarRequest )
}
// Basic HTTP Authentication
if auth , ok := ctx . Value ( ContextBasicAuth ) . ( BasicAuth ) ; ok {
localVarRequest . SetBasicAuth ( auth . UserName , auth . Password )
}
// AccessToken Authentication
if auth , ok := ctx . Value ( ContextAccessToken ) . ( string ) ; ok {
localVarRequest . Header . Add ( "Authorization" , "Bearer " + auth )
}
2024-04-10 22:18:44 +03:00
}
for header , value := range c . cfg . DefaultHeader {
localVarRequest . Header . Add ( header , value )
}
2024-05-12 12:36:47 +03:00
2024-04-10 22:18:44 +03:00
return localVarRequest , nil
}
func ( c * APIClient ) decode ( v interface { } , b [ ] byte , contentType string ) ( err error ) {
2024-05-12 12:36:47 +03:00
if strings . Contains ( contentType , "application/xml" ) {
2024-04-10 22:18:44 +03:00
if err = xml . Unmarshal ( b , v ) ; err != nil {
return err
}
return nil
2024-05-12 12:36:47 +03:00
} else if strings . Contains ( contentType , "application/json" ) {
if err = json . Unmarshal ( b , v ) ; err != nil {
2024-04-10 22:18:44 +03:00
return err
}
return nil
}
return errors . New ( "undefined response type" )
}
// Add a file to the multipart request
func addFile ( w * multipart . Writer , fieldName , path string ) error {
2024-05-12 12:36:47 +03:00
file , err := os . Open ( path )
2024-04-10 22:18:44 +03:00
if err != nil {
return err
}
2024-05-12 12:36:47 +03:00
defer file . Close ( )
2024-04-10 22:18:44 +03:00
part , err := w . CreateFormFile ( fieldName , filepath . Base ( path ) )
if err != nil {
return err
}
_ , err = io . Copy ( part , file )
return err
}
// Prevent trying to import "fmt"
func reportError ( format string , a ... interface { } ) error {
return fmt . Errorf ( format , a ... )
}
// Set request body from an interface{}
func setBody ( body interface { } , contentType string ) ( bodyBuf * bytes . Buffer , err error ) {
if bodyBuf == nil {
bodyBuf = & bytes . Buffer { }
}
if reader , ok := body . ( io . Reader ) ; ok {
_ , err = bodyBuf . ReadFrom ( reader )
} else if b , ok := body . ( [ ] byte ) ; ok {
_ , err = bodyBuf . Write ( b )
} else if s , ok := body . ( string ) ; ok {
_ , err = bodyBuf . WriteString ( s )
} else if s , ok := body . ( * string ) ; ok {
_ , err = bodyBuf . WriteString ( * s )
2024-05-12 12:36:47 +03:00
} else if jsonCheck . MatchString ( contentType ) {
2024-04-10 22:18:44 +03:00
err = json . NewEncoder ( bodyBuf ) . Encode ( body )
2024-05-12 12:36:47 +03:00
} else if xmlCheck . MatchString ( contentType ) {
xml . NewEncoder ( bodyBuf ) . Encode ( body )
2024-04-10 22:18:44 +03:00
}
if err != nil {
return nil , err
}
if bodyBuf . Len ( ) == 0 {
2024-05-12 12:36:47 +03:00
err = fmt . Errorf ( "Invalid body type %s\n" , contentType )
2024-04-10 22:18:44 +03:00
return nil , err
}
return bodyBuf , nil
}
// detectContentType method is used to figure out `Request.Body` content type for request header
func detectContentType ( body interface { } ) string {
contentType := "text/plain; charset=utf-8"
kind := reflect . TypeOf ( body ) . Kind ( )
switch kind {
case reflect . Struct , reflect . Map , reflect . Ptr :
contentType = "application/json; charset=utf-8"
case reflect . String :
contentType = "text/plain; charset=utf-8"
default :
if b , ok := body . ( [ ] byte ) ; ok {
contentType = http . DetectContentType ( b )
} else if kind == reflect . Slice {
contentType = "application/json; charset=utf-8"
}
}
return contentType
}
// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go
type cacheControl map [ string ] string
func parseCacheControl ( headers http . Header ) cacheControl {
cc := cacheControl { }
ccHeader := headers . Get ( "Cache-Control" )
for _ , part := range strings . Split ( ccHeader , "," ) {
part = strings . Trim ( part , " " )
if part == "" {
continue
}
if strings . ContainsRune ( part , '=' ) {
keyval := strings . Split ( part , "=" )
cc [ strings . Trim ( keyval [ 0 ] , " " ) ] = strings . Trim ( keyval [ 1 ] , "," )
} else {
cc [ part ] = ""
}
}
return cc
}
// CacheExpires helper function to determine remaining time before repeating a request.
func CacheExpires ( r * http . Response ) time . Time {
// Figure out when the cache expires.
var expires time . Time
now , err := time . Parse ( time . RFC1123 , r . Header . Get ( "date" ) )
if err != nil {
return time . Now ( )
}
respCacheControl := parseCacheControl ( r . Header )
if maxAge , ok := respCacheControl [ "max-age" ] ; ok {
lifetime , err := time . ParseDuration ( maxAge + "s" )
if err != nil {
expires = now
}
2024-05-12 12:36:47 +03:00
expires = now . Add ( lifetime )
2024-04-10 22:18:44 +03:00
} else {
expiresHeader := r . Header . Get ( "Expires" )
if expiresHeader != "" {
expires , err = time . Parse ( time . RFC1123 , expiresHeader )
if err != nil {
expires = now
}
}
}
return expires
}
func strlen ( s string ) int {
return utf8 . RuneCountInString ( s )
}
2024-05-12 12:36:47 +03:00
// GenericSwaggerError Provides access to the body, error and model on returned errors.
type GenericSwaggerError struct {
2024-04-10 22:18:44 +03:00
body [ ] byte
error string
model interface { }
}
// Error returns non-empty string if there was an error.
2024-05-12 12:36:47 +03:00
func ( e GenericSwaggerError ) Error ( ) string {
2024-04-10 22:18:44 +03:00
return e . error
}
// Body returns the raw bytes of the response
2024-05-12 12:36:47 +03:00
func ( e GenericSwaggerError ) Body ( ) [ ] byte {
2024-04-10 22:18:44 +03:00
return e . body
}
// Model returns the unpacked model of the error
2024-05-12 12:36:47 +03:00
func ( e GenericSwaggerError ) Model ( ) interface { } {
2024-04-10 22:18:44 +03:00
return e . model
}