Use MentionedJIDs metadata instead of assuming everything is a mention

This commit is contained in:
Tulir Asokan 2020-07-31 14:30:58 +03:00
parent 6cb55f3969
commit 9671b6c39a
4 changed files with 45 additions and 28 deletions

View file

@ -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
View file

@ -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
View file

@ -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=

View file

@ -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,