docxTemplater/amo/api.go

312 lines
6.1 KiB
Go
Raw Normal View History

2022-07-28 15:00:43 +00:00
package amo
import (
"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"
"io/ioutil"
"net/http"
"time"
"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"
)
const (
OAUTH_URL = "https://www.amocrm.ru/oauth"
)
type Client struct {
App *ClientApp
Config *oauth2.Config // Индивидуальный конфиг клиента
2022-07-28 15:00:43 +00:00
HTTPClient *http.Client
Subdomain string // Субдомен с которым работаем
Token *oauth2.Token
}
type ClientApp struct {
Config *oauth2.Config
2022-07-28 15:00:43 +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 + "2/access_token",
},
RedirectURL: redirectUri,
Scopes: nil,
},
}
2022-07-28 15:00:43 +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
}
return ca.Config.AuthCodeURL(
state,
oauth2.SetAuthURLParam("mode", "popup"),
), 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) {
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
}
func (ca *ClientApp) NewClient(ctx context.Context, referer string, token *oauth2.Token, code string) (*Client,
error) {
var err error
2022-07-28 15:00:43 +00:00
referer = "https://" + referer
2022-07-28 15:00:43 +00:00
client := &Client{
App: ca,
Config: &oauth2.Config{
ClientID: ca.Config.ClientID,
ClientSecret: ca.Config.ClientSecret,
Endpoint: oauth2.Endpoint{
AuthURL: ca.Config.Endpoint.AuthURL,
TokenURL: referer + "/oauth2/access_token",
},
RedirectURL: ca.Config.RedirectURL,
Scopes: ca.Config.Scopes,
},
HTTPClient: nil,
Subdomain: referer,
Token: token,
}
2022-07-28 15:00:43 +00:00
if code != "" {
token, err = client.Config.Exchange(ctx, code)
2022-07-28 15:00:43 +00:00
}
if err != nil {
return nil, err
}
client.Token = token
client.HTTPClient = client.Config.Client(ctx, token)
return client, nil
}
func (ca *ClientApp) RefreshToken(ctx context.Context, oldToken *oauth2.Token, referer string) (*oauth2.Token,
error) {
referer = "https://" + referer
config := &oauth2.Config{
ClientID: ca.Config.ClientID,
ClientSecret: ca.Config.ClientSecret,
Endpoint: oauth2.Endpoint{
AuthURL: ca.Config.Endpoint.AuthURL,
TokenURL: referer + "/oauth2/access_token",
},
RedirectURL: ca.Config.RedirectURL,
Scopes: ca.Config.Scopes,
}
token, err := config.TokenSource(ctx, oldToken).Token()
if err != nil {
return nil, err
}
return token, nil
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", err)
2022-07-28 15:00:43 +00:00
return nil, err
}
c.setHeaders(req)
resp, err := c.HTTPClient.Do(req)
if err != nil {
fmt.Println("2", err)
2022-07-28 15:00:43 +00:00
return nil, err
}
for resp.StatusCode == 429 {
time.Sleep(time.Second)
resp, err = c.HTTPClient.Do(req)
if err != nil {
fmt.Println("5", err)
return nil, err
}
}
2022-07-28 15:00:43 +00:00
var response Lead
str, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("4", err)
}
err = json.Unmarshal(str, &response)
2022-07-28 15:00:43 +00:00
if err != nil {
fmt.Println("3", err, string(str))
2022-07-28 15:00:43 +00:00
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
}
for resp.StatusCode == 429 {
time.Sleep(time.Second)
resp, err = c.HTTPClient.Do(req)
if err != nil {
fmt.Println("5", err)
return nil, err
}
}
2022-07-28 15:00:43 +00:00
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
}
for resp.StatusCode == 429 {
time.Sleep(time.Second)
resp, err = c.HTTPClient.Do(req)
if err != nil {
fmt.Println("5", err)
return nil, err
}
}
2022-07-28 15:00:43 +00:00
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)
//}
2022-07-28 15:00:43 +00:00
}