package amo import ( "context" "encoding/json" "errors" "fmt" "github.com/dgrijalva/jwt-go" "golang.org/x/oauth2" "net/http" ) const ( OAUTH_URL = "https://www.amocrm.ru/oauth" ) type Client struct { App *ClientApp HTTPClient *http.Client Subdomain string // Субдомен с которым работаем Code string // Код авторизации Token *oauth2.Token } type ClientApp struct { Config *oauth2.Config } func NewClientApp(clientID, clientSecret string, redirectUri string) *ClientApp { return &ClientApp{ Config: &oauth2.Config{ ClientID: clientID, ClientSecret: clientSecret, Endpoint: oauth2.Endpoint{ AuthURL: OAUTH_URL, TokenURL: OAUTH_URL + "/token", }, RedirectURL: redirectUri, Scopes: nil, }, } } func (ca *ClientApp) GenerateOAuthUrl() string { return ca.Config.AuthCodeURL( "my-state", oauth2.SetAuthURLParam("mode", "popup"), ) } func (ca *ClientApp) DecodeJwt(r *http.Request) (*XAuthToken, error) { tokenHeader := r.Header.Get("x-auth-token") if tokenHeader == "" { return nil, errors.New("empty jwt") } token, err := jwt.ParseWithClaims(tokenHeader, &XAuthToken{}, func(token *jwt.Token) (interface{}, error) { return []byte(ca.Config.ClientSecret), nil }) if err != nil { return nil, err } claims, ok := token.Claims.(*XAuthToken) if !ok || !token.Valid { fmt.Println("token:", token) fmt.Println("claims:", claims) fmt.Println("valid:", token.Valid) return nil, errors.New("invalid token") } return claims, nil } func (ca *ClientApp) NewClient(ctx context.Context, subdomain string, token *oauth2.Token, code string) (*Client, error) { var err error subdomain = "https://" + subdomain ca.Config.Endpoint.TokenURL = subdomain if code != "" { token, err = ca.Config.Exchange(ctx, code) } return &Client{ App: ca, HTTPClient: ca.Config.Client(ctx, token), Subdomain: subdomain, Token: token, }, err } // AuthCode - обменивает код авторизации на токен //func (c *Client) AuthCode() (*oauth2.Token, error) { // body := map[string]string{ // "client_id": c.App.ClientID, // "client_secret": c.App.ClientSecret, // "grant_type": "authorization_code", // "code": c.Code, // "redirect_uri": c.App.RedirectUri, // } // // bytesBody, err := json.Marshal(body) // if err != nil { // return nil, err // } // // req, err := http.NewRequest("POST", c.Subdomain+"/oauth2/access_token", bytes.NewBuffer(bytesBody)) // if err != nil { // return nil, err // } // // c.setHeaders(req) // // resp, err := c.HTTPClient.Do(req) // // if err != nil { // return nil, err // } // // var response RespAuthCode // err = json.NewDecoder(resp.Body).Decode(&response) // if err != nil { // return nil, err // } // // c.Token = &oauth2.Token{ // AccessToken: response.AccessToken, // TokenType: response.TokenType, // RefreshToken: response.RefreshToken, // Expiry: time.Now().Add(time.Duration(response.ExpiresIn) * time.Second), // } // // return c.Token, nil //} func (c *Client) GetAccount() (*Account, error) { req, err := http.NewRequest("GET", c.Subdomain+"/api/v4/account", nil) if err != nil { fmt.Println("1") return nil, err } c.setHeaders(req) resp, err := c.HTTPClient.Do(req) if err != nil { fmt.Println("2") return nil, err } var response Account err = json.NewDecoder(resp.Body).Decode(&response) if err != nil { fmt.Println("3") return nil, err } return &response, nil } func (c *Client) GetLeadById(id string) (*Lead, error) { req, err := http.NewRequest("GET", fmt.Sprintf("%v/api/v4/leads/%v?with=contacts,catalog_elements,is_price_modified_by_robot,loss_reason", c.Subdomain, id), nil, ) fmt.Println("URL:", fmt.Sprintf("%v/api/v4/leads/%v?with=contacts,catalog_elements,is_price_modified_by_robot,"+ "loss_reason", c.Subdomain, id)) if err != nil { fmt.Println("1") return nil, err } c.setHeaders(req) resp, err := c.HTTPClient.Do(req) if err != nil { fmt.Println("2") return nil, err } var response Lead err = json.NewDecoder(resp.Body).Decode(&response) if err != nil { return nil, err } return &response, nil } func (c *Client) GetContactById(id string) (*Contact, error) { req, err := http.NewRequest("GET", fmt.Sprintf("%v/api/v4/contacts/%v?with=catalog_elements,leads,customers", c.Subdomain, id), nil, ) if err != nil { fmt.Println("1") return nil, err } c.setHeaders(req) resp, err := c.HTTPClient.Do(req) if err != nil { fmt.Println("2") return nil, err } var response Contact err = json.NewDecoder(resp.Body).Decode(&response) if err != nil { return nil, err } return &response, nil } func (c *Client) GetCompanyById(id string) (*Company, error) { req, err := http.NewRequest("GET", fmt.Sprintf("%v/api/v4/companies/%v?with=contacts,leads,catalog_elements,customers", c.Subdomain, id), nil, ) if err != nil { fmt.Println("1") return nil, err } c.setHeaders(req) resp, err := c.HTTPClient.Do(req) if err != nil { fmt.Println("2") return nil, err } var response Company err = json.NewDecoder(resp.Body).Decode(&response) if err != nil { return nil, err } return &response, nil } func (c *Client) setHeaders(req *http.Request) { req.Header.Set("User-Agent", "amoCRM-oAuth-client/1.0") req.Header.Set("Content-Type", "application/json") //if c.Token != nil { // c.Token.SetAuthHeader(req) //} }