mirror of
https://github.com/mautrix/whatsapp.git
synced 2025-03-14 14:15:38 +00:00
client: add support for connect-once background resync interface
This commit is contained in:
parent
989f9036e4
commit
c3a263a537
4 changed files with 43 additions and 5 deletions
2
go.mod
2
go.mod
|
@ -17,7 +17,7 @@ require (
|
|||
golang.org/x/sync v0.10.0
|
||||
google.golang.org/protobuf v1.36.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
maunium.net/go/mautrix v0.22.2-0.20250113200949-53a56684d3d3
|
||||
maunium.net/go/mautrix v0.22.2-0.20250115130529-b17a8cd74cf6
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
4
go.sum
4
go.sum
|
@ -101,5 +101,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
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/mautrix v0.22.2-0.20250113200949-53a56684d3d3 h1:ouuSo9unoAHaEze2hOo7z7lQG+rTjxhvXlXngExQwqg=
|
||||
maunium.net/go/mautrix v0.22.2-0.20250113200949-53a56684d3d3/go.mod h1:07i96D7BALyuAqxFhRzvaId8FC9NABgRQBPY5HWndf4=
|
||||
maunium.net/go/mautrix v0.22.2-0.20250115130529-b17a8cd74cf6 h1:NwaMR4yLqkkTkQMP4Vv8wbo1PY/8qgVQ1CrexUSd/Wc=
|
||||
maunium.net/go/mautrix v0.22.2-0.20250115130529-b17a8cd74cf6/go.mod h1:07i96D7BALyuAqxFhRzvaId8FC9NABgRQBPY5HWndf4=
|
||||
|
|
|
@ -96,14 +96,16 @@ type WhatsAppClient struct {
|
|||
directMediaRetries map[networkid.MessageID]*directMediaRetry
|
||||
directMediaLock sync.Mutex
|
||||
mediaRetryLock *semaphore.Weighted
|
||||
offlineSyncWaiter chan error
|
||||
|
||||
lastPhoneOfflineWarning time.Time
|
||||
isNewLogin bool
|
||||
}
|
||||
|
||||
var (
|
||||
_ bridgev2.NetworkAPI = (*WhatsAppClient)(nil)
|
||||
_ bridgev2.PushableNetworkAPI = (*WhatsAppClient)(nil)
|
||||
_ bridgev2.NetworkAPI = (*WhatsAppClient)(nil)
|
||||
_ bridgev2.PushableNetworkAPI = (*WhatsAppClient)(nil)
|
||||
_ bridgev2.BackgroundSyncingNetworkAPI = (*WhatsAppClient)(nil)
|
||||
)
|
||||
|
||||
var pushCfg = &bridgev2.PushConfig{
|
||||
|
@ -171,6 +173,34 @@ func (wa *WhatsAppClient) Connect(ctx context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func (wa *WhatsAppClient) notifyOfflineSyncWaiter(err error) {
|
||||
if wa.offlineSyncWaiter != nil {
|
||||
wa.offlineSyncWaiter <- err
|
||||
}
|
||||
}
|
||||
|
||||
func (wa *WhatsAppClient) ConnectBackground(ctx context.Context) error {
|
||||
if wa.Client == nil {
|
||||
return bridgev2.ErrNotLoggedIn
|
||||
}
|
||||
wa.offlineSyncWaiter = make(chan error)
|
||||
wa.Main.firstClientConnectOnce.Do(wa.Main.onFirstClientConnect)
|
||||
if err := wa.Main.updateProxy(ctx, wa.Client, false); err != nil {
|
||||
zerolog.Ctx(ctx).Err(err).Msg("Failed to update proxy")
|
||||
}
|
||||
err := wa.Client.Connect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer wa.Disconnect()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case err = <-wa.offlineSyncWaiter:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func (wa *WhatsAppClient) startLoops() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
oldStop := wa.stopLoops.Swap(&cancel)
|
||||
|
|
|
@ -181,14 +181,17 @@ func (wa *WhatsAppClient) handleWAEvent(rawEvt any) {
|
|||
} else {
|
||||
log.Info().Msg("Offline sync completed")
|
||||
}
|
||||
wa.notifyOfflineSyncWaiter(nil)
|
||||
case *events.LoggedOut:
|
||||
wa.handleWALogout(evt.Reason, evt.OnConnect)
|
||||
wa.notifyOfflineSyncWaiter(fmt.Errorf("logged out: %s", evt.Reason))
|
||||
case *events.Disconnected:
|
||||
// Don't send the normal transient disconnect state if we're already in a different transient disconnect state.
|
||||
// TODO remove this if/when the phone offline state is moved to a sub-state of CONNECTED
|
||||
if wa.UserLogin.BridgeState.GetPrev().Error != WAPhoneOffline && wa.PhoneRecentlySeen(false) {
|
||||
wa.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: WADisconnected})
|
||||
}
|
||||
wa.notifyOfflineSyncWaiter(fmt.Errorf("disconnected"))
|
||||
case *events.StreamError:
|
||||
var message string
|
||||
if evt.Code != "" {
|
||||
|
@ -203,8 +206,10 @@ func (wa *WhatsAppClient) handleWAEvent(rawEvt any) {
|
|||
Error: WAStreamError,
|
||||
Message: message,
|
||||
})
|
||||
wa.notifyOfflineSyncWaiter(fmt.Errorf("stream error: %s", message))
|
||||
case *events.StreamReplaced:
|
||||
wa.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: WAStreamReplaced})
|
||||
wa.notifyOfflineSyncWaiter(fmt.Errorf("stream replaced"))
|
||||
case *events.KeepAliveTimeout:
|
||||
wa.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: WAKeepaliveTimeout})
|
||||
case *events.KeepAliveRestored:
|
||||
|
@ -216,15 +221,18 @@ func (wa *WhatsAppClient) handleWAEvent(rawEvt any) {
|
|||
Error: status.BridgeStateErrorCode(fmt.Sprintf("wa-connect-failure-%d", evt.Reason)),
|
||||
Message: fmt.Sprintf("Unknown connection failure: %s (%s)", evt.Reason, evt.Message),
|
||||
})
|
||||
wa.notifyOfflineSyncWaiter(fmt.Errorf("connection failure: %s (%s)", evt.Reason, evt.Message))
|
||||
case *events.ClientOutdated:
|
||||
wa.UserLogin.Log.Error().Msg("Got a client outdated connect failure. The bridge is likely out of date, please update immediately.")
|
||||
wa.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: WAClientOutdated})
|
||||
wa.notifyOfflineSyncWaiter(fmt.Errorf("client outdated"))
|
||||
case *events.TemporaryBan:
|
||||
wa.UserLogin.BridgeState.Send(status.BridgeState{
|
||||
StateEvent: status.StateBadCredentials,
|
||||
Error: WATemporaryBan,
|
||||
Message: evt.String(),
|
||||
})
|
||||
wa.notifyOfflineSyncWaiter(fmt.Errorf("temporary ban: %s", evt.String()))
|
||||
default:
|
||||
log.Debug().Type("event_type", rawEvt).Msg("Unhandled WhatsApp event")
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue