diff --git a/bridge/vk/vk.go b/bridge/vk/vk.go index 4e6e9fa5..656f689f 100644 --- a/bridge/vk/vk.go +++ b/bridge/vk/vk.go @@ -18,6 +18,16 @@ import ( "github.com/SevereCloud/vksdk/v2/object" ) +const ( + audioMessage = "audio_message" + document = "doc" + photo = "photo" + video = "video" + graffiti = "graffiti" + sticker = "sticker" + wall = "wall" +) + type user struct { lastname, firstname, avatar string } @@ -38,6 +48,7 @@ func (b *Bvk) Connect() error { lp, err := longpoll.NewLongPoll(b.c, b.GetInt("GroupID")) if err != nil { b.Log.Debugf("%#v", err) + return err } @@ -47,7 +58,12 @@ func (b *Bvk) Connect() error { b.Log.Info("Connection succeeded") - go lp.Run() + go func() { + err := lp.Run() + if err != nil { + b.Log.Fatal("Enable longpoll in group management") + } + }() return nil } @@ -63,69 +79,28 @@ func (b *Bvk) JoinChannel(channel config.ChannelInfo) error { func (b *Bvk) Send(msg config.Message) (string, error) { b.Log.Debugf("=> Receiving %#v", msg) - peerID, err := strconv.ParseInt(msg.Channel, 10, 64) + peerID, err := strconv.Atoi(msg.Channel) if err != nil { return "", err } - text := msg.Username + params := api.Params{} - if msg.Text != "" { - text += msg.Text - } - - params := api.Params{ - "message": text, - } + text := msg.Username + msg.Text if msg.Extra != nil { if len(msg.Extra["file"]) > 0 { // generate attachments string - var attachments []string - - for _, f := range msg.Extra["file"] { - fi := f.(config.FileInfo) - photoRE := regexp.MustCompile(".(jpg|jpe|png)$") - if photoRE.MatchString(fi.Name) { - r := bytes.NewReader(*fi.Data) - photo, err := b.c.UploadMessagesPhoto(int(peerID), r) - if err != nil { - b.Log.Error("Failad uploading photo") - b.Log.Error(err) - } else { - attachments = append(attachments, "photo"+strconv.Itoa(photo[0].OwnerID)+"_"+strconv.Itoa(photo[0].ID)) - if fi.Comment != "" { - text += fi.Comment + "\n" - } - } - } else { - r := bytes.NewReader(*fi.Data) - - var doctype string - if strings.Contains(fi.Name, ".ogg") { - doctype = "audio_message" - } else { - doctype = "doc" - } - - doc, err := b.c.UploadMessagesDoc(int(peerID), doctype, fi.Name, "", r) - if err != nil { - b.Log.Error("Failad uploading file") - b.Log.Error(err) - } else if doc.Type == "audio_message" { - attachments = append(attachments, "doc"+strconv.Itoa(doc.AudioMessage.OwnerID)+"_"+strconv.Itoa(doc.AudioMessage.ID)) - } else if doc.Type == "doc" { - attachments = append(attachments, "doc"+strconv.Itoa(doc.Doc.OwnerID)+"_"+strconv.Itoa(doc.Doc.ID)) - } - } - - } - params["attachment"] = strings.Join(attachments, ",") - params["message"] = text + attachment, urls := b.uploadFiles(msg.Extra, peerID) + params["attachment"] = attachment + text += urls } } + params["message"] = text + if msg.ID == "" { + // New message params["random_id"] = time.Now().Unix() params["peer_ids"] = msg.Channel @@ -135,18 +110,22 @@ func (b *Bvk) Send(msg config.Message) (string, error) { } return strconv.Itoa(res[0].ConversationMessageID), nil - } else { - messageID, err := strconv.ParseInt(msg.ID, 10, 64) - params["peer_id"] = peerID - params["conversation_message_id"] = messageID - - _, err = b.c.MessagesEdit(params) - if err != nil { - return "", err - } - - return msg.ID, nil } + // Edit message + messageID, err := strconv.ParseInt(msg.ID, 10, 64) + if err != nil { + return "", err + } + + params["peer_id"] = peerID + params["conversation_message_id"] = messageID + + _, err = b.c.MessagesEdit(params) + if err != nil { + return "", err + } + + return msg.ID, nil } func (b *Bvk) getUser(id int) user { @@ -202,48 +181,10 @@ func (b *Bvk) handleMessage(msg object.MessagesMessage, isFwd bool) { } if len(msg.Attachments) > 0 { - var urls []string + urls, text := b.getFiles(msg.Attachments) - // get URLs for attachments - for _, a := range msg.Attachments { - if a.Type == "photo" { - var resolution float64 = 0 - url := a.Photo.Sizes[0].URL - for _, size := range a.Photo.Sizes { - r := size.Height * size.Width - if resolution < r { - resolution = r - url = size.URL - } - } - - urls = append(urls, url) - } else if a.Type == "doc" { - urls = append(urls, a.Doc.URL) - } else if a.Type == "graffiti" { - urls = append(urls, a.Graffiti.URL) - } else if a.Type == "audio_message" { - urls = append(urls, a.AudioMessage.DocsDocPreviewAudioMessage.LinkOgg) - } else if a.Type == "sticker" { - var resolution float64 = 0 - url := a.Sticker.Images[0].URL - for _, size := range a.Sticker.Images { - r := size.Height * size.Width - if resolution < r { - resolution = r - url = size.URL - } - } - urls = append(urls, url+".png") - } else if a.Type == "doc" { - urls = append(urls, a.Doc.URL) - } else if a.Type == "video" { - rmsg.Text += "https://vk.com/video" + strconv.Itoa(a.Video.OwnerID) + "_" + strconv.Itoa(a.Video.ID) - } else if a.Type == "wall" { - rmsg.Text += "https://vk.com/wall" + strconv.Itoa(a.Wall.FromID) + "_" + strconv.Itoa(a.Wall.ID) - } else { - rmsg.Text += "This attachment is not supported (" + a.Type + ")" - } + if text != "" { + rmsg.Text += "\n" + text } if b.GetBool("UseFileURL") { @@ -251,14 +192,7 @@ func (b *Bvk) handleMessage(msg object.MessagesMessage, isFwd bool) { rmsg.Text += "\n" + strings.Join(urls, "\n") } else { // download - for _, url := range urls { - data, err := helper.DownloadFile(url) - if err == nil { - urlPart := strings.Split(url, "/") - name := strings.Split(urlPart[len(urlPart)-1], "?")[0] - helper.HandleDownloadData(b.Log, &rmsg, name, "", url, data, b.General) - } - } + b.downloadFiles(&rmsg, urls) } } @@ -276,3 +210,123 @@ func (b *Bvk) handleMessage(msg object.MessagesMessage, isFwd bool) { } } } + +func (b *Bvk) uploadFiles(extra map[string][]interface{}, peerID int) (string, string) { + var attachments []string + text := "" + + for _, f := range extra["file"] { + fi := f.(config.FileInfo) + + if fi.Comment != "" { + text += fi.Comment + "\n" + } + a, err := b.uploadFile(fi, peerID) + if err != nil { + b.Log.Error("File upload error ", fi.Name) + } + + attachments = append(attachments, a) + } + + return strings.Join(attachments, ","), text +} + +func (b *Bvk) uploadFile(file config.FileInfo, peerID int) (string, error) { + r := bytes.NewReader(*file.Data) + + photoRE := regexp.MustCompile(".(jpg|jpe|png)$") + if photoRE.MatchString(file.Name) { + p, err := b.c.UploadMessagesPhoto(peerID, r) + if err != nil { + return "", err + } + + return photo + strconv.Itoa(p[0].OwnerID) + "_" + strconv.Itoa(p[0].ID), nil + } + + var doctype string + if strings.Contains(file.Name, ".ogg") { + doctype = audioMessage + } else { + doctype = document + } + + doc, err := b.c.UploadMessagesDoc(peerID, doctype, file.Name, "", r) + if err != nil { + return "", err + } + + switch doc.Type { + case audioMessage: + return document + strconv.Itoa(doc.AudioMessage.OwnerID) + "_" + strconv.Itoa(doc.AudioMessage.ID), nil + case document: + return document + strconv.Itoa(doc.Doc.OwnerID) + "_" + strconv.Itoa(doc.Doc.ID), nil + } + + return "", nil +} + +func (b *Bvk) getFiles(attachments []object.MessagesMessageAttachment) ([]string, string) { + var urls []string + var text []string + + for _, a := range attachments { + switch a.Type { + case photo: + var resolution float64 = 0 + url := a.Photo.Sizes[0].URL + for _, size := range a.Photo.Sizes { + r := size.Height * size.Width + if resolution < r { + resolution = r + url = size.URL + } + } + + urls = append(urls, url) + + case document: + urls = append(urls, a.Doc.URL) + + case graffiti: + urls = append(urls, a.Graffiti.URL) + + case audioMessage: + urls = append(urls, a.AudioMessage.DocsDocPreviewAudioMessage.LinkOgg) + + case sticker: + var resolution float64 = 0 + url := a.Sticker.Images[0].URL + for _, size := range a.Sticker.Images { + r := size.Height * size.Width + if resolution < r { + resolution = r + url = size.URL + } + } + urls = append(urls, url+".png") + case video: + text = append(text, "https://vk.com/video"+strconv.Itoa(a.Video.OwnerID)+"_"+strconv.Itoa(a.Video.ID)) + + case wall: + text = append(text, "https://vk.com/wall"+strconv.Itoa(a.Wall.FromID)+"_"+strconv.Itoa(a.Wall.ID)) + + default: + text = append(text, "This attachment is not supported ("+a.Type+")") + } + } + + return urls, strings.Join(text, "\n") +} + +func (b *Bvk) downloadFiles(rmsg *config.Message, urls []string) { + for _, url := range urls { + data, err := helper.DownloadFile(url) + if err == nil { + urlPart := strings.Split(url, "/") + name := strings.Split(urlPart[len(urlPart)-1], "?")[0] + helper.HandleDownloadData(b.Log, rmsg, name, "", url, data, b.General) + } + } +}