diff --git a/formatting.go b/formatting.go
index 7880790..478fd1a 100644
--- a/formatting.go
+++ b/formatting.go
@@ -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("%s
", str)
},
- mentionRegex: func(str string) string {
- mxid, displayname := formatter.getMatrixInfoByJID(str[1:] + whatsappExt.NewUserSuffix)
- return fmt.Sprintf(`%s`, 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(`%s`, mxid, displayname), -1)
+ content.Body = strings.Replace(content.Body, number, displayname, -1)
+ }
if output != content.Body {
output = strings.Replace(output, "\n", "
", -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
}
diff --git a/go.mod b/go.mod
index ce09146..0ffed15 100644
--- a/go.mod
+++ b/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
diff --git a/go.sum b/go.sum
index d41785f..c52ba65 100644
--- a/go.sum
+++ b/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=
diff --git a/portal.go b/portal.go
index 53a495c..89c2b58 100644
--- a/portal.go
+++ b/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,