docxTemplater/amo/api.go
Skeris 15c37f29d2 fix: add mkdir command to create downloaded and generated dirs on image
building
feat: add rerequesting logic for 429 status code from amocrm
feat(rm when unnecessary): add some logging to have better understanding
of errors that occurs due to amo api requesting process
fix: revert change replacing space to ground
feat: change filename generator to adding client name to filename
fix: move down template option setter to avoid circumstances for calling
option setter on nil
2022-12-20 16:14:02 +03:00

312 lines
6.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package amo
import (
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/Pena-Co-Ltd/amocrm_templategen_back/tools"
"github.com/dgrijalva/jwt-go"
"golang.org/x/oauth2"
)
const (
OAUTH_URL = "https://www.amocrm.ru/oauth"
)
type Client struct {
App *ClientApp
Config *oauth2.Config // Индивидуальный конфиг клиента
HTTPClient *http.Client
Subdomain 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 + "2/access_token",
},
RedirectURL: redirectUri,
Scopes: nil,
},
}
}
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
}
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, referer string, token *oauth2.Token, code string) (*Client,
error) {
var err error
referer = "https://" + referer
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,
}
if code != "" {
token, err = client.Config.Exchange(ctx, code)
}
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
}
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", err)
return nil, err
}
c.setHeaders(req)
resp, err := c.HTTPClient.Do(req)
if err != nil {
fmt.Println("2", err)
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
}
}
var response Lead
str, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("4", err)
}
err = json.Unmarshal(str, &response)
if err != nil {
fmt.Println("3", err, string(str))
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
}
}
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
}
}
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)
//}
}