Kaynağa Gözat

Update mautrix-go for new bridge status package

Tulir Asokan 2 yıl önce
ebeveyn
işleme
52072d9650
8 değiştirilmiş dosya ile 57 ekleme ve 54 silme
  1. 18 18
      bridgestate.go
  2. 5 4
      commands.go
  3. 1 1
      go.mod
  4. 2 2
      go.sum
  5. 2 1
      main.go
  6. 5 5
      messagetracking.go
  7. 5 5
      provisioning.go
  8. 19 18
      user.go

+ 18 - 18
bridgestate.go

@@ -20,23 +20,23 @@ import (
 	"fmt"
 	"fmt"
 	"net/http"
 	"net/http"
 
 
-	"maunium.net/go/mautrix/bridge"
+	"maunium.net/go/mautrix/bridge/status"
 	"maunium.net/go/mautrix/id"
 	"maunium.net/go/mautrix/id"
 )
 )
 
 
 const (
 const (
-	WALoggedOut        bridge.StateErrorCode = "wa-logged-out"
-	WAMainDeviceGone   bridge.StateErrorCode = "wa-main-device-gone"
-	WAUnknownLogout    bridge.StateErrorCode = "wa-unknown-logout"
-	WANotConnected     bridge.StateErrorCode = "wa-not-connected"
-	WAConnecting       bridge.StateErrorCode = "wa-connecting"
-	WAKeepaliveTimeout bridge.StateErrorCode = "wa-keepalive-timeout"
-	WAPhoneOffline     bridge.StateErrorCode = "wa-phone-offline"
-	WAConnectionFailed bridge.StateErrorCode = "wa-connection-failed"
+	WALoggedOut        status.BridgeStateErrorCode = "wa-logged-out"
+	WAMainDeviceGone   status.BridgeStateErrorCode = "wa-main-device-gone"
+	WAUnknownLogout    status.BridgeStateErrorCode = "wa-unknown-logout"
+	WANotConnected     status.BridgeStateErrorCode = "wa-not-connected"
+	WAConnecting       status.BridgeStateErrorCode = "wa-connecting"
+	WAKeepaliveTimeout status.BridgeStateErrorCode = "wa-keepalive-timeout"
+	WAPhoneOffline     status.BridgeStateErrorCode = "wa-phone-offline"
+	WAConnectionFailed status.BridgeStateErrorCode = "wa-connection-failed"
 )
 )
 
 
 func init() {
 func init() {
-	bridge.StateHumanErrors.Update(bridge.StateErrorMap{
+	status.BridgeStateHumanErrors.Update(status.BridgeStateErrorMap{
 		WALoggedOut:        "You were logged out from another device. Relogin to continue using the bridge.",
 		WALoggedOut:        "You were logged out from another device. Relogin to continue using the bridge.",
 		WAMainDeviceGone:   "Your phone was logged out from WhatsApp. Relogin to continue using the bridge.",
 		WAMainDeviceGone:   "Your phone was logged out from WhatsApp. Relogin to continue using the bridge.",
 		WAUnknownLogout:    "You were logged out for an unknown reason. Relogin to continue using the bridge.",
 		WAUnknownLogout:    "You were logged out for an unknown reason. Relogin to continue using the bridge.",
@@ -68,24 +68,24 @@ func (prov *ProvisioningAPI) BridgeStatePing(w http.ResponseWriter, r *http.Requ
 	}
 	}
 	userID := r.URL.Query().Get("user_id")
 	userID := r.URL.Query().Get("user_id")
 	user := prov.bridge.GetUserByMXID(id.UserID(userID))
 	user := prov.bridge.GetUserByMXID(id.UserID(userID))
-	var global bridge.State
-	global.StateEvent = bridge.StateRunning
-	var remote bridge.State
+	var global status.BridgeState
+	global.StateEvent = status.StateRunning
+	var remote status.BridgeState
 	if user.IsConnected() {
 	if user.IsConnected() {
 		if user.Client.IsLoggedIn() {
 		if user.Client.IsLoggedIn() {
-			remote.StateEvent = bridge.StateConnected
+			remote.StateEvent = status.StateConnected
 		} else if user.Session != nil {
 		} else if user.Session != nil {
-			remote.StateEvent = bridge.StateConnecting
+			remote.StateEvent = status.StateConnecting
 			remote.Error = WAConnecting
 			remote.Error = WAConnecting
 		} // else: unconfigured
 		} // else: unconfigured
 	} else if user.Session != nil {
 	} else if user.Session != nil {
-		remote.StateEvent = bridge.StateBadCredentials
+		remote.StateEvent = status.StateBadCredentials
 		remote.Error = WANotConnected
 		remote.Error = WANotConnected
 	} // else: unconfigured
 	} // else: unconfigured
 	global = global.Fill(nil)
 	global = global.Fill(nil)
-	resp := bridge.GlobalState{
+	resp := status.GlobalBridgeState{
 		BridgeState:  global,
 		BridgeState:  global,
-		RemoteStates: map[string]bridge.State{},
+		RemoteStates: map[string]status.BridgeState{},
 	}
 	}
 	if len(remote.StateEvent) > 0 {
 	if len(remote.StateEvent) > 0 {
 		remote = remote.Fill(user)
 		remote = remote.Fill(user)

+ 5 - 4
commands.go

@@ -38,6 +38,7 @@ import (
 	"maunium.net/go/mautrix"
 	"maunium.net/go/mautrix"
 	"maunium.net/go/mautrix/bridge"
 	"maunium.net/go/mautrix/bridge"
 	"maunium.net/go/mautrix/bridge/commands"
 	"maunium.net/go/mautrix/bridge/commands"
+	"maunium.net/go/mautrix/bridge/status"
 	"maunium.net/go/mautrix/event"
 	"maunium.net/go/mautrix/event"
 	"maunium.net/go/mautrix/id"
 	"maunium.net/go/mautrix/id"
 
 
@@ -518,7 +519,7 @@ func fnLogout(ce *WrappedCommandEvent) {
 		return
 		return
 	}
 	}
 	ce.User.Session = nil
 	ce.User.Session = nil
-	ce.User.removeFromJIDMap(bridge.State{StateEvent: bridge.StateLoggedOut})
+	ce.User.removeFromJIDMap(status.BridgeState{StateEvent: status.StateLoggedOut})
 	ce.User.DeleteConnection()
 	ce.User.DeleteConnection()
 	ce.User.DeleteSession()
 	ce.User.DeleteSession()
 	ce.Reply("Logged out successfully.")
 	ce.Reply("Logged out successfully.")
@@ -575,7 +576,7 @@ func fnDeleteSession(ce *WrappedCommandEvent) {
 		ce.Reply("Nothing to purge: no session information stored and no active connection.")
 		ce.Reply("Nothing to purge: no session information stored and no active connection.")
 		return
 		return
 	}
 	}
-	ce.User.removeFromJIDMap(bridge.State{StateEvent: bridge.StateLoggedOut})
+	ce.User.removeFromJIDMap(status.BridgeState{StateEvent: status.StateLoggedOut})
 	ce.User.DeleteConnection()
 	ce.User.DeleteConnection()
 	ce.User.DeleteSession()
 	ce.User.DeleteSession()
 	ce.Reply("Session information purged")
 	ce.Reply("Session information purged")
@@ -600,7 +601,7 @@ func fnReconnect(ce *WrappedCommandEvent) {
 		}
 		}
 	} else {
 	} else {
 		ce.User.DeleteConnection()
 		ce.User.DeleteConnection()
-		ce.User.BridgeState.Send(bridge.State{StateEvent: bridge.StateTransientDisconnect, Error: WANotConnected})
+		ce.User.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: WANotConnected})
 		ce.User.Connect()
 		ce.User.Connect()
 		ce.Reply("Restarted connection to WhatsApp")
 		ce.Reply("Restarted connection to WhatsApp")
 	}
 	}
@@ -622,7 +623,7 @@ func fnDisconnect(ce *WrappedCommandEvent) {
 	}
 	}
 	ce.User.DeleteConnection()
 	ce.User.DeleteConnection()
 	ce.Reply("Successfully disconnected. Use the `reconnect` command to reconnect.")
 	ce.Reply("Successfully disconnected. Use the `reconnect` command to reconnect.")
-	ce.User.BridgeState.Send(bridge.State{StateEvent: bridge.StateBadCredentials, Error: WANotConnected})
+	ce.User.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Error: WANotConnected})
 }
 }
 
 
 var cmdPing = &commands.FullHandler{
 var cmdPing = &commands.FullHandler{

+ 1 - 1
go.mod

@@ -15,7 +15,7 @@ require (
 	golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e
 	golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e
 	google.golang.org/protobuf v1.28.0
 	google.golang.org/protobuf v1.28.0
 	maunium.net/go/maulogger/v2 v2.3.2
 	maunium.net/go/maulogger/v2 v2.3.2
-	maunium.net/go/mautrix v0.11.1-0.20220814160431-6f13ea458647
+	maunium.net/go/mautrix v0.11.1-0.20220815133425-ba1fce8fce24
 )
 )
 
 
 require (
 require (

+ 2 - 2
go.sum

@@ -122,5 +122,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/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
 maunium.net/go/maulogger/v2 v2.3.2 h1:1XmIYmMd3PoQfp9J+PaHhpt80zpfmMqaShzUTC7FwY0=
 maunium.net/go/maulogger/v2 v2.3.2 h1:1XmIYmMd3PoQfp9J+PaHhpt80zpfmMqaShzUTC7FwY0=
 maunium.net/go/maulogger/v2 v2.3.2/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
 maunium.net/go/maulogger/v2 v2.3.2/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
-maunium.net/go/mautrix v0.11.1-0.20220814160431-6f13ea458647 h1:CbSd7DSU7wXVNEhcjikUDuRtrDwegKFQfO4ZEwIxqgg=
-maunium.net/go/mautrix v0.11.1-0.20220814160431-6f13ea458647/go.mod h1:hHvNi5iKVAiI2MAdAeXHtP4g9BvNEX2rsQpSF/x6Kx4=
+maunium.net/go/mautrix v0.11.1-0.20220815133425-ba1fce8fce24 h1:40cxOxHwTw+UYdDTV//tHw9bjNMmJ9uH6ye+C1SbOGA=
+maunium.net/go/mautrix v0.11.1-0.20220815133425-ba1fce8fce24/go.mod h1:hHvNi5iKVAiI2MAdAeXHtP4g9BvNEX2rsQpSF/x6Kx4=

+ 2 - 1
main.go

@@ -36,6 +36,7 @@ import (
 	"maunium.net/go/mautrix"
 	"maunium.net/go/mautrix"
 	"maunium.net/go/mautrix/bridge"
 	"maunium.net/go/mautrix/bridge"
 	"maunium.net/go/mautrix/bridge/commands"
 	"maunium.net/go/mautrix/bridge/commands"
+	"maunium.net/go/mautrix/bridge/status"
 	"maunium.net/go/mautrix/event"
 	"maunium.net/go/mautrix/event"
 	"maunium.net/go/mautrix/id"
 	"maunium.net/go/mautrix/id"
 	"maunium.net/go/mautrix/util/configupgrade"
 	"maunium.net/go/mautrix/util/configupgrade"
@@ -194,7 +195,7 @@ func (br *WABridge) StartUsers() {
 		go user.Connect()
 		go user.Connect()
 	}
 	}
 	if !foundAnySessions {
 	if !foundAnySessions {
-		br.SendGlobalBridgeState(bridge.State{StateEvent: bridge.StateUnconfigured}.Fill(nil))
+		br.SendGlobalBridgeState(status.BridgeState{StateEvent: status.StateUnconfigured}.Fill(nil))
 	}
 	}
 	br.Log.Debugln("Starting custom puppets")
 	br.Log.Debugln("Starting custom puppets")
 	for _, loopuppet := range br.GetAllPuppetsWithCustomMXID() {
 	for _, loopuppet := range br.GetAllPuppetsWithCustomMXID() {

+ 5 - 5
messagetracking.go

@@ -28,7 +28,7 @@ import (
 	"go.mau.fi/whatsmeow"
 	"go.mau.fi/whatsmeow"
 
 
 	"maunium.net/go/mautrix"
 	"maunium.net/go/mautrix"
-	"maunium.net/go/mautrix/bridge"
+	"maunium.net/go/mautrix/bridge/status"
 	"maunium.net/go/mautrix/event"
 	"maunium.net/go/mautrix/event"
 	"maunium.net/go/mautrix/id"
 	"maunium.net/go/mautrix/id"
 )
 )
@@ -197,9 +197,9 @@ func (portal *Portal) sendMessageMetrics(evt *event.Event, err error, part strin
 			level = log.LevelDebug
 			level = log.LevelDebug
 		}
 		}
 		portal.log.Logfln(level, "%s %s %s from %s: %v", part, msgType, evtDescription, evt.Sender, err)
 		portal.log.Logfln(level, "%s %s %s from %s: %v", part, msgType, evtDescription, evt.Sender, err)
-		reason, status, isCertain, sendNotice, _ := errorToStatusReason(err)
-		checkpointStatus := bridge.ReasonToCheckpointStatus(reason, status)
-		portal.bridge.SendMessageCheckpoint(evt, bridge.MsgStepRemote, err, checkpointStatus, ms.getRetryNum())
+		reason, statusCode, isCertain, sendNotice, _ := errorToStatusReason(err)
+		checkpointStatus := status.ReasonToCheckpointStatus(reason, statusCode)
+		portal.bridge.SendMessageCheckpoint(evt, status.MsgStepRemote, err, checkpointStatus, ms.getRetryNum())
 		if sendNotice {
 		if sendNotice {
 			ms.setNoticeID(portal.sendErrorMessage(evt, err, isCertain, ms.getNoticeID()))
 			ms.setNoticeID(portal.sendErrorMessage(evt, err, isCertain, ms.getNoticeID()))
 		}
 		}
@@ -207,7 +207,7 @@ func (portal *Portal) sendMessageMetrics(evt *event.Event, err error, part strin
 	} else {
 	} else {
 		portal.log.Debugfln("Handled Matrix %s %s", msgType, evtDescription)
 		portal.log.Debugfln("Handled Matrix %s %s", msgType, evtDescription)
 		portal.sendDeliveryReceipt(evt.ID)
 		portal.sendDeliveryReceipt(evt.ID)
-		portal.bridge.SendMessageSuccessCheckpoint(evt, bridge.MsgStepRemote, ms.getRetryNum())
+		portal.bridge.SendMessageSuccessCheckpoint(evt, status.MsgStepRemote, ms.getRetryNum())
 		portal.sendStatusEvent(origEvtID, evt.ID, nil)
 		portal.sendStatusEvent(origEvtID, evt.ID, nil)
 		if prevNotice := ms.popNoticeID(); prevNotice != "" {
 		if prevNotice := ms.popNoticeID(); prevNotice != "" {
 			_, _ = portal.MainIntent().RedactEvent(portal.MXID, prevNotice, mautrix.ReqRedact{
 			_, _ = portal.MainIntent().RedactEvent(portal.MXID, prevNotice, mautrix.ReqRedact{

+ 5 - 5
provisioning.go

@@ -39,7 +39,7 @@ import (
 
 
 	log "maunium.net/go/maulogger/v2"
 	log "maunium.net/go/maulogger/v2"
 
 
-	"maunium.net/go/mautrix/bridge"
+	"maunium.net/go/mautrix/bridge/status"
 	"maunium.net/go/mautrix/id"
 	"maunium.net/go/mautrix/id"
 )
 )
 
 
@@ -151,7 +151,7 @@ func (prov *ProvisioningAPI) DeleteSession(w http.ResponseWriter, r *http.Reques
 	user.DeleteConnection()
 	user.DeleteConnection()
 	user.DeleteSession()
 	user.DeleteSession()
 	jsonResponse(w, http.StatusOK, Response{true, "Session information purged"})
 	jsonResponse(w, http.StatusOK, Response{true, "Session information purged"})
-	user.removeFromJIDMap(bridge.State{StateEvent: bridge.StateLoggedOut})
+	user.removeFromJIDMap(status.BridgeState{StateEvent: status.StateLoggedOut})
 }
 }
 
 
 func (prov *ProvisioningAPI) Disconnect(w http.ResponseWriter, r *http.Request) {
 func (prov *ProvisioningAPI) Disconnect(w http.ResponseWriter, r *http.Request) {
@@ -165,7 +165,7 @@ func (prov *ProvisioningAPI) Disconnect(w http.ResponseWriter, r *http.Request)
 	}
 	}
 	user.DeleteConnection()
 	user.DeleteConnection()
 	jsonResponse(w, http.StatusOK, Response{true, "Disconnected from WhatsApp"})
 	jsonResponse(w, http.StatusOK, Response{true, "Disconnected from WhatsApp"})
-	user.BridgeState.Send(bridge.State{StateEvent: bridge.StateBadCredentials, Error: WANotConnected})
+	user.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Error: WANotConnected})
 }
 }
 
 
 func (prov *ProvisioningAPI) Reconnect(w http.ResponseWriter, r *http.Request) {
 func (prov *ProvisioningAPI) Reconnect(w http.ResponseWriter, r *http.Request) {
@@ -182,7 +182,7 @@ func (prov *ProvisioningAPI) Reconnect(w http.ResponseWriter, r *http.Request) {
 		}
 		}
 	} else {
 	} else {
 		user.DeleteConnection()
 		user.DeleteConnection()
-		user.BridgeState.Send(bridge.State{StateEvent: bridge.StateTransientDisconnect, Error: WANotConnected})
+		user.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: WANotConnected})
 		user.Connect()
 		user.Connect()
 		jsonResponse(w, http.StatusAccepted, Response{true, "Restarted connection to WhatsApp"})
 		jsonResponse(w, http.StatusAccepted, Response{true, "Restarted connection to WhatsApp"})
 	}
 	}
@@ -577,7 +577,7 @@ func (prov *ProvisioningAPI) Logout(w http.ResponseWriter, r *http.Request) {
 	}
 	}
 
 
 	user.bridge.Metrics.TrackConnectionState(user.JID, false)
 	user.bridge.Metrics.TrackConnectionState(user.JID, false)
-	user.removeFromJIDMap(bridge.State{StateEvent: bridge.StateLoggedOut})
+	user.removeFromJIDMap(status.BridgeState{StateEvent: status.StateLoggedOut})
 	user.DeleteSession()
 	user.DeleteSession()
 	jsonResponse(w, http.StatusOK, Response{true, "Logged out successfully."})
 	jsonResponse(w, http.StatusOK, Response{true, "Logged out successfully."})
 }
 }

+ 19 - 18
user.go

@@ -38,6 +38,7 @@ import (
 	"maunium.net/go/mautrix/appservice"
 	"maunium.net/go/mautrix/appservice"
 	"maunium.net/go/mautrix/bridge"
 	"maunium.net/go/mautrix/bridge"
 	"maunium.net/go/mautrix/bridge/bridgeconfig"
 	"maunium.net/go/mautrix/bridge/bridgeconfig"
+	"maunium.net/go/mautrix/bridge/status"
 	"maunium.net/go/mautrix/event"
 	"maunium.net/go/mautrix/event"
 	"maunium.net/go/mautrix/format"
 	"maunium.net/go/mautrix/format"
 	"maunium.net/go/mautrix/id"
 	"maunium.net/go/mautrix/id"
@@ -161,7 +162,7 @@ func (user *User) addToJIDMap() {
 	user.bridge.usersLock.Unlock()
 	user.bridge.usersLock.Unlock()
 }
 }
 
 
-func (user *User) removeFromJIDMap(state bridge.State) {
+func (user *User) removeFromJIDMap(state status.BridgeState) {
 	user.bridge.usersLock.Lock()
 	user.bridge.usersLock.Lock()
 	jidUser, ok := user.bridge.usersByUsername[user.JID.User]
 	jidUser, ok := user.bridge.usersByUsername[user.JID.User]
 	if ok && user == jidUser {
 	if ok && user == jidUser {
@@ -533,13 +534,13 @@ func (user *User) Connect() bool {
 		return false
 		return false
 	}
 	}
 	user.log.Debugln("Connecting to WhatsApp")
 	user.log.Debugln("Connecting to WhatsApp")
-	user.BridgeState.Send(bridge.State{StateEvent: bridge.StateConnecting, Error: WAConnecting})
+	user.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnecting, Error: WAConnecting})
 	user.createClient(user.Session)
 	user.createClient(user.Session)
 	err := user.Client.Connect()
 	err := user.Client.Connect()
 	if err != nil {
 	if err != nil {
 		user.log.Warnln("Error connecting to WhatsApp:", err)
 		user.log.Warnln("Error connecting to WhatsApp:", err)
-		user.BridgeState.Send(bridge.State{
-			StateEvent: bridge.StateUnknownError,
+		user.BridgeState.Send(status.BridgeState{
+			StateEvent: status.StateUnknownError,
 			Error:      WAConnectionFailed,
 			Error:      WAConnectionFailed,
 			Info: map[string]interface{}{
 			Info: map[string]interface{}{
 				"go_error": err.Error(),
 				"go_error": err.Error(),
@@ -708,7 +709,7 @@ func (user *User) phoneSeen(ts time.Time) {
 	} else if !user.PhoneRecentlySeen(false) {
 	} else if !user.PhoneRecentlySeen(false) {
 		if user.BridgeState.GetPrev().Error == WAPhoneOffline && user.IsConnected() {
 		if user.BridgeState.GetPrev().Error == WAPhoneOffline && user.IsConnected() {
 			user.log.Debugfln("Saw phone after current bridge state said it has been offline, switching state back to connected")
 			user.log.Debugfln("Saw phone after current bridge state said it has been offline, switching state back to connected")
-			go user.BridgeState.Send(bridge.State{StateEvent: bridge.StateConnected})
+			go user.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnected})
 		} else {
 		} else {
 			user.log.Debugfln("Saw phone after current bridge state said it has been offline, not sending new bridge state (prev: %s, connected: %t)", user.BridgeState.GetPrev().Error, user.IsConnected())
 			user.log.Debugfln("Saw phone after current bridge state said it has been offline, not sending new bridge state (prev: %s, connected: %t)", user.BridgeState.GetPrev().Error, user.IsConnected())
 		}
 		}
@@ -762,19 +763,19 @@ func (user *User) HandleEvent(event interface{}) {
 		}
 		}
 	case *events.OfflineSyncPreview:
 	case *events.OfflineSyncPreview:
 		user.log.Infofln("Server says it's going to send %d messages and %d receipts that were missed during downtime", v.Messages, v.Receipts)
 		user.log.Infofln("Server says it's going to send %d messages and %d receipts that were missed during downtime", v.Messages, v.Receipts)
-		go user.BridgeState.Send(bridge.State{
-			StateEvent: bridge.StateBackfilling,
+		go user.BridgeState.Send(status.BridgeState{
+			StateEvent: status.StateBackfilling,
 			Message:    fmt.Sprintf("backfilling %d messages and %d receipts", v.Messages, v.Receipts),
 			Message:    fmt.Sprintf("backfilling %d messages and %d receipts", v.Messages, v.Receipts),
 		})
 		})
 	case *events.OfflineSyncCompleted:
 	case *events.OfflineSyncCompleted:
 		if !user.PhoneRecentlySeen(true) {
 		if !user.PhoneRecentlySeen(true) {
 			user.log.Infofln("Offline sync completed, but phone last seen date is still %s - sending phone offline bridge status", user.PhoneLastSeen)
 			user.log.Infofln("Offline sync completed, but phone last seen date is still %s - sending phone offline bridge status", user.PhoneLastSeen)
-			go user.BridgeState.Send(bridge.State{StateEvent: bridge.StateTransientDisconnect, Error: WAPhoneOffline})
+			go user.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: WAPhoneOffline})
 		} else {
 		} else {
-			if user.BridgeState.GetPrev().StateEvent == bridge.StateBackfilling {
+			if user.BridgeState.GetPrev().StateEvent == status.StateBackfilling {
 				user.log.Infoln("Offline sync completed")
 				user.log.Infoln("Offline sync completed")
 			}
 			}
-			go user.BridgeState.Send(bridge.State{StateEvent: bridge.StateConnected})
+			go user.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnected})
 		}
 		}
 	case *events.AppStateSyncComplete:
 	case *events.AppStateSyncComplete:
 		if len(user.Client.Store.PushName) > 0 && v.Name == appstate.WAPatchCriticalBlock {
 		if len(user.Client.Store.PushName) > 0 && v.Name == appstate.WAPatchCriticalBlock {
@@ -812,23 +813,23 @@ func (user *User) HandleEvent(event interface{}) {
 		} else {
 		} else {
 			message = "Unknown stream error"
 			message = "Unknown stream error"
 		}
 		}
-		go user.BridgeState.Send(bridge.State{StateEvent: bridge.StateUnknownError, Message: message})
+		go user.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Message: message})
 		user.bridge.Metrics.TrackConnectionState(user.JID, false)
 		user.bridge.Metrics.TrackConnectionState(user.JID, false)
 	case *events.ConnectFailure:
 	case *events.ConnectFailure:
-		go user.BridgeState.Send(bridge.State{StateEvent: bridge.StateUnknownError, Message: fmt.Sprintf("Unknown connection failure: %s", v.Reason)})
+		go user.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Message: fmt.Sprintf("Unknown connection failure: %s", v.Reason)})
 		user.bridge.Metrics.TrackConnectionState(user.JID, false)
 		user.bridge.Metrics.TrackConnectionState(user.JID, false)
 	case *events.ClientOutdated:
 	case *events.ClientOutdated:
 		user.log.Errorfln("Got a client outdated connect failure. The bridge is likely out of date, please update immediately.")
 		user.log.Errorfln("Got a client outdated connect failure. The bridge is likely out of date, please update immediately.")
-		go user.BridgeState.Send(bridge.State{StateEvent: bridge.StateUnknownError, Message: "Connect failure: 405 client outdated"})
+		go user.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Message: "Connect failure: 405 client outdated"})
 		user.bridge.Metrics.TrackConnectionState(user.JID, false)
 		user.bridge.Metrics.TrackConnectionState(user.JID, false)
 	case *events.TemporaryBan:
 	case *events.TemporaryBan:
-		go user.BridgeState.Send(bridge.State{StateEvent: bridge.StateBadCredentials, Message: v.String()})
+		go user.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: v.String()})
 		user.bridge.Metrics.TrackConnectionState(user.JID, false)
 		user.bridge.Metrics.TrackConnectionState(user.JID, false)
 	case *events.Disconnected:
 	case *events.Disconnected:
 		// Don't send the normal transient disconnect state if we're already in a different transient disconnect state.
 		// 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
 		// TODO remove this if/when the phone offline state is moved to a sub-state of CONNECTED
 		if user.BridgeState.GetPrev().Error != WAPhoneOffline && user.PhoneRecentlySeen(false) {
 		if user.BridgeState.GetPrev().Error != WAPhoneOffline && user.PhoneRecentlySeen(false) {
-			go user.BridgeState.Send(bridge.State{StateEvent: bridge.StateTransientDisconnect, Message: "Disconnected from WhatsApp. Trying to reconnect."})
+			go user.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Message: "Disconnected from WhatsApp. Trying to reconnect."})
 		}
 		}
 		user.bridge.Metrics.TrackConnectionState(user.JID, false)
 		user.bridge.Metrics.TrackConnectionState(user.JID, false)
 	case *events.Contact:
 	case *events.Contact:
@@ -913,10 +914,10 @@ func (user *User) HandleEvent(event interface{}) {
 	case *events.AppState:
 	case *events.AppState:
 		// Ignore
 		// Ignore
 	case *events.KeepAliveTimeout:
 	case *events.KeepAliveTimeout:
-		go user.BridgeState.Send(bridge.State{StateEvent: bridge.StateTransientDisconnect, Error: WAKeepaliveTimeout})
+		go user.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: WAKeepaliveTimeout})
 	case *events.KeepAliveRestored:
 	case *events.KeepAliveRestored:
 		user.log.Infof("Keepalive restored after timeouts, sending connected event")
 		user.log.Infof("Keepalive restored after timeouts, sending connected event")
-		go user.BridgeState.Send(bridge.State{StateEvent: bridge.StateConnected})
+		go user.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnected})
 	case *events.MarkChatAsRead:
 	case *events.MarkChatAsRead:
 		if user.bridge.Config.Bridge.SyncManualMarkedUnread {
 		if user.bridge.Config.Bridge.SyncManualMarkedUnread {
 			user.markUnread(user.GetPortalByJID(v.JID), !v.Action.GetRead())
 			user.markUnread(user.GetPortalByJID(v.JID), !v.Action.GetRead())
@@ -1109,7 +1110,7 @@ func (user *User) handleLoggedOut(onConnect bool, reason events.ConnectFailureRe
 	} else if reason == events.ConnectFailureMainDeviceGone {
 	} else if reason == events.ConnectFailureMainDeviceGone {
 		errorCode = WAMainDeviceGone
 		errorCode = WAMainDeviceGone
 	}
 	}
-	user.removeFromJIDMap(bridge.State{StateEvent: bridge.StateBadCredentials, Error: errorCode})
+	user.removeFromJIDMap(status.BridgeState{StateEvent: status.StateBadCredentials, Error: errorCode})
 	user.DeleteConnection()
 	user.DeleteConnection()
 	user.Session = nil
 	user.Session = nil
 	user.JID = types.EmptyJID
 	user.JID = types.EmptyJID