summaryrefslogtreecommitdiffstats
path: root/bridge
diff options
context:
space:
mode:
authorWim <wim@42.be>2017-09-21 22:35:21 +0200
committerWim <wim@42.be>2017-09-21 22:35:21 +0200
commitc4b75e5754c58758c920c79b0458171e98269961 (patch)
treea1070f27993de91489d26cea03f7e47ebccf9738 /bridge
parent6a7adb20a8f9f54d408f573763bc86d2670a0cf7 (diff)
downloadmatterbridge-msglm-c4b75e5754c58758c920c79b0458171e98269961.tar.gz
matterbridge-msglm-c4b75e5754c58758c920c79b0458171e98269961.tar.bz2
matterbridge-msglm-c4b75e5754c58758c920c79b0458171e98269961.zip
Download files from slack and reupload to mattermost (slack/mattermost). Closes #255
Refactor message.Extra to a map[string][]interface{} to have a bit more flexibility for stuffing extra stuff. For attached files from slack, files < 1MB size get downloaded (in memory), and get put into Extra["file"][]config.FileInfo (containing a pointer to the buffer and the filename). This is not async so slack channels with lots of attached files may suffer a slowdown. (the download timeout is set at 5 seconds).
Diffstat (limited to 'bridge')
-rw-r--r--bridge/config/config.go7
-rw-r--r--bridge/mattermost/mattermost.go21
-rw-r--r--bridge/slack/slack.go43
3 files changed, 64 insertions, 7 deletions
diff --git a/bridge/config/config.go b/bridge/config/config.go
index 2b678d2f..c6686a42 100644
--- a/bridge/config/config.go
+++ b/bridge/config/config.go
@@ -29,7 +29,12 @@ type Message struct {
Gateway string `json:"gateway"`
Timestamp time.Time `json:"timestamp"`
ID string `json:"id"`
- Extra []interface{}
+ Extra map[string][]interface{}
+}
+
+type FileInfo struct {
+ Name string
+ Data *[]byte
}
type ChannelInfo struct {
diff --git a/bridge/mattermost/mattermost.go b/bridge/mattermost/mattermost.go
index bedd07a8..985d0d76 100644
--- a/bridge/mattermost/mattermost.go
+++ b/bridge/mattermost/mattermost.go
@@ -26,7 +26,7 @@ type MMMessage struct {
UserID string
ID string
Event string
- Extra []interface{}
+ Extra map[string][]interface{}
}
type Bmattermost struct {
@@ -179,6 +179,21 @@ func (b *Bmattermost) Send(msg config.Message) (string, error) {
}
return msg.ID, b.mc.DeleteMessage(msg.ID)
}
+ if msg.Extra != nil {
+ for _, f := range msg.Extra["file"] {
+ fi := f.(config.FileInfo)
+ id, err := b.mc.UploadFile(*fi.Data, b.mc.GetChannelId(channel, ""), fi.Name)
+ if err != nil {
+ flog.Debugf("ERROR %#v", err)
+ return "", err
+ }
+ message = "uploaded a file: " + fi.Name
+ if b.Config.PrefixMessagesWithNick {
+ message = nick + "uploaded a file: " + fi.Name
+ }
+ return b.mc.PostMessageWithFiles(b.mc.GetChannelId(channel, ""), message, []string{id})
+ }
+ }
if msg.ID != "" {
return b.mc.EditMessage(msg.ID, message)
}
@@ -225,7 +240,7 @@ func (b *Bmattermost) handleMatterClient(mchan chan *MMMessage) {
continue
}
- m := &MMMessage{}
+ m := &MMMessage{Extra: make(map[string][]interface{})}
props := message.Post.Props
if props != nil {
@@ -237,7 +252,7 @@ func (b *Bmattermost) handleMatterClient(mchan chan *MMMessage) {
message.Username = props["override_username"].(string)
}
if _, ok := props["attachments"].([]interface{}); ok {
- m.Extra = props["attachments"].([]interface{})
+ m.Extra["attachments"] = props["attachments"].([]interface{})
}
}
// do not post our own messages back to irc
diff --git a/bridge/slack/slack.go b/bridge/slack/slack.go
index 0469d7ad..d72a2223 100644
--- a/bridge/slack/slack.go
+++ b/bridge/slack/slack.go
@@ -1,6 +1,7 @@
package bslack
import (
+ "bytes"
"errors"
"fmt"
"github.com/42wim/matterbridge/bridge/config"
@@ -8,6 +9,8 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/nlopes/slack"
"html"
+ "io"
+ "net/http"
"regexp"
"strings"
"time"
@@ -250,7 +253,7 @@ func (b *Bslack) handleSlack() {
text = b.replaceURL(text)
text = html.UnescapeString(text)
flog.Debugf("Sending message from %s on %s to gateway", message.Username, b.Account)
- msg := config.Message{Text: text, Username: message.Username, Channel: message.Channel, Account: b.Account, Avatar: b.getAvatar(message.Username), UserID: message.UserID, ID: "slack " + message.Raw.Timestamp}
+ msg := config.Message{Text: text, Username: message.Username, Channel: message.Channel, Account: b.Account, Avatar: b.getAvatar(message.Username), UserID: message.UserID, ID: "slack " + message.Raw.Timestamp, Extra: make(map[string][]interface{})}
if message.Raw.SubType == "me_message" {
msg.Event = config.EVENT_USER_ACTION
}
@@ -267,6 +270,19 @@ func (b *Bslack) handleSlack() {
msg.Event = config.EVENT_MSG_DELETE
msg.ID = "slack " + message.Raw.DeletedTimestamp
}
+
+ // if we have a file attached, download it (in memory) and put a pointer to it in msg.Extra
+ if message.Raw.File != nil {
+ // limit to 1MB for now
+ if message.Raw.File.Size <= 1000000 {
+ data, err := b.downloadFile(message.Raw.File.URLPrivateDownload)
+ if err != nil {
+ flog.Errorf("download %s failed %#v", message.Raw.File.URLPrivateDownload, err)
+ } else {
+ msg.Extra["file"] = append(msg.Extra["file"], config.FileInfo{Name: message.Raw.File.Name, Data: data})
+ }
+ }
+ }
flog.Debugf("Message is %#v", msg)
b.Remote <- msg
}
@@ -398,9 +414,9 @@ func (b *Bslack) replaceURL(text string) string {
return text
}
-func (b *Bslack) createAttach(extra []interface{}) []slack.Attachment {
+func (b *Bslack) createAttach(extra map[string][]interface{}) []slack.Attachment {
var attachs []slack.Attachment
- for _, v := range extra {
+ for _, v := range extra["attachments"] {
entry := v.(map[string]interface{})
s := slack.Attachment{}
s.Fallback = entry["fallback"].(string)
@@ -420,3 +436,24 @@ func (b *Bslack) createAttach(extra []interface{}) []slack.Attachment {
}
return attachs
}
+
+func (b *Bslack) downloadFile(url string) (*[]byte, error) {
+ var buf bytes.Buffer
+ client := &http.Client{
+ Timeout: time.Second * 5,
+ }
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Add("Authorization", "Bearer "+b.Config.Token)
+ resp, err := client.Do(req)
+ if err != nil {
+ resp.Body.Close()
+ return nil, err
+ }
+ io.Copy(&buf, resp.Body)
+ data := buf.Bytes()
+ resp.Body.Close()
+ return &data, nil
+}