From f1dd496a2db3aedc0c20d3b5ef9f7cbb2520b482 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 2 Aug 2021 12:53:38 +0300 Subject: [PATCH] Add support for Matrix->WhatsApp location messages --- ROADMAP.md | 1 + portal.go | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 8ffd831..3d9f8ac 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -3,6 +3,7 @@ * [x] Message content * [x] Plain text * [x] Formatted messages + * [x] Location messages * [x] Media/files * [x] Replies * [x] Message redactions diff --git a/portal.go b/portal.go index 3183121..80b6489 100644 --- a/portal.go +++ b/portal.go @@ -36,6 +36,7 @@ import ( "os/exec" "path/filepath" "reflect" + "strconv" "strings" "sync" "sync/atomic" @@ -2039,6 +2040,24 @@ func addCodecToMime(mimeType, codec string) string { return mime.FormatMediaType(mediaType, params) } +func parseGeoURI(uri string) (lat, long float64, err error) { + if !strings.HasPrefix(uri, "geo:") { + err = fmt.Errorf("uri doesn't have geo: prefix") + return + } + // Remove geo: prefix and anything after ; + coordinates := strings.Split(strings.TrimPrefix(uri, "geo:"), ";")[0] + + if splitCoordinates := strings.Split(coordinates, ","); len(splitCoordinates) != 2 { + err = fmt.Errorf("didn't find exactly two numbers separated by a comma") + } else if lat, err = strconv.ParseFloat(splitCoordinates[0], 64); err != nil { + err = fmt.Errorf("latitude is not a number: %w", err) + } else if long, err = strconv.ParseFloat(splitCoordinates[1], 64); err != nil { + err = fmt.Errorf("longitude is not a number: %w", err) + } + return +} + func (portal *Portal) convertMatrixMessage(sender *User, evt *event.Event) (*waProto.WebMessageInfo, *User) { content, ok := evt.Content.Parsed.(*event.MessageEventContent) if !ok { @@ -2190,6 +2209,18 @@ func (portal *Portal) convertMatrixMessage(sender *User, evt *event.Event) (*waP FileSha256: media.FileSHA256, FileLength: &media.FileLength, } + case event.MsgLocation: + lat, long, err := parseGeoURI(content.GeoURI) + if err != nil { + portal.log.Debugfln("Invalid geo URI on Matrix event %s: %v", evt.ID, err) + return nil, sender + } + info.Message.LocationMessage = &waProto.LocationMessage{ + DegreesLatitude: &lat, + DegreesLongitude: &long, + Comment: &content.Body, + ContextInfo: ctxInfo, + } default: portal.log.Debugfln("Unhandled Matrix event %s: unknown msgtype %s", evt.ID, content.MsgType) return nil, sender @@ -2234,8 +2265,8 @@ func (portal *Portal) sendDeliveryReceipt(eventID id.EventID) { } func (portal *Portal) HandleMatrixMessage(sender *User, evt *event.Event) { - if !portal.HasRelaybot() && ( - (portal.IsPrivateChat() && sender.JID != portal.Key.Receiver) || + if !portal.HasRelaybot() && + ((portal.IsPrivateChat() && sender.JID != portal.Key.Receiver) || portal.sendMatrixConnectionError(sender, evt.ID)) { return }