From d5387bba41d064b1dd95da3b7517359d4337dd1a Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Tue, 16 Nov 2021 13:07:29 -0700 Subject: [PATCH 1/4] config: add message_send_checkpoint_endpoint --- config/config.go | 9 +++++---- config/upgrade.go | 1 + example-config.yaml | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/config/config.go b/config/config.go index c43f191..78ad457 100644 --- a/config/config.go +++ b/config/config.go @@ -29,10 +29,11 @@ var ExampleConfig string type Config struct { Homeserver struct { - Address string `yaml:"address"` - Domain string `yaml:"domain"` - Asmux bool `yaml:"asmux"` - StatusEndpoint string `yaml:"status_endpoint"` + Address string `yaml:"address"` + Domain string `yaml:"domain"` + Asmux bool `yaml:"asmux"` + StatusEndpoint string `yaml:"status_endpoint"` + MessageSendCheckpointEndpoint string `yaml:"message_send_checkpoint_endpoint"` } `yaml:"homeserver"` AppService struct { diff --git a/config/upgrade.go b/config/upgrade.go index 6ecb423..62c2585 100644 --- a/config/upgrade.go +++ b/config/upgrade.go @@ -31,6 +31,7 @@ func (helper *UpgradeHelper) doUpgrade() { helper.Copy(Str, "homeserver", "domain") helper.Copy(Bool, "homeserver", "asmux") helper.Copy(Str|Null, "homeserver", "status_endpoint") + helper.Copy(Str|Null, "homeserver", "message_send_checkpoint_endpoint") helper.Copy(Str, "appservice", "address") helper.Copy(Str, "appservice", "hostname") diff --git a/example-config.yaml b/example-config.yaml index 9f31ddf..83dbd07 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -11,6 +11,8 @@ homeserver: # If set, the bridge will make POST requests to this URL whenever a user's whatsapp connection state changes. # The bridge will use the appservice as_token to authorize requests. status_endpoint: null + # Endpoint for reporting per-message status. + message_send_checkpoint_endpoint: null # Application service host/registration related details. # Changing these values requires regeneration of the registration. From 712dc5a7b60c0679cf4b958a52639b2180470094 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Tue, 16 Nov 2021 13:07:52 -0700 Subject: [PATCH 2/4] deps/mautrix-go: upgrade to latest master --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5be040e..7844bba 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b maunium.net/go/mauflag v1.0.0 maunium.net/go/maulogger/v2 v2.3.1 - maunium.net/go/mautrix v0.10.2 + maunium.net/go/mautrix v0.10.3-0.20211118154012-0649e096bb01 ) require ( diff --git a/go.sum b/go.sum index b56eff0..be95f49 100644 --- a/go.sum +++ b/go.sum @@ -221,5 +221,5 @@ maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= maunium.net/go/maulogger/v2 v2.3.1 h1:fwBYJne0pHvJrrIPHK+TAPfyxxbBEz46oVGez2x0ODE= maunium.net/go/maulogger/v2 v2.3.1/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A= -maunium.net/go/mautrix v0.10.2 h1:JslJrE+6VBP/5h/Zq7Q6SsnLUqrNlg7oI/MMcgJNYIY= -maunium.net/go/mautrix v0.10.2/go.mod h1:k4Ng5oci83MEbqPL6KOjPdbU7f8v01KlMjR/zTQ+7mA= +maunium.net/go/mautrix v0.10.3-0.20211118154012-0649e096bb01 h1:u2gQndikai5YcUVdqz01ToBJ+Ngu2DLRIlpvXQicjvc= +maunium.net/go/mautrix v0.10.3-0.20211118154012-0649e096bb01/go.mod h1:k4Ng5oci83MEbqPL6KOjPdbU7f8v01KlMjR/zTQ+7mA= From 52f09001a7e92582295442d93a721ccbd9baf2bf Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Tue, 16 Nov 2021 13:08:21 -0700 Subject: [PATCH 3/4] portal: send checkpoint for matrix messages --- config/config.go | 1 + portal.go | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/config/config.go b/config/config.go index 78ad457..9cd8cae 100644 --- a/config/config.go +++ b/config/config.go @@ -121,6 +121,7 @@ func (config *Config) MakeAppService() (*appservice.AppService, error) { as.HomeserverURL = config.Homeserver.Address as.Host.Hostname = config.AppService.Hostname as.Host.Port = config.AppService.Port + as.MessageSendCheckpointEndpoint = config.Homeserver.MessageSendCheckpointEndpoint as.DefaultHTTPRetries = 4 var err error as.Registration, err = config.GetRegistration() diff --git a/portal.go b/portal.go index 9cc6e6c..988dbda 100644 --- a/portal.go +++ b/portal.go @@ -43,6 +43,7 @@ import ( "golang.org/x/image/webp" "google.golang.org/protobuf/proto" + "maunium.net/go/mautrix/bridge" "maunium.net/go/mautrix/format" "go.mau.fi/whatsmeow" @@ -2144,8 +2145,14 @@ func (portal *Portal) HandleMatrixMessage(sender *User, evt *event.Event) { if err != nil { portal.log.Errorln("Error sending message: %v", err) portal.sendErrorMessage(err.Error(), true) + checkpoint := bridge.NewErrorMessageSendCheckpoint(evt.ID, evt.RoomID, bridge.StepRemote, evt.Type, err) + checkpoint.MessageType = evt.Content.AsMessage().MsgType + go checkpoint.Send(portal.bridge.Config.Homeserver.MessageSendCheckpointEndpoint, portal.bridge.AS.Registration.AppToken) } else { portal.log.Debugfln("Handled Matrix event %s", evt.ID) + checkpoint := bridge.NewMessageSendCheckpoint(evt.ID, evt.RoomID, bridge.StepRemote, bridge.StatusSuccesss, evt.Type) + checkpoint.MessageType = evt.Content.AsMessage().MsgType + go checkpoint.Send(portal.bridge.Config.Homeserver.MessageSendCheckpointEndpoint, portal.bridge.AS.Registration.AppToken) portal.sendDeliveryReceipt(evt.ID) dbMsg.MarkSent(ts) } @@ -2179,8 +2186,12 @@ func (portal *Portal) HandleMatrixRedaction(sender *User, evt *event.Event) { _, err := sender.Client.RevokeMessage(portal.Key.JID, msg.JID) if err != nil { portal.log.Errorfln("Error handling Matrix redaction %s: %v", evt.ID, err) + checkpoint := bridge.NewErrorMessageSendCheckpoint(evt.ID, evt.RoomID, bridge.StepRemote, evt.Type, err) + go checkpoint.Send(portal.bridge.Config.Homeserver.MessageSendCheckpointEndpoint, portal.bridge.AS.Registration.AppToken) } else { portal.log.Debugfln("Handled Matrix redaction %s of %s", evt.ID, evt.Redacts) + checkpoint := bridge.NewMessageSendCheckpoint(evt.ID, evt.RoomID, bridge.StepRemote, bridge.StatusSuccesss, evt.Type) + go checkpoint.Send(portal.bridge.Config.Homeserver.MessageSendCheckpointEndpoint, portal.bridge.AS.Registration.AppToken) portal.sendDeliveryReceipt(evt.ID) } } From 139a0bd679428f366194418c8290258634e34c95 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Wed, 17 Nov 2021 14:52:16 -0700 Subject: [PATCH 4/4] Send checkpoints using new API and send DECRYPTED step checkpoints --- matrix.go | 17 ++++++++++++++--- portal.go | 15 ++++----------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/matrix.go b/matrix.go index 981fa30..6829bfd 100644 --- a/matrix.go +++ b/matrix.go @@ -342,16 +342,20 @@ func (mx *MatrixHandler) HandleEncrypted(evt *event.Event) { mx.log.Debugfln("Got session %s after waiting, trying to decrypt %s again", content.SessionID, evt.ID) decrypted, err = mx.bridge.Crypto.Decrypt(evt) } else { + mx.as.SendErrorMessageSendCheckpoint(evt, appservice.StepDecrypted, err, false) go mx.waitLongerForSession(evt) return } } if err != nil { + mx.as.SendErrorMessageSendCheckpoint(evt, appservice.StepDecrypted, err, true) + mx.log.Warnfln("Failed to decrypt %s: %v", evt.ID, err) _, _ = mx.bridge.Bot.SendNotice(evt.RoomID, fmt.Sprintf( "\u26a0 Your message was not bridged: %v", err)) return } + mx.as.SendMessageSendCheckpoint(decrypted, appservice.StepDecrypted) mx.bridge.EventProcessor.Dispatch(decrypted) } @@ -375,14 +379,18 @@ func (mx *MatrixHandler) waitLongerForSession(evt *event.Event) { mx.log.Debugfln("Got session %s after waiting more, trying to decrypt %s again", content.SessionID, evt.ID) decrypted, err := mx.bridge.Crypto.Decrypt(evt) if err == nil { + mx.as.SendMessageSendCheckpoint(decrypted, appservice.StepDecrypted) mx.bridge.EventProcessor.Dispatch(decrypted) _, _ = mx.bridge.Bot.RedactEvent(evt.RoomID, resp.EventID) return } - mx.log.Warnfln("Failed to decrypt %s: %v", err) + mx.log.Warnfln("Failed to decrypt %s: %v", evt.ID, err) + mx.as.SendErrorMessageSendCheckpoint(evt, appservice.StepDecrypted, err, true) update.Body = fmt.Sprintf("\u26a0 Your message was not bridged: %v", err) } else { - mx.log.Debugfln("Didn't get %s, giving up on %s", content.SessionID, evt.ID) + errMsg := fmt.Sprintf("Didn't get %s, giving up on %s", content.SessionID, evt.ID) + mx.log.Debugfln(errMsg) + mx.as.SendErrorMessageSendCheckpoint(evt, appservice.StepDecrypted, fmt.Errorf(errMsg), true) update.Body = "\u26a0 Your message was not bridged: the bridge hasn't received the decryption keys. " + "If this keeps happening, try restarting your client." } @@ -395,7 +403,10 @@ func (mx *MatrixHandler) waitLongerForSession(evt *event.Event) { EventID: resp.EventID, } } - _, _ = mx.bridge.Bot.SendMessageEvent(evt.RoomID, event.EventMessage, &update) + _, err = mx.bridge.Bot.SendMessageEvent(evt.RoomID, event.EventMessage, &update) + if err != nil { + mx.log.Debugfln("Failed to update decryption error notice %s: %v", resp.EventID, err) + } } func (mx *MatrixHandler) HandleMessage(evt *event.Event) { diff --git a/portal.go b/portal.go index 988dbda..16dd13e 100644 --- a/portal.go +++ b/portal.go @@ -43,7 +43,6 @@ import ( "golang.org/x/image/webp" "google.golang.org/protobuf/proto" - "maunium.net/go/mautrix/bridge" "maunium.net/go/mautrix/format" "go.mau.fi/whatsmeow" @@ -2145,14 +2144,10 @@ func (portal *Portal) HandleMatrixMessage(sender *User, evt *event.Event) { if err != nil { portal.log.Errorln("Error sending message: %v", err) portal.sendErrorMessage(err.Error(), true) - checkpoint := bridge.NewErrorMessageSendCheckpoint(evt.ID, evt.RoomID, bridge.StepRemote, evt.Type, err) - checkpoint.MessageType = evt.Content.AsMessage().MsgType - go checkpoint.Send(portal.bridge.Config.Homeserver.MessageSendCheckpointEndpoint, portal.bridge.AS.Registration.AppToken) + portal.bridge.AS.SendErrorMessageSendCheckpoint(evt, appservice.StepRemote, err, true) } else { portal.log.Debugfln("Handled Matrix event %s", evt.ID) - checkpoint := bridge.NewMessageSendCheckpoint(evt.ID, evt.RoomID, bridge.StepRemote, bridge.StatusSuccesss, evt.Type) - checkpoint.MessageType = evt.Content.AsMessage().MsgType - go checkpoint.Send(portal.bridge.Config.Homeserver.MessageSendCheckpointEndpoint, portal.bridge.AS.Registration.AppToken) + portal.bridge.AS.SendMessageSendCheckpoint(evt, appservice.StepRemote) portal.sendDeliveryReceipt(evt.ID) dbMsg.MarkSent(ts) } @@ -2186,12 +2181,10 @@ func (portal *Portal) HandleMatrixRedaction(sender *User, evt *event.Event) { _, err := sender.Client.RevokeMessage(portal.Key.JID, msg.JID) if err != nil { portal.log.Errorfln("Error handling Matrix redaction %s: %v", evt.ID, err) - checkpoint := bridge.NewErrorMessageSendCheckpoint(evt.ID, evt.RoomID, bridge.StepRemote, evt.Type, err) - go checkpoint.Send(portal.bridge.Config.Homeserver.MessageSendCheckpointEndpoint, portal.bridge.AS.Registration.AppToken) + portal.bridge.AS.SendErrorMessageSendCheckpoint(evt, appservice.StepRemote, err, true) } else { portal.log.Debugfln("Handled Matrix redaction %s of %s", evt.ID, evt.Redacts) - checkpoint := bridge.NewMessageSendCheckpoint(evt.ID, evt.RoomID, bridge.StepRemote, bridge.StatusSuccesss, evt.Type) - go checkpoint.Send(portal.bridge.Config.Homeserver.MessageSendCheckpointEndpoint, portal.bridge.AS.Registration.AppToken) + portal.bridge.AS.SendMessageSendCheckpoint(evt, appservice.StepRemote) portal.sendDeliveryReceipt(evt.ID) } }