summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bridge/config/config.go16
-rw-r--r--bridge/discord/discord.go41
-rw-r--r--bridge/helper/helper.go16
-rw-r--r--bridge/slack/handlers.go34
-rw-r--r--bridge/slack/slack.go37
-rw-r--r--gateway/gateway.go5
6 files changed, 112 insertions, 37 deletions
diff --git a/bridge/config/config.go b/bridge/config/config.go
index 7b7c2f2e..16b397f3 100644
--- a/bridge/config/config.go
+++ b/bridge/config/config.go
@@ -23,6 +23,7 @@ const (
EventRejoinChannels = "rejoin_channels"
EventUserAction = "user_action"
EventMsgDelete = "msg_delete"
+ EventFileDelete = "file_delete"
EventAPIConnected = "api_connected"
EventUserTyping = "user_typing"
EventGetChannelMembers = "get_channel_members"
@@ -56,13 +57,14 @@ func (m Message) ParentValid() bool {
}
type FileInfo struct {
- Name string
- Data *[]byte
- Comment string
- URL string
- Size int64
- Avatar bool
- SHA string
+ Name string
+ Data *[]byte
+ Comment string
+ URL string
+ Size int64
+ Avatar bool
+ SHA string
+ NativeID string
}
type ChannelInfo struct {
diff --git a/bridge/discord/discord.go b/bridge/discord/discord.go
index 0ac2b50c..9b9065f8 100644
--- a/bridge/discord/discord.go
+++ b/bridge/discord/discord.go
@@ -10,10 +10,14 @@ import (
"github.com/42wim/matterbridge/bridge/config"
"github.com/42wim/matterbridge/bridge/discord/transmitter"
"github.com/42wim/matterbridge/bridge/helper"
+ lru "github.com/hashicorp/golang-lru"
"github.com/matterbridge/discordgo"
)
-const MessageLength = 1950
+const (
+ MessageLength = 1950
+ cFileUpload = "file_upload"
+)
type Bdiscord struct {
*bridge.Config
@@ -35,10 +39,20 @@ type Bdiscord struct {
// Webhook specific logic
useAutoWebhooks bool
transmitter *transmitter.Transmitter
+ cache *lru.Cache
}
func New(cfg *bridge.Config) bridge.Bridger {
- b := &Bdiscord{Config: cfg}
+ newCache, err := lru.New(5000)
+ if err != nil {
+ cfg.Log.Fatalf("Could not create LRU cache: %v", err)
+ }
+
+ b := &Bdiscord{
+ Config: cfg,
+ cache: newCache,
+ }
+
b.userMemberMap = make(map[string]*discordgo.Member)
b.nickMemberMap = make(map[string]*discordgo.Member)
b.channelInfoMap = make(map[string]*config.ChannelInfo)
@@ -280,6 +294,21 @@ func (b *Bdiscord) handleEventBotUser(msg *config.Message, channelID string) (st
return "", err
}
+ // Delete a file
+ if msg.Event == config.EventFileDelete {
+ if msg.ID == "" {
+ return "", nil
+ }
+
+ if fi, ok := b.cache.Get(cFileUpload + msg.ID); ok {
+ err := b.c.ChannelMessageDelete(channelID, fi.(string)) // nolint:forcetypeassert
+ b.cache.Remove(cFileUpload + msg.ID)
+ return "", err
+ }
+
+ return "", fmt.Errorf("file %s not found", msg.ID)
+ }
+
// Upload a file if it exists
if msg.Extra != nil {
for _, rmsg := range helper.HandleExtra(msg, b.General) {
@@ -327,7 +356,6 @@ func (b *Bdiscord) handleEventBotUser(msg *config.Message, channelID string) (st
// handleUploadFile handles native upload of files
func (b *Bdiscord) handleUploadFile(msg *config.Message, channelID string) (string, error) {
- var err error
for _, f := range msg.Extra["file"] {
fi := f.(config.FileInfo)
file := discordgo.File{
@@ -340,10 +368,15 @@ func (b *Bdiscord) handleUploadFile(msg *config.Message, channelID string) (stri
Files: []*discordgo.File{&file},
AllowedMentions: b.getAllowedMentions(),
}
- _, err = b.c.ChannelMessageSendComplex(channelID, &m)
+ res, err := b.c.ChannelMessageSendComplex(channelID, &m)
if err != nil {
return "", fmt.Errorf("file upload failed: %s", err)
}
+
+ // link file_upload_nativeID (file ID from the original bridge) to our upload id
+ // so that we can remove this later when it eg needs to be deleted
+ b.cache.Add(cFileUpload+fi.NativeID, res.ID)
}
+
return "", nil
}
diff --git a/bridge/helper/helper.go b/bridge/helper/helper.go
index 581a2c43..fb65d8d9 100644
--- a/bridge/helper/helper.go
+++ b/bridge/helper/helper.go
@@ -168,17 +168,23 @@ func HandleDownloadSize(logger *logrus.Entry, msg *config.Message, name string,
// HandleDownloadData adds the data for a remote file into a Matterbridge gateway message.
func HandleDownloadData(logger *logrus.Entry, msg *config.Message, name, comment, url string, data *[]byte, general *config.Protocol) {
+ HandleDownloadData2(logger, msg, name, "", comment, url, data, general)
+}
+
+// HandleDownloadData adds the data for a remote file into a Matterbridge gateway message.
+func HandleDownloadData2(logger *logrus.Entry, msg *config.Message, name, id, comment, url string, data *[]byte, general *config.Protocol) {
var avatar bool
logger.Debugf("Download OK %#v %#v", name, len(*data))
if msg.Event == config.EventAvatarDownload {
avatar = true
}
msg.Extra["file"] = append(msg.Extra["file"], config.FileInfo{
- Name: name,
- Data: data,
- URL: url,
- Comment: comment,
- Avatar: avatar,
+ Name: name,
+ Data: data,
+ URL: url,
+ Comment: comment,
+ Avatar: avatar,
+ NativeID: id,
})
}
diff --git a/bridge/slack/handlers.go b/bridge/slack/handlers.go
index 4dc57d0d..c469b9a5 100644
--- a/bridge/slack/handlers.go
+++ b/bridge/slack/handlers.go
@@ -27,7 +27,8 @@ func (b *Bslack) handleSlack() {
b.Log.Debug("Start listening for Slack messages")
for message := range messages {
// don't do any action on deleted/typing messages
- if message.Event != config.EventUserTyping && message.Event != config.EventMsgDelete {
+ if message.Event != config.EventUserTyping && message.Event != config.EventMsgDelete &&
+ message.Event != config.EventFileDelete {
b.Log.Debugf("<= Sending message from %s on %s to gateway", message.Username, b.Account)
// cleanup the message
message.Text = b.replaceMention(message.Text)
@@ -76,6 +77,13 @@ func (b *Bslack) handleSlackClient(messages chan *config.Message) {
continue
}
messages <- rmsg
+ case *slack.FileDeletedEvent:
+ rmsg, err := b.handleFileDeletedEvent(ev)
+ if err != nil {
+ b.Log.Errorf("%#v", err)
+ continue
+ }
+ messages <- rmsg
case *slack.OutgoingErrorEvent:
b.Log.Debugf("%#v", ev.Error())
case *slack.ChannelJoinedEvent:
@@ -222,6 +230,26 @@ func (b *Bslack) handleMessageEvent(ev *slack.MessageEvent) (*config.Message, er
return rmsg, nil
}
+func (b *Bslack) handleFileDeletedEvent(ev *slack.FileDeletedEvent) (*config.Message, error) {
+ if rawChannel, ok := b.cache.Get(cfileDownloadChannel + ev.FileID); ok {
+ channel, err := b.channels.getChannelByID(rawChannel.(string))
+ if err != nil {
+ return nil, err
+ }
+
+ return &config.Message{
+ Event: config.EventFileDelete,
+ Text: config.EventFileDelete,
+ Channel: channel.Name,
+ Account: b.Account,
+ ID: ev.FileID,
+ Protocol: b.Protocol,
+ }, nil
+ }
+
+ return nil, fmt.Errorf("channel ID for file ID %s not found", ev.FileID)
+}
+
func (b *Bslack) handleStatusEvent(ev *slack.MessageEvent, rmsg *config.Message) bool {
switch ev.SubType {
case sChannelJoined, sMemberJoined:
@@ -281,6 +309,8 @@ func (b *Bslack) handleAttachments(ev *slack.MessageEvent, rmsg *config.Message)
// If we have files attached, download them (in memory) and put a pointer to it in msg.Extra.
for i := range ev.Files {
+ // keep reference in cache on which channel we added this file
+ b.cache.Add(cfileDownloadChannel+ev.Files[i].ID, ev.Channel)
if err := b.handleDownloadFile(rmsg, &ev.Files[i], false); err != nil {
b.Log.Errorf("Could not download incoming file: %#v", err)
}
@@ -330,7 +360,7 @@ func (b *Bslack) handleDownloadFile(rmsg *config.Message, file *slack.File, retr
// that the comment is not duplicated.
comment := rmsg.Text
rmsg.Text = ""
- helper.HandleDownloadData(b.Log, rmsg, file.Name, comment, file.URLPrivateDownload, data, b.General)
+ helper.HandleDownloadData2(b.Log, rmsg, file.Name, file.ID, comment, file.URLPrivateDownload, data, b.General)
return nil
}
diff --git a/bridge/slack/slack.go b/bridge/slack/slack.go
index 5db0c33e..55231c38 100644
--- a/bridge/slack/slack.go
+++ b/bridge/slack/slack.go
@@ -36,24 +36,25 @@ type Bslack struct {
}
const (
- sHello = "hello"
- sChannelJoin = "channel_join"
- sChannelLeave = "channel_leave"
- sChannelJoined = "channel_joined"
- sMemberJoined = "member_joined_channel"
- sMessageChanged = "message_changed"
- sMessageDeleted = "message_deleted"
- sSlackAttachment = "slack_attachment"
- sPinnedItem = "pinned_item"
- sUnpinnedItem = "unpinned_item"
- sChannelTopic = "channel_topic"
- sChannelPurpose = "channel_purpose"
- sFileComment = "file_comment"
- sMeMessage = "me_message"
- sUserTyping = "user_typing"
- sLatencyReport = "latency_report"
- sSystemUser = "system"
- sSlackBotUser = "slackbot"
+ sHello = "hello"
+ sChannelJoin = "channel_join"
+ sChannelLeave = "channel_leave"
+ sChannelJoined = "channel_joined"
+ sMemberJoined = "member_joined_channel"
+ sMessageChanged = "message_changed"
+ sMessageDeleted = "message_deleted"
+ sSlackAttachment = "slack_attachment"
+ sPinnedItem = "pinned_item"
+ sUnpinnedItem = "unpinned_item"
+ sChannelTopic = "channel_topic"
+ sChannelPurpose = "channel_purpose"
+ sFileComment = "file_comment"
+ sMeMessage = "me_message"
+ sUserTyping = "user_typing"
+ sLatencyReport = "latency_report"
+ sSystemUser = "system"
+ sSlackBotUser = "slackbot"
+ cfileDownloadChannel = "file_download_channel"
tokenConfig = "Token"
incomingWebhookConfig = "WebhookBindAddress"
diff --git a/gateway/gateway.go b/gateway/gateway.go
index 85f5a187..fc75916c 100644
--- a/gateway/gateway.go
+++ b/gateway/gateway.go
@@ -447,7 +447,10 @@ func (gw *Gateway) SendMessage(
msg.Avatar = gw.modifyAvatar(rmsg, dest)
msg.Username = gw.modifyUsername(rmsg, dest)
- msg.ID = gw.getDestMsgID(rmsg.Protocol+" "+rmsg.ID, dest, channel)
+ // exclude file delete event as the msg ID here is the native file ID that needs to be deleted
+ if msg.Event != config.EventFileDelete {
+ msg.ID = gw.getDestMsgID(rmsg.Protocol+" "+rmsg.ID, dest, channel)
+ }
// for api we need originchannel as channel
if dest.Protocol == apiProtocol {