Эх сурвалжийг харах

Implement attachments for Matrix -> Discord

Gary Kramlich 3 жил өмнө
parent
commit
1c2dc8e9da
2 өөрчлөгдсөн 72 нэмэгдсэн , 3 устгасан
  1. 35 0
      bridge/attachments.go
  2. 37 3
      bridge/portal.go

+ 35 - 0
bridge/attachments.go

@@ -11,6 +11,7 @@ import (
 
 	"maunium.net/go/mautrix/appservice"
 	"maunium.net/go/mautrix/event"
+	"maunium.net/go/mautrix/id"
 )
 
 func (p *Portal) downloadDiscordAttachment(url string) ([]byte, error) {
@@ -40,6 +41,40 @@ func (p *Portal) downloadDiscordAttachment(url string) ([]byte, error) {
 	return ioutil.ReadAll(resp.Body)
 }
 
+func (p *Portal) downloadMatrixAttachment(eventID id.EventID, content *event.MessageEventContent) ([]byte, error) {
+	var file *event.EncryptedFileInfo
+	rawMXC := content.URL
+
+	if content.File != nil {
+		file = content.File
+		rawMXC = file.URL
+	}
+
+	mxc, err := rawMXC.Parse()
+	if err != nil {
+		p.log.Errorln("Malformed content URL in %s: %v", eventID, err)
+
+		return nil, err
+	}
+
+	data, err := p.MainIntent().DownloadBytes(mxc)
+	if err != nil {
+		p.log.Errorfln("Failed to download media in %s: %v", eventID, err)
+
+		return nil, err
+	}
+
+	if file != nil {
+		data, err = file.Decrypt(data)
+		if err != nil {
+			p.log.Errorfln("Failed to decrypt media in %s: %v", eventID, err)
+			return nil, err
+		}
+	}
+
+	return data, nil
+}
+
 func (p *Portal) uploadMatrixAttachment(intent *appservice.IntentAPI, data []byte, content *event.MessageEventContent) error {
 	uploaded, err := intent.UploadBytes(data, content.Info.MimeType)
 	if err != nil {

+ 37 - 3
bridge/portal.go

@@ -1,6 +1,7 @@
 package bridge
 
 import (
+	"bytes"
 	"fmt"
 	"strings"
 	"sync"
@@ -592,14 +593,47 @@ func (p *Portal) handleMatrixMessage(sender *User, evt *event.Event) {
 				return
 			}
 		}
-	} else {
-		msg, err := sender.Session.ChannelMessageSend(p.Key.ChannelID, content.Body)
+
+		return
+	}
+
+	var msg *discordgo.Message
+	var err error
+
+	switch content.MsgType {
+	case event.MsgText, event.MsgEmote, event.MsgNotice:
+		msg, err = sender.Session.ChannelMessageSend(p.Key.ChannelID, content.Body)
+	case event.MsgAudio, event.MsgFile, event.MsgImage, event.MsgVideo:
+		data, err := p.downloadMatrixAttachment(evt.ID, content)
 		if err != nil {
-			p.log.Errorfln("Failed to send message: %v", err)
+			p.log.Errorfln("Failed to download matrix attachment: %v", err)
 
 			return
 		}
 
+		msgSend := &discordgo.MessageSend{
+			Files: []*discordgo.File{
+				&discordgo.File{
+					Name:        content.Body,
+					ContentType: content.Info.MimeType,
+					Reader:      bytes.NewReader(data),
+				},
+			},
+		}
+
+		msg, err = sender.Session.ChannelMessageSendComplex(p.Key.ChannelID, msgSend)
+	default:
+		p.log.Warnln("unknown message type:", content.MsgType)
+		return
+	}
+
+	if err != nil {
+		p.log.Errorfln("Failed to send message: %v", err)
+
+		return
+	}
+
+	if msg != nil {
 		dbMsg := p.bridge.db.Message.New()
 		dbMsg.Channel = p.Key
 		dbMsg.DiscordID = msg.ID