2022-07-28 15:00:43 +00:00
|
|
|
|
package amo
|
|
|
|
|
|
|
|
|
|
import (
|
2022-09-15 13:53:55 +00:00
|
|
|
|
"context"
|
2022-07-28 15:00:43 +00:00
|
|
|
|
"encoding/json"
|
2022-08-10 13:53:34 +00:00
|
|
|
|
"errors"
|
2022-07-28 15:00:43 +00:00
|
|
|
|
"fmt"
|
2022-10-11 10:07:29 +00:00
|
|
|
|
"github.com/Pena-Co-Ltd/amocrm_templategen_back/tools"
|
2022-08-10 13:53:34 +00:00
|
|
|
|
"github.com/dgrijalva/jwt-go"
|
2022-07-28 15:00:43 +00:00
|
|
|
|
"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 {
|
2022-09-15 13:53:55 +00:00
|
|
|
|
Config *oauth2.Config
|
2022-07-28 15:00:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-09-15 13:53:55 +00:00
|
|
|
|
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,
|
|
|
|
|
},
|
|
|
|
|
}
|
2022-07-28 15:00:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-10-11 10:07:29 +00:00
|
|
|
|
func (ca *ClientApp) GenerateOAuthUrl(userId, redirectUrl string) (string, error) {
|
|
|
|
|
state, err := tools.EncryptTokenRC4(tools.StateToken{
|
|
|
|
|
UserID: userId,
|
|
|
|
|
Service: "amo",
|
|
|
|
|
RedirectUrl: redirectUrl,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-15 13:53:55 +00:00
|
|
|
|
return ca.Config.AuthCodeURL(
|
2022-10-11 10:07:29 +00:00
|
|
|
|
state,
|
2022-09-15 13:53:55 +00:00
|
|
|
|
oauth2.SetAuthURLParam("mode", "popup"),
|
2022-10-11 10:07:29 +00:00
|
|
|
|
), nil
|
2022-07-28 15:00:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-10 13:53:34 +00:00
|
|
|
|
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) {
|
2022-09-15 13:53:55 +00:00
|
|
|
|
return []byte(ca.Config.ClientSecret), nil
|
2022-08-10 13:53:34 +00:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-15 13:53:55 +00:00
|
|
|
|
func (ca *ClientApp) NewClient(ctx context.Context, subdomain string, token *oauth2.Token, code string) (*Client,
|
|
|
|
|
error) {
|
|
|
|
|
var err error
|
2022-07-28 15:00:43 +00:00
|
|
|
|
|
2022-09-15 13:53:55 +00:00
|
|
|
|
subdomain = "https://" + subdomain
|
2022-07-28 15:00:43 +00:00
|
|
|
|
|
2022-11-21 18:32:00 +00:00
|
|
|
|
ca.Config.Endpoint.TokenURL = subdomain + "/oauth2/access_token"
|
2022-07-28 15:00:43 +00:00
|
|
|
|
|
2022-09-15 13:53:55 +00:00
|
|
|
|
if code != "" {
|
|
|
|
|
token, err = ca.Config.Exchange(ctx, code)
|
2022-07-28 15:00:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-09-15 13:53:55 +00:00
|
|
|
|
return &Client{
|
|
|
|
|
App: ca,
|
|
|
|
|
HTTPClient: ca.Config.Client(ctx, token),
|
|
|
|
|
Subdomain: subdomain,
|
|
|
|
|
Token: token,
|
|
|
|
|
}, err
|
2022-07-28 15:00:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
)
|
2022-08-10 13:53:34 +00:00
|
|
|
|
|
|
|
|
|
fmt.Println("URL:", fmt.Sprintf("%v/api/v4/leads/%v?with=contacts,catalog_elements,is_price_modified_by_robot,"+
|
|
|
|
|
"loss_reason",
|
|
|
|
|
c.Subdomain, id))
|
|
|
|
|
|
2022-07-28 15:00:43 +00:00
|
|
|
|
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")
|
|
|
|
|
|
2022-09-15 13:53:55 +00:00
|
|
|
|
//if c.Token != nil {
|
|
|
|
|
// c.Token.SetAuthHeader(req)
|
|
|
|
|
//}
|
2022-07-28 15:00:43 +00:00
|
|
|
|
}
|