Move HandleMediaMessage parameters to a struct

This commit is contained in:
Tulir Asokan 2020-06-20 22:24:27 +03:00
parent bd9464add3
commit 689202f43d

119
portal.go
View file

@ -199,15 +199,34 @@ func (portal *Portal) handleMessage(msg PortalMessage) {
case whatsapp.TextMessage: case whatsapp.TextMessage:
portal.HandleTextMessage(msg.source, data) portal.HandleTextMessage(msg.source, data)
case whatsapp.ImageMessage: case whatsapp.ImageMessage:
portal.HandleMediaMessage(msg.source, data.Download, data.Thumbnail, data.Info, data.ContextInfo, data.Type, data.Caption, "", 0, false) portal.HandleMediaMessage(msg.source, mediaMessage{
base: base{data.Download, data.Info, data.ContextInfo, data.Type},
thumbnail: data.Thumbnail,
caption: data.Caption,
})
case whatsapp.StickerMessage: case whatsapp.StickerMessage:
portal.HandleMediaMessage(msg.source, data.Download, nil, data.Info, data.ContextInfo, data.Type, "", "", 0, true) portal.HandleMediaMessage(msg.source, mediaMessage{
base: base{data.Download, data.Info, data.ContextInfo, data.Type},
sendAsSticker: true,
})
case whatsapp.VideoMessage: case whatsapp.VideoMessage:
portal.HandleMediaMessage(msg.source, data.Download, data.Thumbnail, data.Info, data.ContextInfo, data.Type, data.Caption, "", data.Length, false) portal.HandleMediaMessage(msg.source, mediaMessage{
base: base{data.Download, data.Info, data.ContextInfo, data.Type},
thumbnail: data.Thumbnail,
caption: data.Caption,
length: data.Length,
})
case whatsapp.AudioMessage: case whatsapp.AudioMessage:
portal.HandleMediaMessage(msg.source, data.Download, nil, data.Info, data.ContextInfo, data.Type, "", "", data.Length, false) portal.HandleMediaMessage(msg.source, mediaMessage{
base: base{data.Download, data.Info, data.ContextInfo, data.Type},
length: data.Length,
})
case whatsapp.DocumentMessage: case whatsapp.DocumentMessage:
portal.HandleMediaMessage(msg.source, data.Download, data.Thumbnail, data.Info, data.ContextInfo, data.Type, "", data.Title, 0, false) portal.HandleMediaMessage(msg.source, mediaMessage{
base: base{data.Download, data.Info, data.ContextInfo, data.Type},
thumbnail: data.Thumbnail,
fileName: data.Title,
})
case whatsapp.ContactMessage: case whatsapp.ContactMessage:
portal.HandleContactMessage(msg.source, data) portal.HandleContactMessage(msg.source, data)
case whatsapp.LocationMessage: case whatsapp.LocationMessage:
@ -1250,35 +1269,51 @@ func (portal *Portal) encryptFile(data []byte, mimeType string) ([]byte, string,
URL: "", URL: "",
} }
return file.Encrypt(data), "application/octet-stream", file return file.Encrypt(data), "application/octet-stream", file
} }
func (portal *Portal) HandleMediaMessage(source *User, download func() ([]byte, error), thumbnail []byte, info whatsapp.MessageInfo, context whatsapp.ContextInfo, mimeType, caption, fileName string, length uint32, sendAsSticker bool) { type base struct {
intent := portal.startHandling(source, info) download func() ([]byte, error)
info whatsapp.MessageInfo
context whatsapp.ContextInfo
mimeType string
}
type mediaMessage struct {
base
thumbnail []byte
caption string
fileName string
length uint32
sendAsSticker bool
}
func (portal *Portal) HandleMediaMessage(source *User, msg mediaMessage) {
intent := portal.startHandling(source, msg.info)
if intent == nil { if intent == nil {
return return
} }
data, err := download() data, err := msg.download()
if err == whatsapp.ErrMediaDownloadFailedWith404 || err == whatsapp.ErrMediaDownloadFailedWith410 { if err == whatsapp.ErrMediaDownloadFailedWith404 || err == whatsapp.ErrMediaDownloadFailedWith410 {
portal.log.Warnfln("Failed to download media for %s: %v. Calling LoadMediaInfo and retrying download...", info.Id, err) portal.log.Warnfln("Failed to download media for %s: %v. Calling LoadMediaInfo and retrying download...", msg.info.Id, err)
_, err = source.Conn.LoadMediaInfo(info.RemoteJid, info.Id, info.FromMe) _, err = source.Conn.LoadMediaInfo(msg.info.RemoteJid, msg.info.Id, msg.info.FromMe)
if err != nil { if err != nil {
portal.sendMediaBridgeFailure(source, intent, info, errors.Wrap(err, "failed to load media info")) portal.sendMediaBridgeFailure(source, intent, msg.info, errors.Wrap(err, "failed to load media info"))
return return
} }
data, err = download() data, err = msg.download()
} }
if err == whatsapp.ErrNoURLPresent { if err == whatsapp.ErrNoURLPresent {
portal.log.Debugfln("No URL present error for media message %s, ignoring...", info.Id) portal.log.Debugfln("No URL present error for media message %s, ignoring...", msg.info.Id)
return return
} else if err != nil { } else if err != nil {
portal.sendMediaBridgeFailure(source, intent, info, err) portal.sendMediaBridgeFailure(source, intent, msg.info, err)
return return
} }
// synapse doesn't handle webp well, so we convert it. This can be dropped once https://github.com/matrix-org/synapse/issues/4382 is fixed // synapse doesn't handle webp well, so we convert it. This can be dropped once https://github.com/matrix-org/synapse/issues/4382 is fixed
if mimeType == "image/webp" { if msg.mimeType == "image/webp" {
img, err := decodeWebp(bytes.NewReader(data)) img, err := decodeWebp(bytes.NewReader(data))
if err != nil { if err != nil {
portal.log.Errorfln("Failed to decode media for %s: %v", err) portal.log.Errorfln("Failed to decode media for %s: %v", err)
@ -1292,16 +1327,16 @@ func (portal *Portal) HandleMediaMessage(source *User, download func() ([]byte,
return return
} }
data = buf.Bytes() data = buf.Bytes()
mimeType = "image/png" msg.mimeType = "image/png"
} }
var width, height int var width, height int
if strings.HasPrefix(mimeType, "image/") { if strings.HasPrefix(msg.mimeType, "image/") {
cfg, _, _ := image.DecodeConfig(bytes.NewReader(data)) cfg, _, _ := image.DecodeConfig(bytes.NewReader(data))
width, height = cfg.Width, cfg.Height width, height = cfg.Width, cfg.Height
} }
data, uploadMimeType, file := portal.encryptFile(data, mimeType) data, uploadMimeType, file := portal.encryptFile(data, msg.mimeType)
uploaded, err := intent.UploadBytes(data, uploadMimeType) uploaded, err := intent.UploadBytes(data, uploadMimeType)
if err != nil { if err != nil {
@ -1309,24 +1344,24 @@ func (portal *Portal) HandleMediaMessage(source *User, download func() ([]byte,
return return
} }
if fileName == "" { if msg.fileName == "" {
fileName = info.Id msg.fileName = msg.info.Id
exts, _ := mime.ExtensionsByType(mimeType) exts, _ := mime.ExtensionsByType(msg.mimeType)
if exts != nil && len(exts) > 0 { if exts != nil && len(exts) > 0 {
fileName += exts[0] msg.fileName += exts[0]
} }
} }
content := &event.MessageEventContent{ content := &event.MessageEventContent{
Body: fileName, Body: msg.fileName,
File: file, File: file,
Info: &event.FileInfo{ Info: &event.FileInfo{
Size: len(data), Size: len(data),
MimeType: mimeType, MimeType: msg.mimeType,
Width: width, Width: width,
Height: height, Height: height,
Duration: int(length), Duration: int(msg.length),
}, },
} }
if content.File != nil { if content.File != nil {
@ -1334,16 +1369,16 @@ func (portal *Portal) HandleMediaMessage(source *User, download func() ([]byte,
} else { } else {
content.URL = uploaded.ContentURI.CUString() content.URL = uploaded.ContentURI.CUString()
} }
portal.SetReply(content, context) portal.SetReply(content, msg.context)
if thumbnail != nil && portal.bridge.Config.Bridge.WhatsappThumbnail { if msg.thumbnail != nil && portal.bridge.Config.Bridge.WhatsappThumbnail {
thumbnailMime := http.DetectContentType(thumbnail) thumbnailMime := http.DetectContentType(msg.thumbnail)
thumbnailCfg, _, _ := image.DecodeConfig(bytes.NewReader(thumbnail)) thumbnailCfg, _, _ := image.DecodeConfig(bytes.NewReader(msg.thumbnail))
thumbnailSize := len(thumbnail) thumbnailSize := len(msg.thumbnail)
thumbnail, thumbnailUploadMime, thumbnailFile := portal.encryptFile(thumbnail, thumbnailMime) thumbnail, thumbnailUploadMime, thumbnailFile := portal.encryptFile(msg.thumbnail, thumbnailMime)
uploadedThumbnail, err := intent.UploadBytes(thumbnail, thumbnailUploadMime) uploadedThumbnail, err := intent.UploadBytes(thumbnail, thumbnailUploadMime)
if err != nil { if err != nil {
portal.log.Warnfln("Failed to upload thumbnail for %s: %v", info.Id, err) portal.log.Warnfln("Failed to upload thumbnail for %s: %v", msg.info.Id, err)
} else if uploadedThumbnail != nil { } else if uploadedThumbnail != nil {
if thumbnailFile != nil { if thumbnailFile != nil {
thumbnailFile.URL = uploadedThumbnail.ContentURI.CUString() thumbnailFile.URL = uploadedThumbnail.ContentURI.CUString()
@ -1360,9 +1395,9 @@ func (portal *Portal) HandleMediaMessage(source *User, download func() ([]byte,
} }
} }
switch strings.ToLower(strings.Split(mimeType, "/")[0]) { switch strings.ToLower(strings.Split(msg.mimeType, "/")[0]) {
case "image": case "image":
if !sendAsSticker { if !msg.sendAsSticker {
content.MsgType = event.MsgImage content.MsgType = event.MsgImage
} }
case "video": case "video":
@ -1374,20 +1409,20 @@ func (portal *Portal) HandleMediaMessage(source *User, download func() ([]byte,
} }
_, _ = intent.UserTyping(portal.MXID, false, 0) _, _ = intent.UserTyping(portal.MXID, false, 0)
ts := int64(info.Timestamp * 1000) ts := int64(msg.info.Timestamp * 1000)
eventType := event.EventMessage eventType := event.EventMessage
if sendAsSticker { if msg.sendAsSticker {
eventType = event.EventSticker eventType = event.EventSticker
} }
resp, err := portal.sendMessage(intent, eventType, content, ts) resp, err := portal.sendMessage(intent, eventType, content, ts)
if err != nil { if err != nil {
portal.log.Errorfln("Failed to handle message %s: %v", info.Id, err) portal.log.Errorfln("Failed to handle message %s: %v", msg.info.Id, err)
return return
} }
if len(caption) > 0 { if len(msg.caption) > 0 {
captionContent := &event.MessageEventContent{ captionContent := &event.MessageEventContent{
Body: caption, Body: msg.caption,
MsgType: event.MsgNotice, MsgType: event.MsgNotice,
} }
@ -1395,12 +1430,12 @@ func (portal *Portal) HandleMediaMessage(source *User, download func() ([]byte,
_, err := portal.sendMessage(intent, event.EventMessage, captionContent, ts) _, err := portal.sendMessage(intent, event.EventMessage, captionContent, ts)
if err != nil { if err != nil {
portal.log.Warnfln("Failed to handle caption of message %s: %v", info.Id, err) portal.log.Warnfln("Failed to handle caption of message %s: %v", msg.info.Id, err)
} }
// TODO store caption mxid? // TODO store caption mxid?
} }
portal.finishHandling(source, info.Source, resp.EventID) portal.finishHandling(source, msg.info.Source, resp.EventID)
} }
func makeMessageID() *string { func makeMessageID() *string {