forked from MirrorHub/mautrix-whatsapp
Use MentionedJIDs metadata instead of assuming everything is a mention
This commit is contained in:
parent
6cb55f3969
commit
9671b6c39a
4 changed files with 45 additions and 28 deletions
|
@ -34,7 +34,8 @@ var italicRegex = regexp.MustCompile("([\\s>~*]|^)_(.+?)_([^a-zA-Z\\d]|$)")
|
|||
var boldRegex = regexp.MustCompile("([\\s>_~]|^)\\*(.+?)\\*([^a-zA-Z\\d]|$)")
|
||||
var strikethroughRegex = regexp.MustCompile("([\\s>_*]|^)~(.+?)~([^a-zA-Z\\d]|$)")
|
||||
var codeBlockRegex = regexp.MustCompile("```(?:.|\n)+?```")
|
||||
var mentionRegex = regexp.MustCompile("@[0-9]+")
|
||||
|
||||
const mentionedJIDsContextKey = "net.maunium.whatsapp.mentioned_jids"
|
||||
|
||||
type Formatter struct {
|
||||
bridge *Bridge
|
||||
|
@ -53,28 +54,34 @@ func NewFormatter(bridge *Bridge) *Formatter {
|
|||
TabsToSpaces: 4,
|
||||
Newline: "\n",
|
||||
|
||||
PillConverter: func(mxid, eventID string) string {
|
||||
PillConverter: func(mxid, eventID string, ctx format.Context) string {
|
||||
if mxid[0] == '@' {
|
||||
puppet := bridge.GetPuppetByMXID(id.UserID(mxid))
|
||||
if puppet != nil {
|
||||
jids, ok := ctx[mentionedJIDsContextKey].([]types.WhatsAppID)
|
||||
if !ok {
|
||||
ctx[mentionedJIDsContextKey] = []types.WhatsAppID{puppet.JID}
|
||||
} else {
|
||||
ctx[mentionedJIDsContextKey] = append(jids, puppet.JID)
|
||||
}
|
||||
return "@" + puppet.PhoneNumber()
|
||||
}
|
||||
}
|
||||
return mxid
|
||||
},
|
||||
BoldConverter: func(text string) string {
|
||||
BoldConverter: func(text string, _ format.Context) string {
|
||||
return fmt.Sprintf("*%s*", text)
|
||||
},
|
||||
ItalicConverter: func(text string) string {
|
||||
ItalicConverter: func(text string, _ format.Context) string {
|
||||
return fmt.Sprintf("_%s_", text)
|
||||
},
|
||||
StrikethroughConverter: func(text string) string {
|
||||
StrikethroughConverter: func(text string, _ format.Context) string {
|
||||
return fmt.Sprintf("~%s~", text)
|
||||
},
|
||||
MonospaceConverter: func(text string) string {
|
||||
MonospaceConverter: func(text string, _ format.Context) string {
|
||||
return fmt.Sprintf("```%s```", text)
|
||||
},
|
||||
MonospaceBlockConverter: func(text, language string) string {
|
||||
MonospaceBlockConverter: func(text, language string, _ format.Context) string {
|
||||
return fmt.Sprintf("```%s```", text)
|
||||
},
|
||||
},
|
||||
|
@ -92,16 +99,8 @@ func NewFormatter(bridge *Bridge) *Formatter {
|
|||
}
|
||||
return fmt.Sprintf("<code>%s</code>", str)
|
||||
},
|
||||
mentionRegex: func(str string) string {
|
||||
mxid, displayname := formatter.getMatrixInfoByJID(str[1:] + whatsappExt.NewUserSuffix)
|
||||
return fmt.Sprintf(`<a href="https://matrix.to/#/%s">%s</a>`, mxid, displayname)
|
||||
},
|
||||
}
|
||||
formatter.waReplFuncText = map[*regexp.Regexp]func(string) string{
|
||||
mentionRegex: func(str string) string {
|
||||
_, displayname := formatter.getMatrixInfoByJID(str[1:] + whatsappExt.NewUserSuffix)
|
||||
return displayname
|
||||
},
|
||||
}
|
||||
return formatter
|
||||
}
|
||||
|
@ -117,7 +116,7 @@ func (formatter *Formatter) getMatrixInfoByJID(jid types.WhatsAppID) (mxid id.Us
|
|||
return
|
||||
}
|
||||
|
||||
func (formatter *Formatter) ParseWhatsApp(content *event.MessageEventContent) {
|
||||
func (formatter *Formatter) ParseWhatsApp(content *event.MessageEventContent, mentionedJIDs []types.WhatsAppID) {
|
||||
output := html.EscapeString(content.Body)
|
||||
for regex, replacement := range formatter.waReplString {
|
||||
output = regex.ReplaceAllString(output, replacement)
|
||||
|
@ -125,6 +124,12 @@ func (formatter *Formatter) ParseWhatsApp(content *event.MessageEventContent) {
|
|||
for regex, replacer := range formatter.waReplFunc {
|
||||
output = regex.ReplaceAllStringFunc(output, replacer)
|
||||
}
|
||||
for _, jid := range mentionedJIDs {
|
||||
mxid, displayname := formatter.getMatrixInfoByJID(jid)
|
||||
number := "@" + strings.Replace(jid, whatsappExt.NewUserSuffix, "", 1)
|
||||
output = strings.Replace(output, number, fmt.Sprintf(`<a href="https://matrix.to/#/%s">%s</a>`, mxid, displayname), -1)
|
||||
content.Body = strings.Replace(content.Body, number, displayname, -1)
|
||||
}
|
||||
if output != content.Body {
|
||||
output = strings.Replace(output, "\n", "<br/>", -1)
|
||||
content.FormattedBody = output
|
||||
|
@ -135,6 +140,9 @@ func (formatter *Formatter) ParseWhatsApp(content *event.MessageEventContent) {
|
|||
}
|
||||
}
|
||||
|
||||
func (formatter *Formatter) ParseMatrix(html string) string {
|
||||
return formatter.matrixHTMLParser.Parse(html)
|
||||
func (formatter *Formatter) ParseMatrix(html string) (string, []types.WhatsAppID) {
|
||||
ctx := make(format.Context)
|
||||
result := formatter.matrixHTMLParser.Parse(html, ctx)
|
||||
mentionedJIDs := ctx[mentionedJIDsContextKey].([]types.WhatsAppID)
|
||||
return result, mentionedJIDs
|
||||
}
|
||||
|
|
4
go.mod
4
go.mod
|
@ -16,7 +16,7 @@ require (
|
|||
gopkg.in/yaml.v2 v2.3.0
|
||||
maunium.net/go/mauflag v1.0.0
|
||||
maunium.net/go/maulogger/v2 v2.1.1
|
||||
maunium.net/go/mautrix v0.6.1
|
||||
maunium.net/go/mautrix v0.7.0-rc.2
|
||||
)
|
||||
|
||||
replace github.com/Rhymen/go-whatsapp => github.com/tulir/go-whatsapp v0.3.6
|
||||
replace github.com/Rhymen/go-whatsapp => github.com/tulir/go-whatsapp v0.3.7
|
||||
|
|
4
go.sum
4
go.sum
|
@ -121,6 +121,8 @@ github.com/tulir/go-whatsapp v0.3.5 h1:cFw8MWhoLTqR0h2kSkSvz866rggRIAx4X2l8I65gA
|
|||
github.com/tulir/go-whatsapp v0.3.5/go.mod h1:7yGOBdWidM6gsmbAFwgkwHEIhzVrm01+6UbImpMWfTM=
|
||||
github.com/tulir/go-whatsapp v0.3.6 h1:RtyNh8TFX48ClMvi2J8oS3qmH7b1t9SIKA5jucG2lbk=
|
||||
github.com/tulir/go-whatsapp v0.3.6/go.mod h1:7yGOBdWidM6gsmbAFwgkwHEIhzVrm01+6UbImpMWfTM=
|
||||
github.com/tulir/go-whatsapp v0.3.7 h1:6YoHsAlO+Y1SnU0bOntDmuvJQziEnBjFKO+1fOH2VIw=
|
||||
github.com/tulir/go-whatsapp v0.3.7/go.mod h1:7yGOBdWidM6gsmbAFwgkwHEIhzVrm01+6UbImpMWfTM=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
|
||||
|
@ -212,3 +214,5 @@ maunium.net/go/mautrix v0.6.0 h1:V32l4aygKk2XcH3fi8Yd0pFeSyYZJNRIvr8vdA2GtC8=
|
|||
maunium.net/go/mautrix v0.6.0/go.mod h1:Va/74MijqaS0DQ3aUqxmFO54/PMfr1LVsCOcGRHbYmo=
|
||||
maunium.net/go/mautrix v0.6.1 h1:OFxAEnjEtkstE5J3RLv+vVrUORY6UTXV8pD/qWRBTPI=
|
||||
maunium.net/go/mautrix v0.6.1/go.mod h1:Va/74MijqaS0DQ3aUqxmFO54/PMfr1LVsCOcGRHbYmo=
|
||||
maunium.net/go/mautrix v0.7.0-rc.2 h1:139raRbbLft9i+g0zGVOT8rrHKRQmeo0SsZnFpZDEXE=
|
||||
maunium.net/go/mautrix v0.7.0-rc.2/go.mod h1:Va/74MijqaS0DQ3aUqxmFO54/PMfr1LVsCOcGRHbYmo=
|
||||
|
|
21
portal.go
21
portal.go
|
@ -1189,7 +1189,7 @@ func (portal *Portal) HandleTextMessage(source *User, message whatsapp.TextMessa
|
|||
MsgType: event.MsgText,
|
||||
}
|
||||
|
||||
portal.bridge.Formatter.ParseWhatsApp(content)
|
||||
portal.bridge.Formatter.ParseWhatsApp(content, message.ContextInfo.MentionedJID)
|
||||
portal.SetReply(content, message.ContextInfo)
|
||||
|
||||
_, _ = intent.UserTyping(portal.MXID, false, 0)
|
||||
|
@ -1554,7 +1554,7 @@ func (portal *Portal) HandleMediaMessage(source *User, msg mediaMessage) {
|
|||
MsgType: event.MsgNotice,
|
||||
}
|
||||
|
||||
portal.bridge.Formatter.ParseWhatsApp(captionContent)
|
||||
portal.bridge.Formatter.ParseWhatsApp(captionContent, msg.context.MentionedJID)
|
||||
|
||||
_, err := portal.sendMessage(intent, event.EventMessage, captionContent, ts)
|
||||
if err != nil {
|
||||
|
@ -1658,8 +1658,9 @@ func (portal *Portal) convertGifToVideo(gif []byte) ([]byte, error) {
|
|||
|
||||
func (portal *Portal) preprocessMatrixMedia(sender *User, relaybotFormatted bool, content *event.MessageEventContent, eventID id.EventID, mediaType whatsapp.MediaType) *MediaUpload {
|
||||
var caption string
|
||||
var mentionedJIDs []types.WhatsAppID
|
||||
if relaybotFormatted {
|
||||
caption = portal.bridge.Formatter.ParseMatrix(content.FormattedBody)
|
||||
caption, mentionedJIDs = portal.bridge.Formatter.ParseMatrix(content.FormattedBody)
|
||||
}
|
||||
|
||||
var file *event.EncryptedFileInfo
|
||||
|
@ -1702,6 +1703,7 @@ func (portal *Portal) preprocessMatrixMedia(sender *User, relaybotFormatted bool
|
|||
|
||||
return &MediaUpload{
|
||||
Caption: caption,
|
||||
MentionedJIDs: mentionedJIDs,
|
||||
URL: url,
|
||||
MediaKey: mediaKey,
|
||||
FileEncSHA256: fileEncSHA256,
|
||||
|
@ -1713,6 +1715,7 @@ func (portal *Portal) preprocessMatrixMedia(sender *User, relaybotFormatted bool
|
|||
|
||||
type MediaUpload struct {
|
||||
Caption string
|
||||
MentionedJIDs []types.WhatsAppID
|
||||
URL string
|
||||
MediaKey []byte
|
||||
FileEncSHA256 []byte
|
||||
|
@ -1819,15 +1822,11 @@ func (portal *Portal) convertMatrixMessage(sender *User, evt *event.Event) (*waP
|
|||
case event.MsgText, event.MsgEmote, event.MsgNotice:
|
||||
text := content.Body
|
||||
if content.Format == event.FormatHTML {
|
||||
text = portal.bridge.Formatter.ParseMatrix(content.FormattedBody)
|
||||
text, ctxInfo.MentionedJid = portal.bridge.Formatter.ParseMatrix(content.FormattedBody)
|
||||
}
|
||||
if content.MsgType == event.MsgEmote && !relaybotFormatted {
|
||||
text = "/me " + text
|
||||
}
|
||||
ctxInfo.MentionedJid = mentionRegex.FindAllString(text, -1)
|
||||
for index, mention := range ctxInfo.MentionedJid {
|
||||
ctxInfo.MentionedJid[index] = mention[1:] + whatsappExt.NewUserSuffix
|
||||
}
|
||||
if ctxInfo.StanzaId != nil || ctxInfo.MentionedJid != nil {
|
||||
info.Message.ExtendedTextMessage = &waProto.ExtendedTextMessage{
|
||||
Text: &text,
|
||||
|
@ -1841,7 +1840,9 @@ func (portal *Portal) convertMatrixMessage(sender *User, evt *event.Event) (*waP
|
|||
if media == nil {
|
||||
return nil, sender
|
||||
}
|
||||
ctxInfo.MentionedJid = media.MentionedJIDs
|
||||
info.Message.ImageMessage = &waProto.ImageMessage{
|
||||
ContextInfo: ctxInfo,
|
||||
Caption: &media.Caption,
|
||||
JpegThumbnail: media.Thumbnail,
|
||||
Url: &media.URL,
|
||||
|
@ -1858,7 +1859,9 @@ func (portal *Portal) convertMatrixMessage(sender *User, evt *event.Event) (*waP
|
|||
return nil, sender
|
||||
}
|
||||
duration := uint32(content.GetInfo().Duration)
|
||||
ctxInfo.MentionedJid = media.MentionedJIDs
|
||||
info.Message.VideoMessage = &waProto.VideoMessage{
|
||||
ContextInfo: ctxInfo,
|
||||
Caption: &media.Caption,
|
||||
JpegThumbnail: media.Thumbnail,
|
||||
Url: &media.URL,
|
||||
|
@ -1877,6 +1880,7 @@ func (portal *Portal) convertMatrixMessage(sender *User, evt *event.Event) (*waP
|
|||
}
|
||||
duration := uint32(content.GetInfo().Duration)
|
||||
info.Message.AudioMessage = &waProto.AudioMessage{
|
||||
ContextInfo: ctxInfo,
|
||||
Url: &media.URL,
|
||||
MediaKey: media.MediaKey,
|
||||
Mimetype: &content.GetInfo().MimeType,
|
||||
|
@ -1891,6 +1895,7 @@ func (portal *Portal) convertMatrixMessage(sender *User, evt *event.Event) (*waP
|
|||
return nil, sender
|
||||
}
|
||||
info.Message.DocumentMessage = &waProto.DocumentMessage{
|
||||
ContextInfo: ctxInfo,
|
||||
Url: &media.URL,
|
||||
FileName: &content.Body,
|
||||
MediaKey: media.MediaKey,
|
||||
|
|
Loading…
Reference in a new issue