2019-09-04 15:22:27 +03:00
|
|
|
package core
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha1"
|
|
|
|
"crypto/sha256"
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
"sync/atomic"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
|
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
|
|
"github.com/aws/aws-sdk-go/aws/session"
|
|
|
|
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
|
|
|
"github.com/op/go-logging"
|
|
|
|
v5 "github.com/retailcrm/api-client-go/v5"
|
|
|
|
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Utils service object
|
|
|
|
type Utils struct {
|
|
|
|
IsDebug bool
|
|
|
|
ConfigAWS ConfigAWS
|
|
|
|
Logger *logging.Logger
|
|
|
|
TokenCounter uint32
|
|
|
|
slashRegex *regexp.Regexp
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewUtils will create new Utils instance
|
2019-09-18 18:02:40 +03:00
|
|
|
func NewUtils(awsConfig ConfigAWS, logger *logging.Logger, debug bool) *Utils {
|
2019-09-04 15:22:27 +03:00
|
|
|
return &Utils{
|
|
|
|
IsDebug: debug,
|
|
|
|
ConfigAWS: awsConfig,
|
|
|
|
Logger: logger,
|
|
|
|
TokenCounter: 0,
|
2019-09-04 15:52:41 +03:00
|
|
|
slashRegex: slashRegex,
|
2019-09-04 15:22:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// resetUtils
|
|
|
|
func (u *Utils) resetUtils(awsConfig ConfigAWS, debug bool, tokenCounter uint32) {
|
|
|
|
u.TokenCounter = tokenCounter
|
|
|
|
u.ConfigAWS = awsConfig
|
|
|
|
u.IsDebug = debug
|
2019-09-04 15:52:41 +03:00
|
|
|
u.slashRegex = slashRegex
|
2019-09-04 15:22:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// GenerateToken will generate long pseudo-random string.
|
|
|
|
func (u *Utils) GenerateToken() string {
|
|
|
|
c := atomic.AddUint32(&u.TokenCounter, 1)
|
|
|
|
|
|
|
|
return fmt.Sprintf("%x", sha256.Sum256([]byte(fmt.Sprintf("%d%d", time.Now().UnixNano(), c))))
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAPIClient will initialize retailCRM api client from url and key
|
|
|
|
func (u *Utils) GetAPIClient(url, key string) (*v5.Client, int, error) {
|
|
|
|
client := v5.New(url, key)
|
|
|
|
client.Debug = u.IsDebug
|
|
|
|
|
|
|
|
cr, status, e := client.APICredentials()
|
2019-10-17 13:11:20 +03:00
|
|
|
if e != nil && e.Error() != "" {
|
|
|
|
u.Logger.Error(url, status, e.Error(), cr)
|
|
|
|
return nil, http.StatusInternalServerError, errors.New(e.Error())
|
2019-09-04 15:22:27 +03:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if !cr.Success {
|
2019-10-17 13:11:20 +03:00
|
|
|
errMsg := "unknown error"
|
|
|
|
|
|
|
|
if e != nil {
|
|
|
|
if e.ApiError() != "" {
|
|
|
|
errMsg = e.ApiError()
|
|
|
|
} else if e.ApiErrors() != nil {
|
|
|
|
errMsg = ""
|
|
|
|
|
|
|
|
for key, errText := range e.ApiErrors() {
|
|
|
|
errMsg += fmt.Sprintf("[%s: %s] ", key, errText)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
u.Logger.Error(url, status, errMsg, cr)
|
2019-09-04 15:52:41 +03:00
|
|
|
return nil, http.StatusBadRequest, errors.New("invalid credentials")
|
2019-09-04 15:22:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if res := u.checkCredentials(cr.Credentials); len(res) != 0 {
|
|
|
|
u.Logger.Error(url, status, res)
|
2019-09-04 15:52:41 +03:00
|
|
|
return nil, http.StatusBadRequest, errors.New("missing credentials")
|
2019-09-04 15:22:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return client, 0, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *Utils) checkCredentials(credential []string) []string {
|
2019-09-04 15:52:41 +03:00
|
|
|
rc := make([]string, len(credentialsTransport))
|
|
|
|
copy(rc, credentialsTransport)
|
2019-09-04 15:22:27 +03:00
|
|
|
|
|
|
|
for _, vc := range credential {
|
|
|
|
for kn, vn := range rc {
|
|
|
|
if vn == vc {
|
|
|
|
if len(rc) == 1 {
|
|
|
|
rc = rc[:0]
|
|
|
|
break
|
|
|
|
}
|
|
|
|
rc = append(rc[:kn], rc[kn+1:]...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc
|
|
|
|
}
|
|
|
|
|
|
|
|
// UploadUserAvatar will upload avatar for user
|
|
|
|
func (u *Utils) UploadUserAvatar(url string) (picURLs3 string, err error) {
|
|
|
|
s3Config := &aws.Config{
|
|
|
|
Credentials: credentials.NewStaticCredentials(
|
|
|
|
u.ConfigAWS.AccessKeyID,
|
|
|
|
u.ConfigAWS.SecretAccessKey,
|
|
|
|
""),
|
|
|
|
Region: aws.String(u.ConfigAWS.Region),
|
|
|
|
}
|
|
|
|
|
|
|
|
s := session.Must(session.NewSession(s3Config))
|
|
|
|
uploader := s3manager.NewUploader(s)
|
|
|
|
|
|
|
|
resp, err := http.Get(url)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
if resp.StatusCode >= http.StatusBadRequest {
|
|
|
|
return "", fmt.Errorf("get: %v code: %v", url, resp.StatusCode)
|
|
|
|
}
|
|
|
|
|
|
|
|
result, err := uploader.Upload(&s3manager.UploadInput{
|
|
|
|
Bucket: aws.String(u.ConfigAWS.Bucket),
|
|
|
|
Key: aws.String(fmt.Sprintf("%v/%v.jpg", u.ConfigAWS.FolderName, u.GenerateToken())),
|
|
|
|
Body: resp.Body,
|
|
|
|
ContentType: aws.String(u.ConfigAWS.ContentType),
|
|
|
|
ACL: aws.String("public-read"),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
picURLs3 = result.Location
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-09-18 18:02:40 +03:00
|
|
|
// RemoveTrailingSlash will remove slash at the end of any string
|
|
|
|
func (u *Utils) RemoveTrailingSlash(crmURL string) string {
|
|
|
|
return u.slashRegex.ReplaceAllString(crmURL, ``)
|
|
|
|
}
|
|
|
|
|
2019-09-04 15:22:27 +03:00
|
|
|
// GetMGItemData will upload file to MG by URL and return information about attachable item
|
|
|
|
func GetMGItemData(client *v1.MgClient, url string, caption string) (v1.Item, int, error) {
|
|
|
|
item := v1.Item{}
|
|
|
|
|
|
|
|
data, st, err := client.UploadFileByURL(
|
|
|
|
v1.UploadFileByUrlRequest{
|
|
|
|
Url: url,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return item, st, err
|
|
|
|
}
|
|
|
|
|
|
|
|
item.ID = data.ID
|
|
|
|
item.Caption = caption
|
|
|
|
|
|
|
|
return item, st, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetEntitySHA1 will serialize any value to JSON and return SHA1 hash of this JSON
|
|
|
|
func GetEntitySHA1(v interface{}) (hash string, err error) {
|
|
|
|
res, _ := json.Marshal(v)
|
|
|
|
|
|
|
|
h := sha1.New()
|
|
|
|
_, err = h.Write(res)
|
|
|
|
hash = fmt.Sprintf("%x", h.Sum(nil))
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReplaceMarkdownSymbols will remove markdown symbols from text
|
|
|
|
func ReplaceMarkdownSymbols(s string) string {
|
2019-09-04 15:52:41 +03:00
|
|
|
for _, v := range markdownSymbols {
|
2019-09-04 15:22:27 +03:00
|
|
|
s = strings.Replace(s, v, "\\"+v, -1)
|
|
|
|
}
|
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
// DefaultCurrencies will return default currencies list for all bots
|
|
|
|
func DefaultCurrencies() map[string]string {
|
|
|
|
return map[string]string{
|
|
|
|
"rub": "₽",
|
|
|
|
"uah": "₴",
|
|
|
|
"byr": "Br",
|
|
|
|
"kzt": "₸",
|
|
|
|
"usd": "$",
|
|
|
|
"eur": "€",
|
|
|
|
}
|
|
|
|
}
|