diff --git a/go.mod b/go.mod index b6cbceb..7a3ee86 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.11 require ( github.com/Rhymen/go-whatsapp v0.0.2-0.20190524185555-8d76e32a6d8e + github.com/chai2010/webp v1.1.0 github.com/lib/pq v1.1.1 github.com/mattn/go-sqlite3 v1.10.0 github.com/pkg/errors v0.8.1 @@ -16,6 +17,6 @@ require ( ) replace ( - github.com/Rhymen/go-whatsapp => github.com/tulir/go-whatsapp v0.0.2-0.20190903182221-4e1a838ff3ba + github.com/Rhymen/go-whatsapp => github.com/tulir/go-whatsapp v0.0.2-0.20191004160943-faf0ee6fab98 gopkg.in/russross/blackfriday.v2 => github.com/russross/blackfriday/v2 v2.0.1 ) diff --git a/go.sum b/go.sum index 0e4e7db..8cdfe7b 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/go.mod h1:4a58ifQTEe2uwwsaqbh3i2un5/CBPg+At/qHpt18Tmk= github.com/Rhymen/go-whatsapp v0.0.0/go.mod h1:rdQr95g2C1xcOfM7QGOhza58HeI3I+tZ/bbluv7VazA= github.com/Rhymen/go-whatsapp v0.0.2-0.20190524185555-8d76e32a6d8e/go.mod h1:qf/2PQi82Okxw/igghu/oMGzTeUYuKBq1JNo3tdQyNg= +github.com/chai2010/webp v1.1.0 h1:4Ei0/BRroMF9FaXDG2e4OxwFcuW2vcXd+A6tyqTJUQQ= +github.com/chai2010/webp v1.1.0/go.mod h1:LP12PG5IFmLGHUU26tBiCBKnghxx3toZFwDjOYvd3Ow= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -43,6 +45,8 @@ github.com/tulir/go-whatsapp v0.0.2-0.20190830212741-33ca6ee47cf5 h1:0pUczFGOo4s github.com/tulir/go-whatsapp v0.0.2-0.20190830212741-33ca6ee47cf5/go.mod h1:u3Hdptbz3iB5y/NEoSKgsp9hBzUlm0A5OrLMVdENAX8= github.com/tulir/go-whatsapp v0.0.2-0.20190903182221-4e1a838ff3ba h1:exEcedSHn0qEZ1iwNwFF5brEuflhMScjFyyzmxUA+og= github.com/tulir/go-whatsapp v0.0.2-0.20190903182221-4e1a838ff3ba/go.mod h1:u3Hdptbz3iB5y/NEoSKgsp9hBzUlm0A5OrLMVdENAX8= +github.com/tulir/go-whatsapp v0.0.2-0.20191004160943-faf0ee6fab98 h1:TkKWIdhqxRBM8bZaJvp1q+awGJcY1f76zmlH7nHPDR8= +github.com/tulir/go-whatsapp v0.0.2-0.20191004160943-faf0ee6fab98/go.mod h1:u3Hdptbz3iB5y/NEoSKgsp9hBzUlm0A5OrLMVdENAX8= golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/portal.go b/portal.go index 6f2363a..15c4c17 100644 --- a/portal.go +++ b/portal.go @@ -33,6 +33,8 @@ import ( "sync" "time" + "github.com/chai2010/webp" + "github.com/Rhymen/go-whatsapp" waProto "github.com/Rhymen/go-whatsapp/binary/proto" "maunium.net/go/mautrix/format" @@ -189,13 +191,15 @@ func (portal *Portal) handleMessage(msg PortalMessage) { case whatsapp.TextMessage: portal.HandleTextMessage(msg.source, data) case whatsapp.ImageMessage: - portal.HandleMediaMessage(msg.source, data.Download, data.Thumbnail, data.Info, data.Type, data.Caption) + portal.HandleMediaMessage(msg.source, data.Download, data.Thumbnail, data.Info, data.Type, data.Caption, false) + case whatsapp.StickerMessage: + portal.HandleMediaMessage(msg.source, data.Download, data.Thumbnail, data.Info, data.Type, "", true) case whatsapp.VideoMessage: - portal.HandleMediaMessage(msg.source, data.Download, data.Thumbnail, data.Info, data.Type, data.Caption) + portal.HandleMediaMessage(msg.source, data.Download, data.Thumbnail, data.Info, data.Type, data.Caption, false) case whatsapp.AudioMessage: - portal.HandleMediaMessage(msg.source, data.Download, nil, data.Info, data.Type, "") + portal.HandleMediaMessage(msg.source, data.Download, nil, data.Info, data.Type, "", false) case whatsapp.DocumentMessage: - portal.HandleMediaMessage(msg.source, data.Download, data.Thumbnail, data.Info, data.Type, data.Title) + portal.HandleMediaMessage(msg.source, data.Download, data.Thumbnail, data.Info, data.Type, data.Title, false) case whatsappExt.MessageRevocation: portal.HandleMessageRevoke(msg.source, data) case FakeMessage: @@ -898,7 +902,7 @@ func (portal *Portal) HandleTextMessage(source *User, message whatsapp.TextMessa portal.finishHandling(source, message.Info.Source, resp.EventID) } -func (portal *Portal) HandleMediaMessage(source *User, download func() ([]byte, error), thumbnail []byte, info whatsapp.MessageInfo, mimeType, caption string) { +func (portal *Portal) HandleMediaMessage(source *User, download func() ([]byte, error), thumbnail []byte, info whatsapp.MessageInfo, mimeType, caption string, sendAsSticker bool) { if !portal.startHandling(info) { return } @@ -924,6 +928,25 @@ func (portal *Portal) HandleMediaMessage(source *User, download func() ([]byte, if detected := http.DetectContentType(data); detected != "application/octet-stream" { mimeType = detected } + + // 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" { + img, err := webp.Decode(bytes.NewReader(data)) + if err != nil { + portal.log.Errorfln("Failed to decode media for %s: %v", err) + return + } + + var buf bytes.Buffer + err = png.Encode(&buf, img) + if err != nil { + portal.log.Errorfln("Failed to convert media for %s: %v", err) + return + } + data = buf.Bytes() + mimeType = "image/png" + } + uploaded, err := intent.UploadBytes(data, mimeType) if err != nil { portal.log.Errorfln("Failed to upload media for %s: %v", err) @@ -963,7 +986,9 @@ func (portal *Portal) HandleMediaMessage(source *User, download func() ([]byte, switch strings.ToLower(strings.Split(mimeType, "/")[0]) { case "image": - content.MsgType = mautrix.MsgImage + if (!sendAsSticker) { + content.MsgType = mautrix.MsgImage + } cfg, _, _ := image.DecodeConfig(bytes.NewReader(data)) content.Info.Width = cfg.Width content.Info.Height = cfg.Height @@ -977,7 +1002,11 @@ func (portal *Portal) HandleMediaMessage(source *User, download func() ([]byte, _, _ = intent.UserTyping(portal.MXID, false, 0) ts := int64(info.Timestamp * 1000) - resp, err := intent.SendMassagedMessageEvent(portal.MXID, mautrix.EventMessage, &MessageContent{content, intent.IsCustomPuppet}, ts) + eventType := mautrix.EventMessage + if sendAsSticker { + eventType = mautrix.EventSticker + } + resp, err := intent.SendMassagedMessageEvent(portal.MXID, eventType, &MessageContent{content, intent.IsCustomPuppet}, ts) if err != nil { portal.log.Errorfln("Failed to handle message %s: %v", info.Id, err) return