Merge pull request #56 from DmitryZagorulko/master
add file and images transfer
This commit is contained in:
commit
9d915244e1
4
go.mod
4
go.mod
@ -18,7 +18,7 @@ require (
|
|||||||
github.com/gin-gonic/gin v1.3.0
|
github.com/gin-gonic/gin v1.3.0
|
||||||
github.com/go-ini/ini v1.38.2 // indirect
|
github.com/go-ini/ini v1.38.2 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.4.0 // indirect
|
github.com/go-sql-driver/mysql v1.4.0 // indirect
|
||||||
github.com/go-telegram-bot-api/telegram-bot-api v0.0.0-20180602093832-4c16a90966d1
|
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
|
||||||
github.com/golang-migrate/migrate v3.4.0+incompatible
|
github.com/golang-migrate/migrate v3.4.0+incompatible
|
||||||
github.com/golang/protobuf v1.2.0 // indirect
|
github.com/golang/protobuf v1.2.0 // indirect
|
||||||
github.com/google/go-cmp v0.2.0 // indirect
|
github.com/google/go-cmp v0.2.0 // indirect
|
||||||
@ -45,7 +45,7 @@ require (
|
|||||||
github.com/pkg/errors v0.8.0
|
github.com/pkg/errors v0.8.0
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/retailcrm/api-client-go v1.1.0
|
github.com/retailcrm/api-client-go v1.1.0
|
||||||
github.com/retailcrm/mg-transport-api-client-go v1.1.11
|
github.com/retailcrm/mg-transport-api-client-go v1.1.17
|
||||||
github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf // indirect
|
github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf // indirect
|
||||||
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a // indirect
|
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a // indirect
|
||||||
github.com/stevvooe/resumable v0.0.0-20180830230917-22b14a53ba50 // indirect
|
github.com/stevvooe/resumable v0.0.0-20180830230917-22b14a53ba50 // indirect
|
||||||
|
8
go.sum
8
go.sum
@ -36,8 +36,8 @@ github.com/go-ini/ini v1.38.2 h1:6Hl/z3p3iFkA0dlDfzYxuFuUGD+kaweypF6btsR2/Q4=
|
|||||||
github.com/go-ini/ini v1.38.2/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
github.com/go-ini/ini v1.38.2/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||||
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
|
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
|
||||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
github.com/go-telegram-bot-api/telegram-bot-api v0.0.0-20180602093832-4c16a90966d1 h1:FlRoyZCY3snE+M9jTruqOzPwZg8KIwQBXr//t215K8E=
|
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU=
|
||||||
github.com/go-telegram-bot-api/telegram-bot-api v0.0.0-20180602093832-4c16a90966d1/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
|
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
|
||||||
github.com/golang-migrate/migrate v3.4.0+incompatible h1:9yjg5lYsbeEpWXGc80RylvPMKZ0tZEGsyO3CpYLK3jU=
|
github.com/golang-migrate/migrate v3.4.0+incompatible h1:9yjg5lYsbeEpWXGc80RylvPMKZ0tZEGsyO3CpYLK3jU=
|
||||||
github.com/golang-migrate/migrate v3.4.0+incompatible/go.mod h1:IsVUlFN5puWOmXrqjgGUfIRIbU7mr8oNBE2tyERd9Wk=
|
github.com/golang-migrate/migrate v3.4.0+incompatible/go.mod h1:IsVUlFN5puWOmXrqjgGUfIRIbU7mr8oNBE2tyERd9Wk=
|
||||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||||
@ -95,8 +95,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
|||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/retailcrm/api-client-go v1.1.0 h1:APPO6ccJAeMV7Jz7BhrtDKSOm2r1j5Ft6fuEXNP2ij4=
|
github.com/retailcrm/api-client-go v1.1.0 h1:APPO6ccJAeMV7Jz7BhrtDKSOm2r1j5Ft6fuEXNP2ij4=
|
||||||
github.com/retailcrm/api-client-go v1.1.0/go.mod h1:QRoPE2SM6ST7i2g0yEdqm7Iw98y7cYuq3q14Ot+6N8c=
|
github.com/retailcrm/api-client-go v1.1.0/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.17 h1:8L0meFJFZwr3TyiF/xypI+g0xRXIGkWhyQ6qiCfojqw=
|
||||||
github.com/retailcrm/mg-transport-api-client-go v1.1.11/go.mod h1:AWV6BueE28/6SCoyfKURTo4lF0oXYoOKmHTzehd5vAI=
|
github.com/retailcrm/mg-transport-api-client-go v1.1.17/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 h1:6V1qxN6Usn4jy8unvggSJz/NC790tefw8Zdy6OZS5co=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
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=
|
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a h1:JSvGDIbmil4Ui/dDdFBExb7/cmkNjyX5F97oglmvCDo=
|
||||||
|
225
src/routing.go
225
src/routing.go
@ -343,6 +343,20 @@ func getChannelSettings(cid ...uint64) v1.Channel {
|
|||||||
Creating: v1.ChannelFeatureReceive,
|
Creating: v1.ChannelFeatureReceive,
|
||||||
Editing: v1.ChannelFeatureReceive,
|
Editing: v1.ChannelFeatureReceive,
|
||||||
},
|
},
|
||||||
|
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,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -437,11 +451,6 @@ func telegramWebhookHandler(c *gin.Context) {
|
|||||||
client.Debug = config.Debug
|
client.Debug = config.Debug
|
||||||
|
|
||||||
if update.Message != nil {
|
if update.Message != nil {
|
||||||
if update.Message.Text == "" {
|
|
||||||
setLocale(update.Message.From.LanguageCode)
|
|
||||||
update.Message.Text = getLocalizedMessage(getMessageID(update.Message))
|
|
||||||
}
|
|
||||||
|
|
||||||
nickname := update.Message.From.UserName
|
nickname := update.Message.From.UserName
|
||||||
user := getUserByExternalID(update.Message.From.ID)
|
user := getUserByExternalID(update.Message.From.ID)
|
||||||
|
|
||||||
@ -510,6 +519,17 @@ func telegramWebhookHandler(c *gin.Context) {
|
|||||||
snd.Quote = &v1.SendMessageRequestQuote{ExternalID: strconv.Itoa(update.Message.ReplyToMessage.MessageID)}
|
snd.Quote = &v1.SendMessageRequestQuote{ExternalID: strconv.Itoa(update.Message.ReplyToMessage.MessageID)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if snd.Message.Text == "" {
|
||||||
|
setLocale(update.Message.From.LanguageCode)
|
||||||
|
|
||||||
|
err := setAttachment(update.Message, client, &snd, b.Token)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(client.Token, err.Error())
|
||||||
|
c.AbortWithStatus(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data, st, err := client.Messages(snd)
|
data, st, err := client.Messages(snd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(b.Token, err.Error(), st, data)
|
logger.Error(b.Token, err.Error(), st, data)
|
||||||
@ -528,13 +548,10 @@ func telegramWebhookHandler(c *gin.Context) {
|
|||||||
update.EditedMessage.Text = getLocalizedMessage(getMessageID(update.Message))
|
update.EditedMessage.Text = getLocalizedMessage(getMessageID(update.Message))
|
||||||
}
|
}
|
||||||
|
|
||||||
snd := v1.UpdateData{
|
snd := v1.EditMessageRequest{
|
||||||
Message: v1.UpdateMessage{
|
Message: v1.EditMessageRequestMessage{
|
||||||
Message: v1.Message{
|
ExternalID: strconv.Itoa(update.EditedMessage.MessageID),
|
||||||
ExternalID: strconv.Itoa(update.EditedMessage.MessageID),
|
Text: update.EditedMessage.Text,
|
||||||
Type: "text",
|
|
||||||
Text: update.EditedMessage.Text,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Channel: b.Channel,
|
Channel: b.Channel,
|
||||||
}
|
}
|
||||||
@ -585,10 +602,13 @@ func mgWebhookHandler(c *gin.Context) {
|
|||||||
|
|
||||||
bot.Debug = config.Debug
|
bot.Debug = config.Debug
|
||||||
setLocale(b.Lang)
|
setLocale(b.Lang)
|
||||||
|
mgClient := v1.New(conn.MGURL, conn.MGToken)
|
||||||
|
|
||||||
switch msg.Type {
|
switch msg.Type {
|
||||||
case "message_sent":
|
case "message_sent":
|
||||||
var mb string
|
var mb string
|
||||||
|
var m tgbotapi.Chattable
|
||||||
|
|
||||||
switch msg.Data.Type {
|
switch msg.Data.Type {
|
||||||
case v1.MsgTypeProduct:
|
case v1.MsgTypeProduct:
|
||||||
mb = fmt.Sprintf("*%s*\n", replaceMarkdownSymbols(msg.Data.Product.Name))
|
mb = fmt.Sprintf("*%s*\n", replaceMarkdownSymbols(msg.Data.Product.Name))
|
||||||
@ -616,20 +636,37 @@ func mgWebhookHandler(c *gin.Context) {
|
|||||||
mb = getOrderMessage(msg.Data.Order)
|
mb = getOrderMessage(msg.Data.Order)
|
||||||
case v1.MsgTypeText:
|
case v1.MsgTypeText:
|
||||||
mb = replaceMarkdownSymbols(msg.Data.Content)
|
mb = replaceMarkdownSymbols(msg.Data.Content)
|
||||||
|
case v1.MsgTypeImage:
|
||||||
|
m, err = photoMessage(*msg.Data.Items, mgClient, cid)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m := tgbotapi.NewMessage(cid, mb)
|
if mb != "" {
|
||||||
if msg.Data.QuoteExternalID != "" {
|
m, err = textMessage(cid, mb, msg.Data.QuoteExternalID)
|
||||||
qid, err := strconv.Atoi(msg.Data.QuoteExternalID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Error(err)
|
c.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
m.ReplyToMessageID = qid
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m.ParseMode = "Markdown"
|
|
||||||
|
|
||||||
msgSend, err := bot.Send(m)
|
msgSend, err := bot.Send(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
@ -805,3 +842,155 @@ func getOrderMessage(dataOrder *v1.MessageDataOrder) string {
|
|||||||
|
|
||||||
return mb
|
return mb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func photoMessage(items []v1.FileItem, mgClient *v1.MgClient, cid int64) (chattable tgbotapi.Chattable, err error) {
|
||||||
|
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
|
||||||
|
|
||||||
|
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)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func setAttachment(attachments *tgbotapi.Message, client *v1.MgClient, snd *v1.SendData, botToken string) error {
|
||||||
|
var (
|
||||||
|
items []v1.Item
|
||||||
|
fileID string
|
||||||
|
caption string
|
||||||
|
)
|
||||||
|
|
||||||
|
t := getMessageID(attachments)
|
||||||
|
bot, err := tgbotapi.NewBotAPI(botToken)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch t {
|
||||||
|
case "photo":
|
||||||
|
for _, v := range *attachments.Photo {
|
||||||
|
fileID = v.FileID
|
||||||
|
}
|
||||||
|
|
||||||
|
snd.Message.Type = v1.MsgTypeImage
|
||||||
|
caption = getLocalizedMessage(t)
|
||||||
|
case "document":
|
||||||
|
fileID = attachments.Document.FileID
|
||||||
|
snd.Message.Type = v1.MsgTypeFile
|
||||||
|
caption = attachments.Document.FileName
|
||||||
|
default:
|
||||||
|
snd.Message.Text = getLocalizedMessage(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileID != "" {
|
||||||
|
file, err := getFileURL(fileID, bot)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
item, _, err := getItemData(
|
||||||
|
client,
|
||||||
|
fmt.Sprintf("https://api.telegram.org/file/bot%s/%s", botToken, file.FilePath),
|
||||||
|
caption,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
items = append(items, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(items) > 0 {
|
||||||
|
snd.Message.Items = items
|
||||||
|
}
|
||||||
|
|
||||||
|
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})
|
||||||
|
}
|
||||||
|
@ -79,6 +79,20 @@ func TestRouting_addBotHandler(t *testing.T) {
|
|||||||
Creating: v1.ChannelFeatureReceive,
|
Creating: v1.ChannelFeatureReceive,
|
||||||
Editing: v1.ChannelFeatureReceive,
|
Editing: v1.ChannelFeatureReceive,
|
||||||
},
|
},
|
||||||
|
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,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user