mirror of
https://github.com/tulir/mautrix-whatsapp
synced 2024-12-13 09:03:10 +01:00
Implement matrix->whatsapp formatting and fix whatsapp->matrix files
This commit is contained in:
parent
d13bf4ae64
commit
b62a85a6df
2 changed files with 116 additions and 16 deletions
112
portal.go
112
portal.go
|
@ -28,6 +28,10 @@ import (
|
|||
"sync"
|
||||
"net/http"
|
||||
"maunium.net/go/mautrix-whatsapp/whatsapp-ext"
|
||||
"mime"
|
||||
"image"
|
||||
"bytes"
|
||||
"maunium.net/go/gomatrix/format"
|
||||
)
|
||||
|
||||
func (user *User) GetPortalByMXID(mxid types.MatrixRoomID) *Portal {
|
||||
|
@ -130,8 +134,8 @@ func (portal *Portal) UpdateAvatar() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
mime := http.DetectContentType(data)
|
||||
resp, err := portal.MainIntent().UploadBytes(data, mime)
|
||||
mimeType := http.DetectContentType(data)
|
||||
resp, err := portal.MainIntent().UploadBytes(data, mimeType)
|
||||
if err != nil {
|
||||
portal.log.Errorln("Failed to upload avatar:", err)
|
||||
return false
|
||||
|
@ -278,6 +282,18 @@ func (portal *Portal) GetMessageIntent(info whatsapp.MessageInfo) *appservice.In
|
|||
return puppet.Intent()
|
||||
}
|
||||
|
||||
func (portal *Portal) GetRelations(info whatsapp.MessageInfo) (reply gomatrix.RelatesTo) {
|
||||
if len(info.QuotedMessageID) == 0 {
|
||||
return
|
||||
}
|
||||
message := portal.bridge.DB.Message.GetByJID(portal.Owner, info.QuotedMessageID)
|
||||
if message != nil {
|
||||
reply.InReplyTo.EventID = message.MXID
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func (portal *Portal) HandleTextMessage(message whatsapp.TextMessage) {
|
||||
if portal.IsDuplicate(message.Info.Id) {
|
||||
return
|
||||
|
@ -290,7 +306,11 @@ func (portal *Portal) HandleTextMessage(message whatsapp.TextMessage) {
|
|||
return
|
||||
}
|
||||
|
||||
resp, err := intent.SendText(portal.MXID, message.Text)
|
||||
resp, err := intent.SendMassagedMessageEvent(portal.MXID, gomatrix.EventMessage, gomatrix.Content{
|
||||
Body: message.Text,
|
||||
MsgType: gomatrix.MsgText,
|
||||
RelatesTo: portal.GetRelations(message.Info),
|
||||
}, int64(message.Info.Timestamp*1000))
|
||||
if err != nil {
|
||||
portal.log.Errorfln("Failed to handle message %s: %v", message.Info.Id, err)
|
||||
return
|
||||
|
@ -299,7 +319,7 @@ func (portal *Portal) HandleTextMessage(message whatsapp.TextMessage) {
|
|||
portal.log.Debugln("Handled message", message.Info.Id, "->", resp.EventID)
|
||||
}
|
||||
|
||||
func (portal *Portal) HandleMediaMessage(download func() ([]byte, error), info whatsapp.MessageInfo, mime, caption string) {
|
||||
func (portal *Portal) HandleMediaMessage(download func() ([]byte, error), thumbnail []byte, info whatsapp.MessageInfo, mimeType, caption string) {
|
||||
if portal.IsDuplicate(info.Id) {
|
||||
return
|
||||
}
|
||||
|
@ -311,17 +331,65 @@ func (portal *Portal) HandleMediaMessage(download func() ([]byte, error), info w
|
|||
return
|
||||
}
|
||||
|
||||
img, err := download()
|
||||
data, err := download()
|
||||
if err != nil {
|
||||
portal.log.Errorln("Failed to download media:", err)
|
||||
return
|
||||
}
|
||||
uploaded, err := intent.UploadBytes(img, mime)
|
||||
|
||||
uploaded, err := intent.UploadBytes(data, mimeType)
|
||||
if err != nil {
|
||||
portal.log.Errorln("Failed to upload media:", err)
|
||||
return
|
||||
}
|
||||
resp, err := intent.SendImage(portal.MXID, caption, uploaded.ContentURI)
|
||||
if len(caption) == 0 {
|
||||
caption = info.Id
|
||||
exts, _ := mime.ExtensionsByType(mimeType)
|
||||
if exts != nil && len(exts) > 0 {
|
||||
caption += exts[0]
|
||||
}
|
||||
}
|
||||
|
||||
content := gomatrix.Content{
|
||||
Body: caption,
|
||||
URL: uploaded.ContentURI,
|
||||
Info: gomatrix.FileInfo{
|
||||
Size: len(data),
|
||||
MimeType: mimeType,
|
||||
},
|
||||
RelatesTo: portal.GetRelations(info),
|
||||
}
|
||||
|
||||
if thumbnail != nil {
|
||||
thumbnailMime := http.DetectContentType(thumbnail)
|
||||
uploadedThumbnail, _ := intent.UploadBytes(thumbnail, thumbnailMime)
|
||||
if uploadedThumbnail != nil {
|
||||
content.Info.ThumbnailURL = uploadedThumbnail.ContentURI
|
||||
cfg, _, _ := image.DecodeConfig(bytes.NewReader(data))
|
||||
content.Info.ThumbnailInfo = &gomatrix.FileInfo{
|
||||
Size: len(thumbnail),
|
||||
Width: cfg.Width,
|
||||
Height: cfg.Height,
|
||||
MimeType: thumbnailMime,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch strings.ToLower(strings.Split(mimeType, "/")[0]) {
|
||||
case "image":
|
||||
content.MsgType = gomatrix.MsgImage
|
||||
cfg, _, _ := image.DecodeConfig(bytes.NewReader(data))
|
||||
content.Info.Width = cfg.Width
|
||||
content.Info.Height = cfg.Height
|
||||
case "video":
|
||||
content.MsgType = gomatrix.MsgVideo
|
||||
case "audio":
|
||||
content.MsgType = gomatrix.MsgAudio
|
||||
default:
|
||||
content.MsgType = gomatrix.MsgFile
|
||||
}
|
||||
|
||||
resp, err := intent.SendMassagedMessageEvent(portal.MXID, gomatrix.EventMessage, content, int64(info.Timestamp*1000))
|
||||
if err != nil {
|
||||
portal.log.Errorfln("Failed to handle message %s: %v", info.Id, err)
|
||||
return
|
||||
|
@ -330,12 +398,40 @@ func (portal *Portal) HandleMediaMessage(download func() ([]byte, error), info w
|
|||
portal.log.Debugln("Handled message", info.Id, "->", resp.EventID)
|
||||
}
|
||||
|
||||
var htmlParser = format.HTMLParser{
|
||||
TabsToSpaces: 4,
|
||||
Newline: "\n",
|
||||
|
||||
PillConverter: func(mxid, eventID string) string {
|
||||
return mxid
|
||||
},
|
||||
BoldConverter: func(text string) string {
|
||||
return fmt.Sprintf("*%s*", text)
|
||||
},
|
||||
ItalicConverter: func(text string) string {
|
||||
return fmt.Sprintf("_%s_", text)
|
||||
},
|
||||
StrikethroughConverter: func(text string) string {
|
||||
return fmt.Sprintf("~%s~", text)
|
||||
},
|
||||
MonospaceConverter: func(text string) string {
|
||||
return fmt.Sprintf("```%s```", text)
|
||||
},
|
||||
MonospaceBlockConverter: func(text string) string {
|
||||
return fmt.Sprintf("```%s```", text)
|
||||
},
|
||||
}
|
||||
|
||||
func (portal *Portal) HandleMatrixMessage(evt *gomatrix.Event) {
|
||||
var err error
|
||||
switch evt.Content.MsgType {
|
||||
case gomatrix.MsgText:
|
||||
text := evt.Content.Body
|
||||
if evt.Content.Format == gomatrix.FormatHTML {
|
||||
text = htmlParser.Parse(evt.Content.FormattedBody)
|
||||
}
|
||||
err = portal.user.Conn.Send(whatsapp.TextMessage{
|
||||
Text: evt.Content.Body,
|
||||
Text: text,
|
||||
Info: whatsapp.MessageInfo{
|
||||
RemoteJid: portal.JID,
|
||||
},
|
||||
|
|
20
user.go
20
user.go
|
@ -24,7 +24,6 @@ import (
|
|||
log "maunium.net/go/maulogger"
|
||||
"maunium.net/go/mautrix-whatsapp/types"
|
||||
"strings"
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"maunium.net/go/mautrix-whatsapp/whatsapp-ext"
|
||||
)
|
||||
|
@ -186,10 +185,7 @@ func (user *User) Login(roomID types.MatrixRoomID) {
|
|||
func (user *User) Sync() {
|
||||
user.log.Debugln("Syncing...")
|
||||
user.Conn.Contacts()
|
||||
user.log.Debugln(user.Conn.Store.Contacts)
|
||||
for jid, contact := range user.Conn.Store.Contacts {
|
||||
dat, _ := json.Marshal(&contact)
|
||||
user.log.Debugln(string(dat))
|
||||
if strings.HasSuffix(jid, puppetJIDStrippedSuffix) {
|
||||
puppet := user.GetPuppetByJID(contact.Jid)
|
||||
puppet.Sync(contact)
|
||||
|
@ -216,15 +212,23 @@ func (user *User) HandleTextMessage(message whatsapp.TextMessage) {
|
|||
}
|
||||
|
||||
func (user *User) HandleImageMessage(message whatsapp.ImageMessage) {
|
||||
// user.log.Debugln("Received image message:", message)
|
||||
portal := user.GetPortalByJID(message.Info.RemoteJid)
|
||||
portal.HandleMediaMessage(message.Download, message.Info, message.Type, message.Caption)
|
||||
portal.HandleMediaMessage(message.Download, message.Thumbnail, message.Info, message.Type, message.Caption)
|
||||
}
|
||||
|
||||
func (user *User) HandleVideoMessage(message whatsapp.VideoMessage) {
|
||||
// user.log.Debugln("Received video message:", message)
|
||||
portal := user.GetPortalByJID(message.Info.RemoteJid)
|
||||
portal.HandleMediaMessage(message.Download, message.Info, message.Type, message.Caption)
|
||||
portal.HandleMediaMessage(message.Download, message.Thumbnail, message.Info, message.Type, message.Caption)
|
||||
}
|
||||
|
||||
func (user *User) HandleAudioMessage(message whatsapp.AudioMessage) {
|
||||
portal := user.GetPortalByJID(message.Info.RemoteJid)
|
||||
portal.HandleMediaMessage(message.Download, nil, message.Info, message.Type, "")
|
||||
}
|
||||
|
||||
func (user *User) HandleDocumentMessage(message whatsapp.DocumentMessage) {
|
||||
portal := user.GetPortalByJID(message.Info.RemoteJid)
|
||||
portal.HandleMediaMessage(message.Download, message.Thumbnail, message.Info, message.Type, message.Title)
|
||||
}
|
||||
|
||||
func (user *User) HandleJsonMessage(message string) {
|
||||
|
|
Loading…
Reference in a new issue