mg-transport-core/core/utils.go

268 lines
5.8 KiB
Go
Raw Normal View History

2019-09-04 15:22:27 +03:00
package core
import (
2019-12-12 09:35:05 +03:00
// nolint:gosec
2019-09-04 15:22:27 +03:00
"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"
v5 "github.com/retailcrm/api-client-go/v5"
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
)
var defaultCurrencies = map[string]string{
"rub": "₽",
"uah": "₴",
"byn": "Br",
"kzt": "₸",
"usd": "$",
"eur": "€",
"prb": "PRB",
"mdl": "L",
"kgs": "с",
"pln": "zł",
"azn": "₼",
"amd": "֏",
"thb": "฿",
"aed": "AED",
"nok": "kr",
"cad": "C$",
"czk": "Kč",
"sek": "kr",
"dkk": "kr",
"ron": "lei",
"uzs": "So'm",
"aud": "$",
"chf": "₣",
"inr": "₹",
"bgn": "лв",
"ngn": "₦",
"huf": "ƒ",
"ils": "₪",
"try": "₺",
"stn": "₡",
"ars": "$",
"bob": "Bs",
"ves": "Bs",
"gtq": "Q",
"hnl": "L",
"dop": "RD$",
"cop": "COL$",
"crc": "₡",
"cup": "$MN",
"mxn": "NP$",
"nio": "C$",
"pab": "B/",
"pyg": "₲",
"pen": "S/",
"svc": "₡",
"uyu": "$U",
"clp": "Ch$",
"gel": "₾",
"gbp": "£",
}
2019-09-04 15:22:27 +03:00
// Utils service object
type Utils struct {
IsDebug bool
2019-12-12 10:08:26 +03:00
TokenCounter uint32
2019-09-04 15:22:27 +03:00
ConfigAWS ConfigAWS
Logger LoggerInterface
2019-09-04 15:22:27 +03:00
slashRegex *regexp.Regexp
}
// NewUtils will create new Utils instance
func NewUtils(awsConfig ConfigAWS, logger LoggerInterface, debug bool) *Utils {
2019-09-04 15:22:27 +03:00
return &Utils{
IsDebug: debug,
ConfigAWS: awsConfig,
Logger: logger,
TokenCounter: 0,
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
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()
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 {
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)
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)
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 {
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)
2019-12-12 09:35:05 +03:00
// nolint:gosec
2019-09-04 15:22:27 +03:00
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)
2019-12-12 09:35:05 +03:00
// nolint:gosec
2019-09-04 15:22:27 +03:00
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 {
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 defaultCurrencies
}
// GetCurrencySymbol returns currency symbol by it's ISO 4127 code.
// It returns provided currency code in uppercase if currency symbol cannot be found
func GetCurrencySymbol(code string) string {
if i, ok := DefaultCurrencies()[strings.ToLower(code)]; ok {
return i
2019-09-04 15:22:27 +03:00
}
return strings.ToUpper(code)
2019-09-04 15:22:27 +03:00
}