2018-05-17 18:35:53 +03:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2019-09-02 10:27:01 +03:00
|
|
|
"bytes"
|
2018-08-31 16:09:44 +03:00
|
|
|
"encoding/json"
|
2018-08-15 17:56:36 +03:00
|
|
|
"fmt"
|
2018-12-13 17:31:49 +03:00
|
|
|
"image/png"
|
|
|
|
"io"
|
2019-09-02 10:27:01 +03:00
|
|
|
"io/ioutil"
|
2018-08-17 16:31:55 +03:00
|
|
|
"net/http"
|
|
|
|
"strconv"
|
2018-09-13 21:17:23 +03:00
|
|
|
"strings"
|
2018-08-17 16:31:55 +03:00
|
|
|
"time"
|
2018-05-17 18:35:53 +03:00
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
"github.com/gin-gonic/gin"
|
2019-06-11 17:32:17 +03:00
|
|
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
|
2019-09-02 10:27:01 +03:00
|
|
|
"github.com/h2non/filetype"
|
|
|
|
filetypes "github.com/h2non/filetype/matchers"
|
2019-06-11 17:32:17 +03:00
|
|
|
v5 "github.com/retailcrm/api-client-go/v5"
|
|
|
|
v1 "github.com/retailcrm/mg-transport-api-client-go/v1"
|
2018-12-13 17:31:49 +03:00
|
|
|
"golang.org/x/image/webp"
|
2018-05-17 18:35:53 +03:00
|
|
|
)
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
func connectHandler(c *gin.Context) {
|
2018-05-18 18:11:09 +03:00
|
|
|
res := struct {
|
2018-08-15 17:56:36 +03:00
|
|
|
Conn Connection
|
2018-08-30 15:07:20 +03:00
|
|
|
Locale map[string]interface{}
|
|
|
|
Year int
|
2018-05-18 18:11:09 +03:00
|
|
|
}{
|
2018-08-15 17:56:36 +03:00
|
|
|
c.MustGet("account").(Connection),
|
2018-08-14 17:49:01 +03:00
|
|
|
getLocale(),
|
2018-08-30 15:07:20 +03:00
|
|
|
time.Now().Year(),
|
2018-05-18 18:11:09 +03:00
|
|
|
}
|
2018-05-17 18:35:53 +03:00
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
c.HTML(http.StatusOK, "home", &res)
|
|
|
|
}
|
2018-05-17 18:35:53 +03:00
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
func addBotHandler(c *gin.Context) {
|
2018-08-15 17:56:36 +03:00
|
|
|
b := c.MustGet("bot").(Bot)
|
2018-05-31 19:44:23 +03:00
|
|
|
cl, err := getBotByToken(b.Token)
|
2018-05-31 16:18:52 +03:00
|
|
|
if err != nil {
|
2018-08-14 17:49:01 +03:00
|
|
|
c.Error(err)
|
2018-05-25 18:09:38 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-05-31 19:44:23 +03:00
|
|
|
if cl.ID != 0 {
|
2018-08-23 15:52:32 +03:00
|
|
|
c.AbortWithStatusJSON(BadRequest("bot_already_created"))
|
2018-05-17 18:35:53 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-06-04 16:48:04 +03:00
|
|
|
bot, err := tgbotapi.NewBotAPI(b.Token)
|
2018-05-17 18:35:53 +03:00
|
|
|
if err != nil {
|
2018-08-23 15:52:32 +03:00
|
|
|
c.AbortWithStatusJSON(BadRequest("incorrect_token"))
|
2018-08-16 18:13:01 +03:00
|
|
|
logger.Error(b.Token, err.Error())
|
2018-05-23 18:03:11 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-06-01 12:08:22 +03:00
|
|
|
bot.Debug = config.Debug
|
2018-05-23 18:03:11 +03:00
|
|
|
|
2018-05-25 18:09:38 +03:00
|
|
|
wr, err := bot.SetWebhook(tgbotapi.NewWebhook("https://" + config.HTTPServer.Host + "/telegram/" + bot.Token))
|
2018-08-20 13:51:45 +03:00
|
|
|
if err != nil || !wr.Ok {
|
2018-08-23 15:52:32 +03:00
|
|
|
c.AbortWithStatusJSON(BadRequest("error_creating_webhook"))
|
2018-08-20 13:51:45 +03:00
|
|
|
logger.Error(b.Token, err.Error(), wr)
|
2018-05-25 18:09:38 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-09-24 17:47:44 +03:00
|
|
|
b.Name = bot.Self.UserName
|
2018-08-14 17:49:01 +03:00
|
|
|
conn := getConnectionById(b.ConnectionID)
|
2018-09-21 12:06:33 +03:00
|
|
|
client := v1.New(conn.MGURL, conn.MGToken)
|
2018-09-28 16:06:42 +03:00
|
|
|
client.Debug = config.Debug
|
2018-05-31 18:17:19 +03:00
|
|
|
|
2018-09-24 17:47:44 +03:00
|
|
|
channelSettings := getChannelSettings()
|
|
|
|
if b.Name != "" {
|
|
|
|
channelSettings.Name = "@" + b.Name
|
|
|
|
}
|
|
|
|
|
|
|
|
data, status, err := client.ActivateTransportChannel(channelSettings)
|
2018-05-17 18:35:53 +03:00
|
|
|
if status != http.StatusCreated {
|
2018-08-23 15:52:32 +03:00
|
|
|
c.AbortWithStatusJSON(BadRequest("error_activating_channel"))
|
2018-08-16 18:13:01 +03:00
|
|
|
logger.Error(conn.APIURL, status, err.Error(), data)
|
2018-05-17 18:35:53 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
b.Channel = data.ChannelID
|
2018-12-11 16:45:42 +03:00
|
|
|
b.Lang = "en"
|
|
|
|
|
|
|
|
hashSettings, err := getChannelSettingsHash()
|
|
|
|
if err != nil {
|
|
|
|
logger.Errorf("addBotHandler hashSettings apiURl: %s, err: %s", conn.APIURL, err.Error())
|
|
|
|
} else {
|
|
|
|
b.ChannelSettingsHash = hashSettings
|
|
|
|
}
|
2018-05-17 18:35:53 +03:00
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
err = conn.createBot(b)
|
2018-05-17 18:35:53 +03:00
|
|
|
if err != nil {
|
2019-01-17 12:28:51 +03:00
|
|
|
client.DeactivateTransportChannel(data.ChannelID)
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
c.Error(err)
|
2018-05-24 17:16:21 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-15 17:56:36 +03:00
|
|
|
c.JSON(http.StatusCreated, b)
|
2018-05-17 18:35:53 +03:00
|
|
|
}
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
func deleteBotHandler(c *gin.Context) {
|
2018-08-15 17:56:36 +03:00
|
|
|
b := c.MustGet("bot").(Bot)
|
2018-08-14 17:49:01 +03:00
|
|
|
conn := getConnectionById(b.ConnectionID)
|
|
|
|
if conn.MGURL == "" || conn.MGToken == "" {
|
2018-08-23 15:52:32 +03:00
|
|
|
c.AbortWithStatusJSON(BadRequest("not_found_account"))
|
2018-05-25 18:09:38 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
var client = v1.New(conn.MGURL, conn.MGToken)
|
2018-09-28 16:06:42 +03:00
|
|
|
client.Debug = config.Debug
|
2018-05-17 18:35:53 +03:00
|
|
|
|
2018-06-28 12:17:19 +03:00
|
|
|
data, status, err := client.DeactivateTransportChannel(getBotChannelByToken(b.Token))
|
|
|
|
if status > http.StatusOK {
|
2018-08-23 15:52:32 +03:00
|
|
|
c.AbortWithStatusJSON(BadRequest("error_deactivating_channel"))
|
2018-06-28 12:17:19 +03:00
|
|
|
logger.Error(b.ID, status, err.Error(), data)
|
|
|
|
return
|
2018-05-17 18:35:53 +03:00
|
|
|
}
|
2020-03-27 15:11:00 +03:00
|
|
|
|
2018-06-28 12:17:19 +03:00
|
|
|
err = b.deleteBot()
|
2018-05-17 18:35:53 +03:00
|
|
|
if err != nil {
|
2018-08-14 17:49:01 +03:00
|
|
|
c.Error(err)
|
2018-05-17 18:35:53 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
c.JSON(http.StatusOK, gin.H{})
|
2018-05-17 18:35:53 +03:00
|
|
|
}
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
func settingsHandler(c *gin.Context) {
|
|
|
|
uid := c.Param("uid")
|
2018-05-18 18:11:09 +03:00
|
|
|
|
2018-05-24 18:08:48 +03:00
|
|
|
p := getConnection(uid)
|
2018-05-17 18:35:53 +03:00
|
|
|
if p.ID == 0 {
|
2018-08-14 17:49:01 +03:00
|
|
|
c.Redirect(http.StatusFound, "/")
|
2018-05-29 10:08:38 +03:00
|
|
|
return
|
2018-05-17 18:35:53 +03:00
|
|
|
}
|
|
|
|
|
2018-05-31 16:18:52 +03:00
|
|
|
bots := p.getBotsByClientID()
|
2018-05-17 18:35:53 +03:00
|
|
|
|
|
|
|
res := struct {
|
2018-09-21 12:48:42 +03:00
|
|
|
Conn *Connection
|
|
|
|
Bots Bots
|
|
|
|
Locale map[string]interface{}
|
|
|
|
Year int
|
|
|
|
LangCode []string
|
2018-05-17 18:35:53 +03:00
|
|
|
}{
|
|
|
|
p,
|
|
|
|
bots,
|
2018-08-14 17:49:01 +03:00
|
|
|
getLocale(),
|
2018-08-30 15:07:20 +03:00
|
|
|
time.Now().Year(),
|
2018-09-21 12:48:42 +03:00
|
|
|
[]string{"en", "ru", "es"},
|
2018-05-17 18:35:53 +03:00
|
|
|
}
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
c.HTML(http.StatusOK, "form", &res)
|
2018-05-17 18:35:53 +03:00
|
|
|
}
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
func saveHandler(c *gin.Context) {
|
2018-08-15 17:56:36 +03:00
|
|
|
conn := c.MustGet("connection").(Connection)
|
2018-08-14 17:49:01 +03:00
|
|
|
_, err, code := getAPIClient(conn.APIURL, conn.APIKEY)
|
2018-05-28 18:16:13 +03:00
|
|
|
if err != nil {
|
2018-08-23 15:52:32 +03:00
|
|
|
if code == http.StatusInternalServerError {
|
|
|
|
c.Error(err)
|
|
|
|
} else {
|
2018-09-26 17:12:35 +03:00
|
|
|
c.AbortWithStatusJSON(code, gin.H{"error": err.Error()})
|
2018-08-23 15:52:32 +03:00
|
|
|
}
|
2018-05-28 18:16:13 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-31 16:09:44 +03:00
|
|
|
err = conn.saveConnectionByClientID()
|
2018-05-17 18:35:53 +03:00
|
|
|
if err != nil {
|
2018-08-14 17:49:01 +03:00
|
|
|
c.Error(err)
|
2018-05-17 18:35:53 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
c.JSON(http.StatusOK, gin.H{"message": getLocalizedMessage("successful")})
|
2018-05-17 18:35:53 +03:00
|
|
|
}
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
func createHandler(c *gin.Context) {
|
2018-08-15 17:56:36 +03:00
|
|
|
conn := c.MustGet("connection").(Connection)
|
2018-05-22 10:34:39 +03:00
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
cl := getConnectionByURL(conn.APIURL)
|
2018-05-17 18:35:53 +03:00
|
|
|
if cl.ID != 0 {
|
2018-08-23 15:52:32 +03:00
|
|
|
c.AbortWithStatusJSON(BadRequest("connection_already_created"))
|
2018-05-17 18:35:53 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-16 18:13:01 +03:00
|
|
|
client, err, code := getAPIClient(conn.APIURL, conn.APIKEY)
|
2018-05-28 18:16:13 +03:00
|
|
|
if err != nil {
|
2018-08-16 18:13:01 +03:00
|
|
|
if code == http.StatusInternalServerError {
|
|
|
|
c.Error(err)
|
|
|
|
} else {
|
2018-08-17 13:36:25 +03:00
|
|
|
c.AbortWithStatusJSON(code, gin.H{"error": err.Error()})
|
2018-08-16 18:13:01 +03:00
|
|
|
}
|
2018-05-17 18:35:53 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-15 17:56:36 +03:00
|
|
|
conn.ClientID = GenerateToken()
|
|
|
|
data, status, errr := client.IntegrationModuleEdit(getIntegrationModule(conn.ClientID))
|
2018-05-17 18:35:53 +03:00
|
|
|
if errr.RuntimeErr != nil {
|
2018-08-14 17:49:01 +03:00
|
|
|
c.Error(errr.RuntimeErr)
|
2018-05-17 18:35:53 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-10-24 17:21:55 +03:00
|
|
|
if status == http.StatusPaymentRequired {
|
|
|
|
c.AbortWithStatusJSON(BadRequest("error_payment_mg"))
|
|
|
|
logger.Error(conn.APIURL, status, errr.ApiErr, data)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-05-17 18:35:53 +03:00
|
|
|
if status >= http.StatusBadRequest {
|
2018-08-23 15:52:32 +03:00
|
|
|
c.AbortWithStatusJSON(BadRequest("error_activity_mg"))
|
2018-08-14 17:49:01 +03:00
|
|
|
logger.Error(conn.APIURL, status, errr.ApiErr, data)
|
2018-05-17 18:35:53 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-09-03 11:52:35 +03:00
|
|
|
conn.MGURL = data.Info.MgTransportInfo.EndpointUrl
|
|
|
|
conn.MGToken = data.Info.MgTransportInfo.Token
|
2018-08-14 17:49:01 +03:00
|
|
|
conn.Active = true
|
2018-05-17 18:35:53 +03:00
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
err = conn.createConnection()
|
2018-05-17 18:35:53 +03:00
|
|
|
if err != nil {
|
2018-08-14 17:49:01 +03:00
|
|
|
c.Error(err)
|
2018-05-17 18:35:53 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
c.JSON(
|
|
|
|
http.StatusCreated,
|
|
|
|
gin.H{
|
|
|
|
"url": "/settings/" + conn.ClientID,
|
|
|
|
"message": getLocalizedMessage("successful"),
|
|
|
|
},
|
|
|
|
)
|
2018-05-17 18:35:53 +03:00
|
|
|
}
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
func activityHandler(c *gin.Context) {
|
2018-08-31 16:09:44 +03:00
|
|
|
var (
|
|
|
|
activity v5.Activity
|
|
|
|
systemUrl = c.PostForm("systemUrl")
|
|
|
|
clientId = c.PostForm("clientId")
|
|
|
|
)
|
2018-05-17 18:35:53 +03:00
|
|
|
|
2018-08-31 16:09:44 +03:00
|
|
|
conn := getConnection(clientId)
|
|
|
|
if conn.ID == 0 {
|
|
|
|
c.AbortWithStatusJSON(http.StatusBadRequest,
|
|
|
|
gin.H{
|
|
|
|
"success": false,
|
|
|
|
"error": "Wrong data",
|
|
|
|
},
|
|
|
|
)
|
2018-05-17 18:35:53 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-31 16:09:44 +03:00
|
|
|
err := json.Unmarshal([]byte(c.PostForm("activity")), &activity)
|
|
|
|
if err != nil {
|
2018-08-17 13:36:25 +03:00
|
|
|
c.AbortWithStatusJSON(http.StatusBadRequest,
|
2018-08-14 17:49:01 +03:00
|
|
|
gin.H{
|
|
|
|
"success": false,
|
|
|
|
"error": "Wrong data",
|
|
|
|
},
|
|
|
|
)
|
2018-05-24 17:16:21 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-31 16:09:44 +03:00
|
|
|
conn.Active = activity.Active && !activity.Freeze
|
|
|
|
|
|
|
|
if systemUrl != "" {
|
|
|
|
conn.APIURL = systemUrl
|
|
|
|
}
|
2018-05-28 18:16:13 +03:00
|
|
|
|
2018-12-11 16:45:42 +03:00
|
|
|
hashSettings, err := getChannelSettingsHash()
|
|
|
|
if err != nil {
|
|
|
|
logger.Errorf("activityHandler hashSettings apiURl: %s, err: %s", conn.APIURL, err.Error())
|
|
|
|
} else {
|
|
|
|
updateBots(conn, hashSettings)
|
|
|
|
}
|
|
|
|
|
2018-08-31 16:09:44 +03:00
|
|
|
if err := conn.saveConnection(); err != nil {
|
2018-08-14 17:49:01 +03:00
|
|
|
c.Error(err)
|
|
|
|
return
|
2018-05-28 18:16:13 +03:00
|
|
|
}
|
|
|
|
|
2018-08-14 17:49:01 +03:00
|
|
|
c.JSON(http.StatusOK, gin.H{"success": true})
|
2018-05-28 18:16:13 +03:00
|
|
|
}
|
2018-08-15 17:56:36 +03:00
|
|
|
|
2018-09-21 12:48:42 +03:00
|
|
|
func setLangBotHandler(c *gin.Context) {
|
|
|
|
b := c.MustGet("bot").(Bot)
|
|
|
|
cl, err := getBotByToken(b.Token)
|
|
|
|
if err != nil {
|
|
|
|
c.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
cl.Lang = b.Lang
|
|
|
|
|
|
|
|
err = cl.save()
|
|
|
|
if err != nil {
|
|
|
|
c.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{})
|
|
|
|
}
|
|
|
|
|
2018-08-15 17:56:36 +03:00
|
|
|
func getIntegrationModule(clientId string) v5.IntegrationModule {
|
|
|
|
return v5.IntegrationModule{
|
2018-08-16 18:13:01 +03:00
|
|
|
Code: config.TransportInfo.Code,
|
|
|
|
IntegrationCode: config.TransportInfo.Code,
|
2018-08-15 17:56:36 +03:00
|
|
|
Active: true,
|
2018-08-16 18:13:01 +03:00
|
|
|
Name: config.TransportInfo.Name,
|
2018-08-15 17:56:36 +03:00
|
|
|
ClientID: clientId,
|
|
|
|
Logo: fmt.Sprintf(
|
2018-08-16 18:13:01 +03:00
|
|
|
"https://%s%s",
|
2018-08-15 17:56:36 +03:00
|
|
|
config.HTTPServer.Host,
|
2018-08-16 18:13:01 +03:00
|
|
|
config.TransportInfo.LogoPath,
|
2018-08-15 17:56:36 +03:00
|
|
|
),
|
|
|
|
BaseURL: fmt.Sprintf(
|
|
|
|
"https://%s",
|
|
|
|
config.HTTPServer.Host,
|
|
|
|
),
|
|
|
|
AccountURL: fmt.Sprintf(
|
|
|
|
"https://%s/settings/%s",
|
|
|
|
config.HTTPServer.Host,
|
|
|
|
clientId,
|
|
|
|
),
|
|
|
|
Actions: map[string]string{"activity": "/actions/activity"},
|
|
|
|
Integrations: &v5.Integrations{
|
|
|
|
MgTransport: &v5.MgTransport{
|
|
|
|
WebhookUrl: fmt.Sprintf(
|
|
|
|
"https://%s/webhook/",
|
|
|
|
config.HTTPServer.Host,
|
|
|
|
),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2018-08-17 16:31:55 +03:00
|
|
|
|
2018-09-21 12:06:33 +03:00
|
|
|
func getChannelSettings(cid ...uint64) v1.Channel {
|
|
|
|
var channelID uint64
|
|
|
|
|
|
|
|
if len(cid) > 0 {
|
|
|
|
channelID = cid[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
return v1.Channel{
|
|
|
|
ID: channelID,
|
|
|
|
Type: Type,
|
|
|
|
Settings: v1.ChannelSettings{
|
|
|
|
SpamAllowed: false,
|
|
|
|
Status: v1.Status{
|
|
|
|
Delivered: v1.ChannelFeatureSend,
|
|
|
|
Read: v1.ChannelFeatureNone,
|
|
|
|
},
|
|
|
|
Text: v1.ChannelSettingsText{
|
2018-12-06 15:33:46 +03:00
|
|
|
Creating: v1.ChannelFeatureBoth,
|
|
|
|
Editing: v1.ChannelFeatureBoth,
|
|
|
|
Quoting: v1.ChannelFeatureBoth,
|
|
|
|
Deleting: v1.ChannelFeatureReceive,
|
|
|
|
MaxCharsCount: MaxCharsCount,
|
2018-09-21 12:06:33 +03:00
|
|
|
},
|
|
|
|
Product: v1.Product{
|
|
|
|
Creating: v1.ChannelFeatureReceive,
|
|
|
|
Editing: v1.ChannelFeatureReceive,
|
|
|
|
},
|
|
|
|
Order: v1.Order{
|
|
|
|
Creating: v1.ChannelFeatureReceive,
|
|
|
|
Editing: v1.ChannelFeatureReceive,
|
|
|
|
},
|
2018-11-28 16:17:13 +03:00
|
|
|
File: v1.ChannelSettingsFilesBase{
|
|
|
|
Creating: v1.ChannelFeatureBoth,
|
|
|
|
Editing: v1.ChannelFeatureBoth,
|
|
|
|
Quoting: v1.ChannelFeatureBoth,
|
|
|
|
Deleting: v1.ChannelFeatureReceive,
|
|
|
|
Max: 1,
|
|
|
|
},
|
|
|
|
Image: v1.ChannelSettingsFilesBase{
|
|
|
|
Creating: v1.ChannelFeatureBoth,
|
|
|
|
Editing: v1.ChannelFeatureBoth,
|
|
|
|
Quoting: v1.ChannelFeatureBoth,
|
|
|
|
Deleting: v1.ChannelFeatureReceive,
|
|
|
|
Max: 10,
|
|
|
|
},
|
2018-09-21 12:06:33 +03:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func updateChannelsSettings() {
|
|
|
|
hashSettings, err := getChannelSettingsHash()
|
|
|
|
if err != nil {
|
|
|
|
logger.Error(err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
connections := getConnections()
|
|
|
|
if len(connections) > 0 {
|
|
|
|
for _, conn := range connections {
|
|
|
|
if !conn.Active {
|
|
|
|
logger.Infof(
|
|
|
|
"updateChannelsSettings connection %s deactivated",
|
|
|
|
conn.APIURL,
|
|
|
|
)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
updateBots(conn, hashSettings)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func updateBots(conn *Connection, hashSettings string) {
|
2019-01-17 12:28:51 +03:00
|
|
|
var channelIDs []uint64
|
2018-09-21 12:06:33 +03:00
|
|
|
bots := conn.getBotsByClientID()
|
2019-01-17 12:28:51 +03:00
|
|
|
|
2018-09-21 12:06:33 +03:00
|
|
|
if len(bots) > 0 {
|
|
|
|
client := v1.New(conn.MGURL, conn.MGToken)
|
2018-09-28 16:06:42 +03:00
|
|
|
client.Debug = config.Debug
|
2018-09-21 12:06:33 +03:00
|
|
|
for _, bot := range bots {
|
2019-01-17 12:28:51 +03:00
|
|
|
channelIDs = append(channelIDs, bot.Channel)
|
2018-09-21 12:06:33 +03:00
|
|
|
if bot.ChannelSettingsHash == hashSettings {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2018-09-24 17:47:44 +03:00
|
|
|
channelSettings := getChannelSettings(bot.Channel)
|
|
|
|
if bot.Name != "" {
|
|
|
|
channelSettings.Name = "@" + bot.Name
|
|
|
|
}
|
|
|
|
|
|
|
|
data, status, err := client.UpdateTransportChannel(channelSettings)
|
2018-09-21 12:06:33 +03:00
|
|
|
if config.Debug {
|
|
|
|
logger.Infof(
|
|
|
|
"updateChannelsSettings apiURL: %s, ChannelID: %d, Data: %v, Status: %d, err: %v",
|
|
|
|
conn.APIURL, bot.Channel, data, status, err,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
bot.ChannelSettingsHash = hashSettings
|
|
|
|
err = bot.save()
|
|
|
|
if err != nil {
|
|
|
|
logger.Error(
|
|
|
|
"updateChannelsSettings bot.save apiURL: %s, bot.Channel: %d , err: %v",
|
|
|
|
conn.APIURL, bot.Channel, err,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-01-17 12:28:51 +03:00
|
|
|
|
2019-01-18 10:38:01 +03:00
|
|
|
deactivateChannels(client, channelIDs)
|
2018-09-21 12:06:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-01-18 10:38:01 +03:00
|
|
|
func deactivateChannels(client *v1.MgClient, channelIDs []uint64) {
|
2019-01-17 12:28:51 +03:00
|
|
|
channelListItems, status, err := client.TransportChannels(v1.Channels{Active: true})
|
|
|
|
if config.Debug {
|
|
|
|
logger.Debugf(
|
|
|
|
"TransportChannels ChannelListItems: %+v, Status: %d, err: %v",
|
|
|
|
channelListItems, status, err,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(channelListItems) > 0 {
|
|
|
|
for _, channel := range channelIDs {
|
|
|
|
for key, ch := range channelListItems {
|
|
|
|
if channel == ch.ID {
|
|
|
|
if len(channelListItems) == 1 {
|
|
|
|
channelListItems = channelListItems[:0]
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
channelListItems = append(channelListItems[:key], channelListItems[key+1:]...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(channelListItems) > 0 {
|
|
|
|
for _, ch := range channelListItems {
|
|
|
|
channelListItems, status, err := client.DeactivateTransportChannel(ch.ID)
|
|
|
|
if config.Debug {
|
|
|
|
logger.Debugf(
|
|
|
|
"DeactivateTransportChannel ChannelListItems: %+v, Status: %d, err: %v",
|
|
|
|
channelListItems, status, err,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-17 16:31:55 +03:00
|
|
|
func telegramWebhookHandler(c *gin.Context) {
|
2018-10-12 13:39:55 +03:00
|
|
|
b := c.MustGet("bot").(Bot)
|
2018-08-17 16:31:55 +03:00
|
|
|
|
|
|
|
conn := getConnectionById(b.ConnectionID)
|
|
|
|
if !conn.Active {
|
|
|
|
c.AbortWithStatus(http.StatusOK)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var update tgbotapi.Update
|
|
|
|
if err := c.ShouldBindJSON(&update); err != nil {
|
|
|
|
c.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.Debug {
|
2018-10-10 16:58:12 +03:00
|
|
|
logger.Debugf(
|
|
|
|
"mgWebhookHandler request:\nUpdateID: %v,\nMessage: %+v,\nEditedMessage: %+v",
|
|
|
|
update.UpdateID, update.Message, update.EditedMessage,
|
|
|
|
)
|
2018-08-17 16:31:55 +03:00
|
|
|
}
|
|
|
|
|
2020-03-02 13:53:53 +03:00
|
|
|
if update.Message != nil && shouldMessageBeIgnored(update.Message) {
|
|
|
|
logger.Infof("telegramWebhookHandler ignoring unprocessable message %+v", update.Message)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-17 16:31:55 +03:00
|
|
|
var client = v1.New(conn.MGURL, conn.MGToken)
|
2018-09-28 16:06:42 +03:00
|
|
|
client.Debug = config.Debug
|
2018-08-17 16:31:55 +03:00
|
|
|
|
|
|
|
if update.Message != nil {
|
|
|
|
nickname := update.Message.From.UserName
|
|
|
|
user := getUserByExternalID(update.Message.From.ID)
|
|
|
|
|
|
|
|
if update.Message.From.UserName == "" {
|
|
|
|
nickname = update.Message.From.FirstName
|
|
|
|
}
|
|
|
|
|
|
|
|
if user.Expired(config.UpdateInterval) || user.ID == 0 {
|
|
|
|
fileID, fileURL, err := GetFileIDAndURL(b.Token, update.Message.From.ID)
|
|
|
|
if err != nil {
|
|
|
|
c.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if fileID != user.UserPhotoID && fileURL != "" {
|
|
|
|
picURL, err := UploadUserAvatar(fileURL)
|
|
|
|
if err != nil {
|
|
|
|
c.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
user.UserPhotoID = fileID
|
|
|
|
user.UserPhotoURL = picURL
|
|
|
|
}
|
|
|
|
|
|
|
|
if user.ExternalID == 0 {
|
|
|
|
user.ExternalID = update.Message.From.ID
|
|
|
|
}
|
|
|
|
|
|
|
|
err = user.save()
|
|
|
|
if err != nil {
|
|
|
|
c.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lang := update.Message.From.LanguageCode
|
|
|
|
|
|
|
|
if len(update.Message.From.LanguageCode) > 2 {
|
|
|
|
lang = update.Message.From.LanguageCode[:2]
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.Debug {
|
2018-10-10 16:58:12 +03:00
|
|
|
logger.Debugf("telegramWebhookHandler user %+v", user)
|
2018-08-17 16:31:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
snd := v1.SendData{
|
2018-09-12 11:24:44 +03:00
|
|
|
Message: v1.Message{
|
|
|
|
ExternalID: strconv.Itoa(update.Message.MessageID),
|
|
|
|
Type: "text",
|
|
|
|
Text: update.Message.Text,
|
2018-08-17 16:31:55 +03:00
|
|
|
},
|
2019-03-19 10:33:20 +03:00
|
|
|
Originator: v1.OriginatorCustomer,
|
|
|
|
Customer: v1.Customer{
|
2018-08-17 16:31:55 +03:00
|
|
|
ExternalID: strconv.Itoa(update.Message.From.ID),
|
|
|
|
Nickname: nickname,
|
|
|
|
Firstname: update.Message.From.FirstName,
|
|
|
|
Avatar: user.UserPhotoURL,
|
|
|
|
Lastname: update.Message.From.LastName,
|
|
|
|
Language: lang,
|
|
|
|
},
|
|
|
|
Channel: b.Channel,
|
|
|
|
ExternalChatID: strconv.FormatInt(update.Message.Chat.ID, 10),
|
|
|
|
}
|
|
|
|
|
|
|
|
if update.Message.ReplyToMessage != nil {
|
|
|
|
snd.Quote = &v1.SendMessageRequestQuote{ExternalID: strconv.Itoa(update.Message.ReplyToMessage.MessageID)}
|
|
|
|
}
|
|
|
|
|
2018-11-28 16:17:13 +03:00
|
|
|
if snd.Message.Text == "" {
|
|
|
|
setLocale(update.Message.From.LanguageCode)
|
|
|
|
|
2019-08-26 14:45:03 +03:00
|
|
|
err := setAttachment(update.Message, client, &snd, b.Token)
|
2018-11-28 16:17:13 +03:00
|
|
|
if err != nil {
|
|
|
|
logger.Error(client.Token, err.Error())
|
|
|
|
c.AbortWithStatus(http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-17 16:31:55 +03:00
|
|
|
data, st, err := client.Messages(snd)
|
|
|
|
if err != nil {
|
|
|
|
logger.Error(b.Token, err.Error(), st, data)
|
2018-12-20 15:03:18 +03:00
|
|
|
|
|
|
|
if update.Message.ReplyToMessage != nil {
|
|
|
|
c.AbortWithStatus(http.StatusOK)
|
2019-08-06 10:33:11 +03:00
|
|
|
} else if st == http.StatusBadRequest && err.Error() == "Message with passed external_id already exists" {
|
|
|
|
logger.Errorf("Message with externalId '%s' is already exists - ignoring it", snd.Message.ExternalID)
|
|
|
|
c.JSON(http.StatusOK, gin.H{})
|
2018-12-20 15:03:18 +03:00
|
|
|
} else {
|
|
|
|
c.Error(err)
|
|
|
|
}
|
|
|
|
|
2018-08-17 16:31:55 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.Debug {
|
2018-10-10 16:58:12 +03:00
|
|
|
logger.Debugf("telegramWebhookHandler Type: SendMessage, Bot: %v, Message: %+v, Response: %+v", b.ID, snd, data)
|
2018-08-17 16:31:55 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if update.EditedMessage != nil {
|
|
|
|
if update.EditedMessage.Text == "" {
|
2019-06-11 17:32:17 +03:00
|
|
|
if getMessageID(update.EditedMessage) != "undefined" {
|
|
|
|
if config.Debug {
|
|
|
|
logger.Debug(b.Token, update.EditedMessage, "Only text messages can be updated")
|
|
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{})
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-08-17 16:31:55 +03:00
|
|
|
setLocale(update.EditedMessage.From.LanguageCode)
|
|
|
|
update.EditedMessage.Text = getLocalizedMessage(getMessageID(update.Message))
|
|
|
|
}
|
|
|
|
|
2018-11-28 16:17:13 +03:00
|
|
|
snd := v1.EditMessageRequest{
|
|
|
|
Message: v1.EditMessageRequestMessage{
|
|
|
|
ExternalID: strconv.Itoa(update.EditedMessage.MessageID),
|
|
|
|
Text: update.EditedMessage.Text,
|
2018-08-17 16:31:55 +03:00
|
|
|
},
|
|
|
|
Channel: b.Channel,
|
|
|
|
}
|
|
|
|
|
|
|
|
data, st, err := client.UpdateMessages(snd)
|
|
|
|
if err != nil {
|
|
|
|
logger.Error(b.Token, err.Error(), st, data)
|
|
|
|
c.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.Debug {
|
|
|
|
logger.Debugf("telegramWebhookHandler Type: UpdateMessage, Bot: %v, Message: %v, Response: %v", b.ID, snd, data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{})
|
|
|
|
}
|
|
|
|
|
|
|
|
func mgWebhookHandler(c *gin.Context) {
|
2018-10-12 13:39:55 +03:00
|
|
|
conn := c.MustGet("connection").(Connection)
|
2018-08-17 16:31:55 +03:00
|
|
|
|
|
|
|
var msg v1.WebhookRequest
|
|
|
|
if err := c.ShouldBindJSON(&msg); err != nil {
|
|
|
|
c.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.Debug {
|
2018-10-10 16:58:12 +03:00
|
|
|
logger.Debugf("mgWebhookHandler request: %+v", msg)
|
2018-08-17 16:31:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
uid, _ := strconv.Atoi(msg.Data.ExternalMessageID)
|
|
|
|
cid, _ := strconv.ParseInt(msg.Data.ExternalChatID, 10, 64)
|
|
|
|
|
|
|
|
b := getBot(conn.ID, msg.Data.ChannelID)
|
|
|
|
if b.ID == 0 {
|
|
|
|
c.AbortWithStatus(http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
bot, err := tgbotapi.NewBotAPI(b.Token)
|
|
|
|
if err != nil {
|
2018-08-20 13:51:45 +03:00
|
|
|
logger.Error(b, err)
|
|
|
|
c.AbortWithStatus(http.StatusBadRequest)
|
2018-08-17 16:31:55 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-09-28 16:06:42 +03:00
|
|
|
bot.Debug = config.Debug
|
2018-09-21 12:48:42 +03:00
|
|
|
setLocale(b.Lang)
|
2018-11-28 16:17:13 +03:00
|
|
|
mgClient := v1.New(conn.MGURL, conn.MGToken)
|
2018-09-21 12:48:42 +03:00
|
|
|
|
2018-09-13 16:32:50 +03:00
|
|
|
switch msg.Type {
|
|
|
|
case "message_sent":
|
2018-09-13 17:25:06 +03:00
|
|
|
var mb string
|
2018-11-28 16:17:13 +03:00
|
|
|
var m tgbotapi.Chattable
|
|
|
|
|
2018-09-21 12:25:31 +03:00
|
|
|
switch msg.Data.Type {
|
|
|
|
case v1.MsgTypeProduct:
|
2018-11-06 13:55:34 +03:00
|
|
|
mb = fmt.Sprintf("*%s*\n", replaceMarkdownSymbols(msg.Data.Product.Name))
|
2018-09-19 16:34:13 +03:00
|
|
|
|
2018-09-13 17:25:06 +03:00
|
|
|
if msg.Data.Product.Cost != nil && msg.Data.Product.Cost.Value != 0 {
|
|
|
|
mb += fmt.Sprintf(
|
2018-09-21 12:48:42 +03:00
|
|
|
"\n%s: %s\n",
|
2018-09-21 12:25:31 +03:00
|
|
|
getLocalizedMessage("item_cost"),
|
|
|
|
getLocalizedTemplateMessage(
|
|
|
|
"cost_currency",
|
|
|
|
map[string]interface{}{
|
2018-09-21 12:48:42 +03:00
|
|
|
"Amount": msg.Data.Product.Cost.Value,
|
|
|
|
"Currency": currency[strings.ToLower(msg.Data.Product.Cost.Currency)],
|
2018-09-21 12:25:31 +03:00
|
|
|
},
|
|
|
|
),
|
2018-09-13 17:25:06 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2018-09-19 16:34:13 +03:00
|
|
|
if msg.Data.Product.Url != "" {
|
2018-11-06 13:55:34 +03:00
|
|
|
mb += replaceMarkdownSymbols(msg.Data.Product.Url)
|
2018-09-19 16:34:13 +03:00
|
|
|
} else {
|
2018-11-06 13:55:34 +03:00
|
|
|
mb += replaceMarkdownSymbols(msg.Data.Product.Img)
|
2018-09-13 17:25:06 +03:00
|
|
|
}
|
2018-09-21 12:25:31 +03:00
|
|
|
case v1.MsgTypeOrder:
|
|
|
|
mb = getOrderMessage(msg.Data.Order)
|
|
|
|
case v1.MsgTypeText:
|
2018-11-20 12:19:04 +03:00
|
|
|
mb = replaceMarkdownSymbols(msg.Data.Content)
|
2018-11-28 16:17:13 +03:00
|
|
|
case v1.MsgTypeImage:
|
2019-01-30 15:36:15 +03:00
|
|
|
m, err = photoMessage(msg.Data, mgClient, cid)
|
2018-11-28 16:17:13 +03:00
|
|
|
if err != nil {
|
|
|
|
logger.Errorf(
|
|
|
|
"GetFile request apiURL: %s, clientID: %s, err: %s",
|
|
|
|
conn.APIURL, conn.ClientID, err.Error(),
|
|
|
|
)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
case v1.MsgTypeFile:
|
|
|
|
items := *msg.Data.Items
|
|
|
|
if len(items) > 0 {
|
|
|
|
m, err = documentMessage(items[0], mgClient, cid)
|
|
|
|
if err != nil {
|
|
|
|
logger.Errorf(
|
|
|
|
"GetFile request apiURL: %s, clientID: %s, err: %s",
|
|
|
|
conn.APIURL, conn.ClientID, err.Error(),
|
|
|
|
)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2018-09-13 17:25:06 +03:00
|
|
|
}
|
|
|
|
|
2018-11-28 16:17:13 +03:00
|
|
|
if mb != "" {
|
|
|
|
m, err = textMessage(cid, mb, msg.Data.QuoteExternalID)
|
2018-08-17 16:31:55 +03:00
|
|
|
if err != nil {
|
|
|
|
c.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
msgSend, err := bot.Send(m)
|
|
|
|
if err != nil {
|
|
|
|
logger.Error(err)
|
|
|
|
c.AbortWithStatus(http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.Debug {
|
2018-10-10 16:58:12 +03:00
|
|
|
logger.Debugf("mgWebhookHandler sent %+v", msgSend)
|
2018-08-17 16:31:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{"external_message_id": strconv.Itoa(msgSend.MessageID)})
|
|
|
|
|
2018-09-13 16:32:50 +03:00
|
|
|
case "message_updated":
|
2018-11-20 12:19:04 +03:00
|
|
|
msgSend, err := bot.Send(tgbotapi.NewEditMessageText(cid, uid, replaceMarkdownSymbols(msg.Data.Content)))
|
2018-08-17 16:31:55 +03:00
|
|
|
if err != nil {
|
|
|
|
logger.Error(err)
|
|
|
|
c.AbortWithStatus(http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.Debug {
|
2018-10-10 16:58:12 +03:00
|
|
|
logger.Debugf("mgWebhookHandler update %+v", msgSend)
|
2018-08-17 16:31:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
c.AbortWithStatus(http.StatusOK)
|
|
|
|
|
2018-09-13 16:32:50 +03:00
|
|
|
case "message_deleted":
|
2018-08-17 16:31:55 +03:00
|
|
|
msgSend, err := bot.Send(tgbotapi.NewDeleteMessage(cid, uid))
|
|
|
|
if err != nil {
|
|
|
|
logger.Error(err)
|
|
|
|
c.AbortWithStatus(http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if config.Debug {
|
2018-10-10 16:58:12 +03:00
|
|
|
logger.Debugf("mgWebhookHandler delete %+v", msgSend)
|
2018-08-17 16:31:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{})
|
|
|
|
}
|
|
|
|
}
|
2018-09-21 12:25:31 +03:00
|
|
|
|
|
|
|
func getOrderMessage(dataOrder *v1.MessageDataOrder) string {
|
2018-09-24 17:31:31 +03:00
|
|
|
mb := "*" + getLocalizedMessage("order")
|
2018-09-21 12:25:31 +03:00
|
|
|
|
|
|
|
if dataOrder.Number != "" {
|
2018-11-06 13:55:34 +03:00
|
|
|
mb += " " + replaceMarkdownSymbols(dataOrder.Number)
|
2018-09-21 12:25:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if dataOrder.Date != "" {
|
|
|
|
mb += fmt.Sprintf(" (%s)", dataOrder.Date)
|
|
|
|
}
|
2018-09-24 17:31:31 +03:00
|
|
|
mb += "*\n"
|
2018-09-21 12:25:31 +03:00
|
|
|
if len(dataOrder.Items) > 0 {
|
|
|
|
mb += "\n"
|
|
|
|
for k, v := range dataOrder.Items {
|
|
|
|
mb += fmt.Sprintf(
|
2018-09-21 19:27:15 +03:00
|
|
|
"%d. %s",
|
2018-09-21 12:25:31 +03:00
|
|
|
k+1,
|
2018-11-06 13:55:34 +03:00
|
|
|
replaceMarkdownSymbols(v.Name),
|
2018-09-21 12:25:31 +03:00
|
|
|
)
|
2018-09-21 19:27:15 +03:00
|
|
|
|
|
|
|
if v.Quantity != nil {
|
|
|
|
if v.Quantity.Value != 0 {
|
|
|
|
mb += fmt.Sprintf(
|
2018-09-24 17:31:31 +03:00
|
|
|
" _%v_",
|
2018-09-21 19:27:15 +03:00
|
|
|
v.Quantity.Value,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if v.Price != nil {
|
|
|
|
if val, ok := currency[strings.ToLower(v.Price.Currency)]; ok {
|
|
|
|
mb += fmt.Sprintf(
|
2018-09-24 17:31:31 +03:00
|
|
|
" _x %s_\n",
|
2018-09-21 19:27:15 +03:00
|
|
|
getLocalizedTemplateMessage(
|
|
|
|
"cost_currency",
|
|
|
|
map[string]interface{}{
|
|
|
|
"Amount": v.Price.Value,
|
|
|
|
"Currency": val,
|
|
|
|
},
|
|
|
|
),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
mb += "\n"
|
|
|
|
}
|
2018-09-21 12:25:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-26 17:12:35 +03:00
|
|
|
if dataOrder.Delivery != nil {
|
|
|
|
if dataOrder.Delivery.Name != "" {
|
|
|
|
mb += fmt.Sprintf(
|
|
|
|
"\n*%s:*\n%s",
|
|
|
|
getLocalizedMessage("delivery"),
|
2018-11-06 13:55:34 +03:00
|
|
|
replaceMarkdownSymbols(dataOrder.Delivery.Name),
|
2018-09-26 17:12:35 +03:00
|
|
|
)
|
|
|
|
}
|
2018-09-21 19:27:15 +03:00
|
|
|
|
2018-09-26 17:12:35 +03:00
|
|
|
if dataOrder.Delivery.Price != nil {
|
|
|
|
if val, ok := currency[strings.ToLower(dataOrder.Delivery.Price.Currency)]; ok && dataOrder.Delivery.Price.Value != 0 {
|
2018-09-21 19:27:15 +03:00
|
|
|
mb += fmt.Sprintf(
|
|
|
|
"; %s",
|
|
|
|
getLocalizedTemplateMessage(
|
|
|
|
"cost_currency",
|
|
|
|
map[string]interface{}{
|
2018-09-26 17:12:35 +03:00
|
|
|
"Amount": dataOrder.Delivery.Price.Value,
|
2018-09-21 19:27:15 +03:00
|
|
|
"Currency": val,
|
|
|
|
},
|
|
|
|
),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2018-09-21 12:25:31 +03:00
|
|
|
|
|
|
|
if dataOrder.Delivery.Address != "" {
|
2018-11-06 13:55:34 +03:00
|
|
|
mb += ";\n" + replaceMarkdownSymbols(dataOrder.Delivery.Address)
|
2018-09-21 12:25:31 +03:00
|
|
|
}
|
|
|
|
|
2019-07-16 09:22:26 +03:00
|
|
|
if dataOrder.Delivery.Comment != "" {
|
|
|
|
mb += ";\n" + replaceMarkdownSymbols(dataOrder.Delivery.Comment)
|
|
|
|
}
|
|
|
|
|
2018-09-21 12:25:31 +03:00
|
|
|
mb += "\n"
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(dataOrder.Payments) > 0 {
|
|
|
|
mb += fmt.Sprintf(
|
2018-09-24 17:31:31 +03:00
|
|
|
"\n*%s:*\n",
|
2018-09-21 12:25:31 +03:00
|
|
|
getLocalizedMessage("payment"),
|
|
|
|
)
|
|
|
|
for _, v := range dataOrder.Payments {
|
2018-11-06 13:55:34 +03:00
|
|
|
mb += replaceMarkdownSymbols(v.Name)
|
2018-09-21 19:27:15 +03:00
|
|
|
|
|
|
|
if v.Amount != nil {
|
|
|
|
if val, ok := currency[strings.ToLower(v.Amount.Currency)]; ok && v.Amount.Value != 0 {
|
|
|
|
mb += fmt.Sprintf(
|
|
|
|
"; %s",
|
|
|
|
getLocalizedTemplateMessage(
|
|
|
|
"cost_currency",
|
|
|
|
map[string]interface{}{
|
|
|
|
"Amount": v.Amount.Value,
|
|
|
|
"Currency": val,
|
|
|
|
},
|
|
|
|
),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2018-09-21 12:25:31 +03:00
|
|
|
|
|
|
|
if v.Status != nil && v.Status.Name != "" {
|
|
|
|
mb += fmt.Sprintf(
|
|
|
|
" (%s)",
|
2018-11-06 13:55:34 +03:00
|
|
|
replaceMarkdownSymbols(v.Status.Name),
|
2018-09-21 12:25:31 +03:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
mb += "\n"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-21 19:27:15 +03:00
|
|
|
if dataOrder.Cost != nil {
|
|
|
|
if val, ok := currency[strings.ToLower(dataOrder.Cost.Currency)]; ok && dataOrder.Cost.Value != 0 {
|
|
|
|
mb += fmt.Sprintf(
|
|
|
|
"\n%s: %s",
|
|
|
|
getLocalizedMessage("order_total"),
|
|
|
|
getLocalizedTemplateMessage(
|
|
|
|
"cost_currency",
|
|
|
|
map[string]interface{}{
|
|
|
|
"Amount": dataOrder.Cost.Value,
|
|
|
|
"Currency": val,
|
|
|
|
},
|
|
|
|
),
|
|
|
|
)
|
|
|
|
}
|
2018-09-21 12:25:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return mb
|
|
|
|
}
|
2018-11-28 16:17:13 +03:00
|
|
|
|
2019-01-30 15:36:15 +03:00
|
|
|
func photoMessage(webhookData v1.WebhookData, mgClient *v1.MgClient, cid int64) (chattable tgbotapi.Chattable, err error) {
|
|
|
|
items := *webhookData.Items
|
|
|
|
|
2018-11-28 16:17:13 +03:00
|
|
|
if len(items) == 1 {
|
|
|
|
v := items
|
|
|
|
|
|
|
|
file, _, err := mgClient.GetFile(v[0].ID)
|
|
|
|
if err != nil {
|
|
|
|
return chattable, err
|
|
|
|
}
|
|
|
|
|
|
|
|
msg := tgbotapi.NewPhotoUpload(cid, nil)
|
|
|
|
msg.FileID = file.Url
|
|
|
|
msg.UseExisting = true
|
2019-01-30 15:36:15 +03:00
|
|
|
msg.Caption = webhookData.Content
|
2018-11-28 16:17:13 +03:00
|
|
|
|
|
|
|
chattable = msg
|
|
|
|
} else if len(items) > 1 {
|
|
|
|
var it []interface{}
|
|
|
|
|
|
|
|
for _, v := range items {
|
|
|
|
file, _, err := mgClient.GetFile(v.ID)
|
|
|
|
if err != nil {
|
|
|
|
logger.Errorf(
|
|
|
|
"GetFile request fileID: %s, err: %s",
|
|
|
|
v.ID, err.Error(),
|
|
|
|
)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
ip := tgbotapi.NewInputMediaPhoto(file.Url)
|
2019-01-30 15:36:15 +03:00
|
|
|
ip.Caption = webhookData.Content
|
2018-11-28 16:17:13 +03:00
|
|
|
it = append(it, ip)
|
|
|
|
}
|
|
|
|
|
|
|
|
chattable = tgbotapi.NewMediaGroup(cid, it)
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func documentMessage(item v1.FileItem, mgClient *v1.MgClient, cid int64) (chattable tgbotapi.Chattable, err error) {
|
|
|
|
file, _, err := mgClient.GetFile(item.ID)
|
|
|
|
if err != nil {
|
|
|
|
return chattable, err
|
|
|
|
}
|
|
|
|
|
|
|
|
data, err := http.Get(file.Url)
|
|
|
|
if err != nil {
|
|
|
|
return chattable, err
|
|
|
|
}
|
|
|
|
|
|
|
|
tt := tgbotapi.FileReader{
|
|
|
|
Name: item.Caption,
|
|
|
|
Reader: data.Body,
|
|
|
|
Size: int64(item.Size),
|
|
|
|
}
|
|
|
|
|
|
|
|
chattable = tgbotapi.NewDocumentUpload(cid, tt)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func textMessage(cid int64, mb string, quoteExternalID string) (chattable tgbotapi.Chattable, err error) {
|
|
|
|
var qid int
|
|
|
|
m := tgbotapi.NewMessage(cid, mb)
|
|
|
|
|
|
|
|
if quoteExternalID != "" {
|
|
|
|
qid, err = strconv.Atoi(quoteExternalID)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
m.ReplyToMessageID = qid
|
|
|
|
}
|
|
|
|
|
|
|
|
m.ParseMode = "Markdown"
|
|
|
|
|
|
|
|
chattable = m
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-08-26 14:45:03 +03:00
|
|
|
func setAttachment(attachments *tgbotapi.Message, client *v1.MgClient, snd *v1.SendData, botToken string) error {
|
2018-11-28 16:17:13 +03:00
|
|
|
var (
|
2019-01-30 15:36:15 +03:00
|
|
|
items []v1.Item
|
|
|
|
fileID string
|
2018-11-28 16:17:13 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
t := getMessageID(attachments)
|
|
|
|
bot, err := tgbotapi.NewBotAPI(botToken)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2019-01-30 15:36:15 +03:00
|
|
|
caption := getLocalizedMessage(t)
|
|
|
|
|
2018-11-28 16:17:13 +03:00
|
|
|
switch t {
|
|
|
|
case "photo":
|
|
|
|
for _, v := range *attachments.Photo {
|
|
|
|
fileID = v.FileID
|
|
|
|
}
|
|
|
|
|
|
|
|
snd.Message.Type = v1.MsgTypeImage
|
2019-03-19 10:33:20 +03:00
|
|
|
snd.Message.Note = attachments.Caption
|
2019-08-28 11:17:11 +03:00
|
|
|
case "animation":
|
|
|
|
fileID = attachments.Animation.FileID
|
|
|
|
snd.Message.Type = v1.MsgTypeFile
|
|
|
|
caption += ".mp4"
|
2018-11-28 16:17:13 +03:00
|
|
|
case "document":
|
|
|
|
fileID = attachments.Document.FileID
|
|
|
|
snd.Message.Type = v1.MsgTypeFile
|
|
|
|
caption = attachments.Document.FileName
|
2018-11-29 11:46:39 +03:00
|
|
|
case "sticker":
|
|
|
|
fileID = attachments.Sticker.FileID
|
|
|
|
snd.Message.Type = v1.MsgTypeImage
|
2019-08-21 09:24:29 +03:00
|
|
|
case "voice":
|
|
|
|
fileID = attachments.Voice.FileID
|
|
|
|
snd.Message.Type = v1.MsgTypeAudio
|
2018-11-28 16:17:13 +03:00
|
|
|
default:
|
|
|
|
snd.Message.Text = getLocalizedMessage(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
if fileID != "" {
|
|
|
|
file, err := getFileURL(fileID, bot)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2018-12-13 17:31:49 +03:00
|
|
|
item := v1.Item{}
|
|
|
|
fileUrl := fmt.Sprintf("https://api.telegram.org/file/bot%s/%s", botToken, file.FilePath)
|
2019-08-21 09:24:29 +03:00
|
|
|
switch {
|
2019-08-28 11:41:30 +03:00
|
|
|
case t == "sticker" || t == "voice":
|
2018-12-13 17:31:49 +03:00
|
|
|
item, _, err = getItemData(
|
|
|
|
client,
|
|
|
|
fileUrl,
|
|
|
|
caption,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-08-28 11:41:30 +03:00
|
|
|
case t == "animation":
|
|
|
|
item, _, err = getItemData(
|
|
|
|
client,
|
|
|
|
fileUrl,
|
|
|
|
caption,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
item.Caption = item.ID + ".mp4"
|
2019-08-21 09:24:29 +03:00
|
|
|
default:
|
2018-12-13 17:31:49 +03:00
|
|
|
item, err = convertAndUploadImage(
|
|
|
|
client,
|
|
|
|
fileUrl,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-11-28 16:17:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
items = append(items, item)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(items) > 0 {
|
|
|
|
snd.Message.Items = items
|
2019-01-30 15:36:15 +03:00
|
|
|
snd.Message.Text = attachments.Caption
|
2018-11-28 16:17:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func getItemData(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
|
|
|
|
}
|
|
|
|
|
|
|
|
func getFileURL(fileID string, b *tgbotapi.BotAPI) (tgbotapi.File, error) {
|
|
|
|
return b.GetFile(tgbotapi.FileConfig{FileID: fileID})
|
|
|
|
}
|
2018-12-13 17:31:49 +03:00
|
|
|
|
|
|
|
func convertAndUploadImage(client *v1.MgClient, url string) (v1.Item, error) {
|
|
|
|
item := v1.Item{}
|
|
|
|
|
|
|
|
res, err := http.Get(url)
|
|
|
|
if err != nil {
|
|
|
|
return item, err
|
|
|
|
}
|
|
|
|
|
2019-09-02 10:27:01 +03:00
|
|
|
imgByte, err := ioutil.ReadAll(res.Body)
|
2018-12-13 17:31:49 +03:00
|
|
|
if err != nil {
|
|
|
|
return item, err
|
|
|
|
}
|
|
|
|
|
2019-09-02 10:27:01 +03:00
|
|
|
if kind, err := filetype.Match(imgByte); err != nil {
|
|
|
|
return item, err
|
|
|
|
} else if kind == filetypes.TypeWebp {
|
|
|
|
img, err := webp.Decode(res.Body)
|
|
|
|
if err != nil {
|
|
|
|
return item, err
|
|
|
|
}
|
|
|
|
|
|
|
|
pReader, pWriter := io.Pipe()
|
2018-12-13 17:31:49 +03:00
|
|
|
|
2019-09-02 10:27:01 +03:00
|
|
|
go func() {
|
|
|
|
defer pWriter.Close()
|
|
|
|
err = png.Encode(pWriter, img)
|
|
|
|
if err != nil {
|
|
|
|
logger.Info(item, err.Error())
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
data, _, err := client.UploadFile(pReader)
|
2018-12-13 17:31:49 +03:00
|
|
|
if err != nil {
|
2019-09-02 10:27:01 +03:00
|
|
|
return item, err
|
2018-12-13 17:31:49 +03:00
|
|
|
}
|
|
|
|
|
2019-09-02 10:27:01 +03:00
|
|
|
item.ID = data.ID
|
|
|
|
} else {
|
|
|
|
data, _, err := client.UploadFile(bytes.NewReader(imgByte))
|
|
|
|
if err != nil {
|
|
|
|
return item, err
|
|
|
|
}
|
2018-12-13 17:31:49 +03:00
|
|
|
|
2019-09-02 10:27:01 +03:00
|
|
|
item.ID = data.ID
|
|
|
|
}
|
2018-12-13 17:31:49 +03:00
|
|
|
|
|
|
|
return item, nil
|
|
|
|
}
|