diff --git a/Makefile b/Makefile index 0630871..b16f23b 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,7 @@ jenkins_test: migrate_test @echo "==> Running tests (result in test-report.xml)" @go get -v -u github.com/jstemmer/go-junit-report @go test ./... -v -cpu 2 -race | /go/bin/go-junit-report -set-exit-code > ./test-report.xml + @go mod tidy fmt: @echo "==> Running gofmt" diff --git a/go.mod b/go.mod index d2d168d..e6d2520 100644 --- a/go.mod +++ b/go.mod @@ -30,8 +30,8 @@ require ( github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a // indirect github.com/jinzhu/now v0.0.0-20180511015916-ed742868f2ae // indirect github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect + github.com/joho/godotenv v1.3.0 // indirect github.com/json-iterator/go v1.1.5 // indirect - github.com/jstemmer/go-junit-report v0.0.0-20180614143834-385fac0ced9a // indirect github.com/jtolds/gls v4.2.1+incompatible // indirect github.com/kr/pretty v0.1.0 // indirect github.com/lib/pq v1.0.0 // indirect @@ -44,8 +44,8 @@ require ( github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 github.com/pkg/errors v0.8.0 github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/retailcrm/api-client-go v1.0.6 - github.com/retailcrm/mg-transport-api-client-go v1.1.10 + github.com/retailcrm/api-client-go v1.0.7 + github.com/retailcrm/mg-transport-api-client-go v1.1.11 github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf // indirect github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a // indirect github.com/stevvooe/resumable v0.0.0-20180830230917-22b14a53ba50 // indirect diff --git a/go.sum b/go.sum index bc464c0..c459b47 100644 --- a/go.sum +++ b/go.sum @@ -62,10 +62,10 @@ github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Ao github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/jstemmer/go-junit-report v0.0.0-20180614143834-385fac0ced9a h1:2qq552JOlVHGYvqPc9ynBnGPDHeA7p0/QRn2NkrO8vk= -github.com/jstemmer/go-junit-report v0.0.0-20180614143834-385fac0ced9a/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -93,12 +93,10 @@ github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/retailcrm/api-client-go v1.0.6 h1:4Q3e4ve8GOOHIQdq3/wTGqgWuWa1cKMKqmgrTv4FoDU= -github.com/retailcrm/api-client-go v1.0.6/go.mod h1:QRoPE2SM6ST7i2g0yEdqm7Iw98y7cYuq3q14Ot+6N8c= -github.com/retailcrm/mg-transport-api-client-go v1.1.9 h1:ogh5ThoqZJM5v4ZY6CqctUj01pVVHfBLXkrmX+BFjHE= -github.com/retailcrm/mg-transport-api-client-go v1.1.9/go.mod h1:AWV6BueE28/6SCoyfKURTo4lF0oXYoOKmHTzehd5vAI= -github.com/retailcrm/mg-transport-api-client-go v1.1.10 h1:RR8S5NA6FPVrF6UVXaLwu/gJyKUg5aUObQ97S98M3Yc= -github.com/retailcrm/mg-transport-api-client-go v1.1.10/go.mod h1:AWV6BueE28/6SCoyfKURTo4lF0oXYoOKmHTzehd5vAI= +github.com/retailcrm/api-client-go v1.0.7 h1:j4C2PvPUDP9nAuYWDvJPnYNpkj+LDBgn71kHvxJmSPg= +github.com/retailcrm/api-client-go v1.0.7/go.mod h1:QRoPE2SM6ST7i2g0yEdqm7Iw98y7cYuq3q14Ot+6N8c= +github.com/retailcrm/mg-transport-api-client-go v1.1.11 h1:jAIOKqkjA2r0v/V6lTHYQsD8q0lFpfpqzAffHAJlhCQ= +github.com/retailcrm/mg-transport-api-client-go v1.1.11/go.mod h1:AWV6BueE28/6SCoyfKURTo4lF0oXYoOKmHTzehd5vAI= github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf h1:6V1qxN6Usn4jy8unvggSJz/NC790tefw8Zdy6OZS5co= github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a h1:JSvGDIbmil4Ui/dDdFBExb7/cmkNjyX5F97oglmvCDo= diff --git a/src/routing.go b/src/routing.go index d2f5621..94560c6 100644 --- a/src/routing.go +++ b/src/routing.go @@ -57,11 +57,17 @@ func addBotHandler(c *gin.Context) { return } - b.Name = bot.Self.FirstName + b.Name = bot.Self.UserName conn := getConnectionById(b.ConnectionID) client := v1.New(conn.MGURL, conn.MGToken) + client.Debug = config.Debug - data, status, err := client.ActivateTransportChannel(getChannelSettings()) + channelSettings := getChannelSettings() + if b.Name != "" { + channelSettings.Name = "@" + b.Name + } + + data, status, err := client.ActivateTransportChannel(channelSettings) if status != http.StatusCreated { c.AbortWithStatusJSON(BadRequest("error_activating_channel")) logger.Error(conn.APIURL, status, err.Error(), data) @@ -88,6 +94,7 @@ func deleteBotHandler(c *gin.Context) { } var client = v1.New(conn.MGURL, conn.MGToken) + client.Debug = config.Debug data, status, err := client.DeactivateTransportChannel(getBotChannelByToken(b.Token)) if status > http.StatusOK { @@ -140,7 +147,7 @@ func saveHandler(c *gin.Context) { if code == http.StatusInternalServerError { c.Error(err) } else { - c.AbortWithStatusJSON(BadRequest(err.Error())) + c.AbortWithStatusJSON(code, gin.H{"error": err.Error()}) } return } @@ -362,12 +369,18 @@ func updateBots(conn *Connection, hashSettings string) { bots := conn.getBotsByClientID() if len(bots) > 0 { client := v1.New(conn.MGURL, conn.MGToken) + client.Debug = config.Debug for _, bot := range bots { if bot.ChannelSettingsHash == hashSettings { continue } - data, status, err := client.UpdateTransportChannel(getChannelSettings(bot.Channel)) + channelSettings := getChannelSettings(bot.Channel) + if bot.Name != "" { + channelSettings.Name = "@" + bot.Name + } + + data, status, err := client.UpdateTransportChannel(channelSettings) if config.Debug { logger.Infof( "updateChannelsSettings apiURL: %s, ChannelID: %d, Data: %v, Status: %d, err: %v", @@ -422,6 +435,7 @@ func telegramWebhookHandler(c *gin.Context) { } var client = v1.New(conn.MGURL, conn.MGToken) + client.Debug = config.Debug if update.Message != nil { if update.Message.Text == "" { @@ -580,6 +594,7 @@ func mgWebhookHandler(c *gin.Context) { return } + bot.Debug = config.Debug setLocale(b.Lang) switch msg.Type { @@ -587,7 +602,7 @@ func mgWebhookHandler(c *gin.Context) { var mb string switch msg.Data.Type { case v1.MsgTypeProduct: - mb = fmt.Sprintf("%s\n", msg.Data.Product.Name) + mb = fmt.Sprintf("*%s*\n", msg.Data.Product.Name) if msg.Data.Product.Cost != nil && msg.Data.Product.Cost.Value != 0 { mb += fmt.Sprintf( @@ -624,6 +639,8 @@ func mgWebhookHandler(c *gin.Context) { m.ReplyToMessageID = qid } + m.ParseMode = "Markdown" + msgSend, err := bot.Send(m) if err != nil { logger.Error(err) @@ -669,7 +686,7 @@ func mgWebhookHandler(c *gin.Context) { } func getOrderMessage(dataOrder *v1.MessageDataOrder) string { - mb := getLocalizedMessage("order") + mb := "*" + getLocalizedMessage("order") if dataOrder.Number != "" { mb += " " + dataOrder.Number @@ -678,7 +695,7 @@ func getOrderMessage(dataOrder *v1.MessageDataOrder) string { if dataOrder.Date != "" { mb += fmt.Sprintf(" (%s)", dataOrder.Date) } - mb += "\n" + mb += "*\n" if len(dataOrder.Items) > 0 { mb += "\n" for k, v := range dataOrder.Items { @@ -691,7 +708,7 @@ func getOrderMessage(dataOrder *v1.MessageDataOrder) string { if v.Quantity != nil { if v.Quantity.Value != 0 { mb += fmt.Sprintf( - " %v", + " _%v_", v.Quantity.Value, ) } @@ -700,7 +717,7 @@ func getOrderMessage(dataOrder *v1.MessageDataOrder) string { if v.Price != nil { if val, ok := currency[strings.ToLower(v.Price.Currency)]; ok { mb += fmt.Sprintf( - " x %s\n", + " _x %s_\n", getLocalizedTemplateMessage( "cost_currency", map[string]interface{}{ @@ -719,20 +736,20 @@ func getOrderMessage(dataOrder *v1.MessageDataOrder) string { if dataOrder.Delivery != nil { if dataOrder.Delivery.Name != "" { mb += fmt.Sprintf( - "\n%s:\n%s", + "\n*%s:*\n%s", getLocalizedMessage("delivery"), dataOrder.Delivery.Name, ) } - if dataOrder.Delivery.Amount != nil { - if val, ok := currency[strings.ToLower(dataOrder.Delivery.Amount.Currency)]; ok && dataOrder.Delivery.Amount.Value != 0 { + if dataOrder.Delivery.Price != nil { + if val, ok := currency[strings.ToLower(dataOrder.Delivery.Price.Currency)]; ok && dataOrder.Delivery.Price.Value != 0 { mb += fmt.Sprintf( "; %s", getLocalizedTemplateMessage( "cost_currency", map[string]interface{}{ - "Amount": dataOrder.Delivery.Amount.Value, + "Amount": dataOrder.Delivery.Price.Value, "Currency": val, }, ), @@ -749,7 +766,7 @@ func getOrderMessage(dataOrder *v1.MessageDataOrder) string { if len(dataOrder.Payments) > 0 { mb += fmt.Sprintf( - "\n%s:\n", + "\n*%s:*\n", getLocalizedMessage("payment"), ) for _, v := range dataOrder.Payments { diff --git a/src/routing_test.go b/src/routing_test.go index e86ac04..f4b9445 100644 --- a/src/routing_test.go +++ b/src/routing_test.go @@ -58,6 +58,7 @@ func TestRouting_addBotHandler(t *testing.T) { ch := v1.Channel{ Type: "telegram", + Name: "@TestBot", Settings: v1.ChannelSettings{ SpamAllowed: false, Status: v1.Status{ diff --git a/src/run.go b/src/run.go index 4e8e790..74fd3db 100644 --- a/src/run.go +++ b/src/run.go @@ -59,8 +59,8 @@ func setup() *gin.Engine { gin.SetMode(gin.ReleaseMode) } - r := gin.Default() - + r := gin.New() + r.Use(gin.Recovery()) if config.Debug { r.Use(gin.Logger()) } diff --git a/src/utils.go b/src/utils.go index 2fc15ac..bb93420 100644 --- a/src/utils.go +++ b/src/utils.go @@ -35,6 +35,7 @@ func GenerateToken() string { func getAPIClient(url, key string) (*v5.Client, error, int) { client := v5.New(url, key) + client.Debug = config.Debug cr, status, e := client.APICredentials() if e.RuntimeErr != nil { diff --git a/static/script.js b/static/script.js index a2c4cef..6b51181 100644 --- a/static/script.js +++ b/static/script.js @@ -13,9 +13,11 @@ $(document).on("change", "select", function(e) { $('#save-crm').on("submit", function(e) { e.preventDefault(); + let formData = formDataToObj($(this).serializeArray()); + disableForm($(this)); send( $(this).attr('action'), - formDataToObj($(this).serializeArray()), + formData, function (data) { sessionStorage.setItem("createdMsg", data.message); @@ -28,17 +30,26 @@ $('#save-crm').on("submit", function(e) { $("#save").on("submit", function(e) { e.preventDefault(); + let formData = formDataToObj($(this).serializeArray()); + disableForm($(this)); send( $(this).attr('action'), - formDataToObj($(this).serializeArray()), + formData, function (data) { - M.toast({html: data.message}); + M.toast({ + html: data.message, + displayLength: 1000, + completeCallback: function(){ + enableForm(); + } + }); } ) }); $("#add-bot").on("submit", function(e) { e.preventDefault(); + disableForm($(this)); send( $(this).attr('action'), { @@ -53,6 +64,7 @@ $("#add-bot").on("submit", function(e) { $("#bots tbody").append(getBotTemplate(data)); $("#token").val(""); $('select').formSelect(); + enableForm(); } ) }); @@ -61,6 +73,7 @@ $(document).on("click", ".delete-bot", function(e) { e.preventDefault(); var but = $(this); var confirmText = JSON.parse(sessionStorage.getItem("confirmText")); + but.addClass('disabled'); $.confirm({ title: false, @@ -90,6 +103,9 @@ $(document).on("click", ".delete-bot", function(e) { }, cancel: { text: confirmText["cancel"], + action: function () { + but.removeClass('disabled'); + }, }, } }); @@ -103,14 +119,19 @@ function send(url, data, callback) { success: callback, error: function (res){ if (res.status >= 400) { - M.toast({html: res.responseJSON.error}) + M.toast({ + html: res.responseJSON.error, + displayLength: 1000, + completeCallback: function(){ + enableForm() + } + }) } } }); } function getBotTemplate(data) { - // let bot = JSON.parse(data); tmpl = ` ${data.name} @@ -180,3 +201,15 @@ $( document ).ready(function() { }, 1000); } }); + +function disableForm(elem) { + $(document).find('button.btn').addClass('disabled'); + elem.find(".material-icons").addClass('animate'); + $("form :input").prop("disabled", true); +} + +function enableForm() { + $(document).find('button.btn').removeClass('disabled'); + $(document).find(".material-icons").removeClass('animate'); + $("form :input").prop("disabled", false); +} \ No newline at end of file diff --git a/static/style.css b/static/style.css index dcb57df..b7bc072 100644 --- a/static/style.css +++ b/static/style.css @@ -137,3 +137,14 @@ main { .footer-copyright p { color: #9e9e9e; } + +.animate { + transition: all 0.5s ease; + animation: rotate 1s linear infinite; +} + +@keyframes rotate { + from { + transform: rotate(360deg); + } +} diff --git a/translate/translate.en.yml b/translate/translate.en.yml index b160a5c..e40bdb4 100644 --- a/translate/translate.en.yml +++ b/translate/translate.en.yml @@ -48,4 +48,4 @@ order: "Order" delivery: "Delivery" payment: "Payment" order_total: "Order total" -cost_currency: "{{.Amount}} {{.Currency}}" +cost_currency: "{{.Currency}}{{.Amount}}"