Procházet zdrojové kódy

Make relay mode more like the Signal bridge

Tulir Asokan před 3 roky
rodič
revize
bb9a0f6528
10 změnil soubory, kde provedl 129 přidání a 143 odebrání
  1. 40 32
      commands.go
  2. 5 5
      config/bridge.go
  3. 16 6
      database/portal.go
  4. 12 0
      database/upgrades/2021-10-28-portal-relay-user.go
  5. 1 1
      database/upgrades/upgrades.go
  6. 5 8
      example-config.yaml
  7. 15 24
      main.go
  8. 0 6
      matrix.go
  9. 35 57
      portal.go
  10. 0 4
      user.go

+ 40 - 32
commands.go

@@ -93,17 +93,11 @@ func (handler *CommandHandler) Handle(roomID id.RoomID, user *User, message stri
 		Args:    args[1:],
 	}
 	handler.log.Debugfln("%s sent '%s' in %s", user.MXID, message, roomID)
-	if roomID == handler.bridge.Config.Bridge.Relaybot.ManagementRoom {
-		handler.CommandRelaybot(ce)
-	} else {
-		handler.CommandMux(ce)
-	}
+	handler.CommandMux(ce)
 }
 
 func (handler *CommandHandler) CommandMux(ce *CommandEvent) {
 	switch ce.Command {
-	case "relaybot":
-		handler.CommandRelaybot(ce)
 	case "login":
 		handler.CommandLogin(ce)
 	case "logout-matrix":
@@ -134,7 +128,7 @@ func (handler *CommandHandler) CommandMux(ce *CommandEvent) {
 		handler.CommandLogout(ce)
 	case "toggle":
 		handler.CommandToggle(ce)
-	case "login-matrix", "sync", "list", "open", "pm", "invite-link", "join", "create":
+	case "set-relay", "unset-relay", "login-matrix", "sync", "list", "open", "pm", "invite-link", "join", "create":
 		if !ce.User.HasSession() {
 			ce.Reply("You are not logged in. Use the `login` command to log into WhatsApp.")
 			return
@@ -144,6 +138,10 @@ func (handler *CommandHandler) CommandMux(ce *CommandEvent) {
 		}
 
 		switch ce.Command {
+		case "set-relay":
+			handler.CommandSetRelay(ce)
+		case "unset-relay":
+			handler.CommandUnsetRelay(ce)
 		case "login-matrix":
 			handler.CommandLoginMatrix(ce)
 		case "list":
@@ -175,22 +173,35 @@ func (handler *CommandHandler) CommandDiscardMegolmSession(ce *CommandEvent) {
 	}
 }
 
-func (handler *CommandHandler) CommandRelaybot(ce *CommandEvent) {
-	if handler.bridge.Relaybot == nil {
-		ce.Reply("The relaybot is disabled")
-	} else if !ce.User.Admin {
-		ce.Reply("Only admins can manage the relaybot")
+const cmdSetRelayHelp = `set-relay - Relay messages in this room through your WhatsApp account.`
+
+func (handler *CommandHandler) CommandSetRelay(ce *CommandEvent) {
+	if !handler.bridge.Config.Bridge.Relay.Enabled {
+		ce.Reply("Relay mode is not enabled on this instance of the bridge")
+	} else if ce.Portal == nil {
+		ce.Reply("This is not a portal room")
+	} else if handler.bridge.Config.Bridge.Relay.AdminOnly && !ce.User.Admin {
+		ce.Reply("Only admins are allowed to enable relay mode on this instance of the bridge")
 	} else {
-		if ce.Command == "relaybot" {
-			if len(ce.Args) == 0 {
-				ce.Reply("**Usage:** `relaybot <command>`")
-				return
-			}
-			ce.Command = strings.ToLower(ce.Args[0])
-			ce.Args = ce.Args[1:]
-		}
-		ce.User = handler.bridge.Relaybot
-		handler.CommandMux(ce)
+		ce.Portal.RelayUserID = ce.User.MXID
+		ce.Portal.Update()
+		ce.Reply("Messages from non-logged-in users in this room will now be bridged through your WhatsApp account")
+	}
+}
+
+const cmdUnsetRelayHelp = `set-relay - Stop relaying messages in this room.`
+
+func (handler *CommandHandler) CommandUnsetRelay(ce *CommandEvent) {
+	if !handler.bridge.Config.Bridge.Relay.Enabled {
+		ce.Reply("Relay mode is not enabled on this instance of the bridge")
+	} else if ce.Portal == nil {
+		ce.Reply("This is not a portal room")
+	} else if handler.bridge.Config.Bridge.Relay.AdminOnly && !ce.User.Admin {
+		ce.Reply("Only admins are allowed to enable relay mode on this instance of the bridge")
+	} else {
+		ce.Portal.RelayUserID = ""
+		ce.Portal.Update()
+		ce.Reply("Messages from non-logged-in users will no longer be bridged in this room")
 	}
 }
 
@@ -627,7 +638,7 @@ const cmdHelpHelp = `help - Prints this help`
 // CommandHelp handles help command
 func (handler *CommandHandler) CommandHelp(ce *CommandEvent) {
 	cmdPrefix := ""
-	if ce.User.ManagementRoom != ce.RoomID || ce.User.IsRelaybot {
+	if ce.User.ManagementRoom != ce.RoomID {
 		cmdPrefix = handler.bridge.Config.Bridge.CommandPrefix + " "
 	}
 
@@ -640,6 +651,8 @@ func (handler *CommandHandler) CommandHelp(ce *CommandEvent) {
 		cmdPrefix + cmdReconnectHelp,
 		cmdPrefix + cmdDisconnectHelp,
 		cmdPrefix + cmdPingHelp,
+		cmdPrefix + cmdSetRelayHelp,
+		cmdPrefix + cmdUnsetRelayHelp,
 		cmdPrefix + cmdLoginMatrixHelp,
 		cmdPrefix + cmdLogoutMatrixHelp,
 		cmdPrefix + cmdToggleHelp,
@@ -871,14 +884,9 @@ func (handler *CommandHandler) CommandPM(ce *CommandEvent) {
 	puppet.SyncContact(user, true)
 	portal := user.GetPortalByJID(puppet.JID)
 	if len(portal.MXID) > 0 {
-		if !user.IsRelaybot {
-			_, err = portal.MainIntent().Client.InviteUser(portal.MXID, &mautrix.ReqInviteUser{UserID: user.MXID})
-			if httpErr, ok := err.(mautrix.HTTPError); ok && httpErr.RespError != nil && strings.Contains(httpErr.RespError.Err, "is already in the room") {
-				err = nil
-			}
-		}
-		if err != nil {
-			portal.log.Warnfln("Failed to invite %s to portal: %v. Creating new portal", user.MXID, err)
+		ok := portal.ensureUserInvited(user)
+		if !ok {
+			portal.log.Warnfln("ensureUserInvited(%s) returned false, creating new portal", user.MXID)
 			portal.MXID = ""
 		} else {
 			ce.Reply("You already have a private chat portal with that user at [%s](https://matrix.to/#/%s)", puppet.Displayname, portal.MXID)

+ 5 - 5
config/bridge.go

@@ -85,7 +85,7 @@ type BridgeConfig struct {
 
 	Permissions PermissionConfig `yaml:"permissions"`
 
-	Relaybot RelaybotConfig `yaml:"relaybot"`
+	Relay RelaybotConfig `yaml:"relay"`
 
 	usernameTemplate    *template.Template `yaml:"-"`
 	displaynameTemplate *template.Template `yaml:"-"`
@@ -110,6 +110,8 @@ func (bc *BridgeConfig) setDefaults() {
 
 	bc.BridgeNotices = true
 	bc.EnableStatusBroadcast = true
+
+	bc.Relay.AdminOnly = true
 }
 
 type umBridgeConfig BridgeConfig
@@ -271,10 +273,8 @@ func (pc PermissionConfig) GetPermissionLevel(userID id.UserID) PermissionLevel
 }
 
 type RelaybotConfig struct {
-	Enabled        bool        `yaml:"enabled"`
-	ManagementRoom id.RoomID   `yaml:"management"`
-	InviteUsers    []id.UserID `yaml:"invites"`
-
+	Enabled          bool                         `yaml:"enabled"`
+	AdminOnly        bool                         `yaml:"admin_only"`
 	MessageFormats   map[event.MessageType]string `yaml:"message_formats"`
 	messageTemplates *template.Template           `yaml:"-"`
 }

+ 16 - 6
database/portal.go

@@ -121,11 +121,13 @@ type Portal struct {
 
 	FirstEventID id.EventID
 	NextBatchID  id.BatchID
+
+	RelayUserID id.UserID
 }
 
 func (portal *Portal) Scan(row Scannable) *Portal {
-	var mxid, avatarURL, firstEventID, nextBatchID sql.NullString
-	err := row.Scan(&portal.Key.JID, &portal.Key.Receiver, &mxid, &portal.Name, &portal.Topic, &portal.Avatar, &avatarURL, &portal.Encrypted, &firstEventID, &nextBatchID)
+	var mxid, avatarURL, firstEventID, nextBatchID, relayUserID sql.NullString
+	err := row.Scan(&portal.Key.JID, &portal.Key.Receiver, &mxid, &portal.Name, &portal.Topic, &portal.Avatar, &avatarURL, &portal.Encrypted, &firstEventID, &nextBatchID, &relayUserID)
 	if err != nil {
 		if err != sql.ErrNoRows {
 			portal.log.Errorln("Database scan failed:", err)
@@ -136,6 +138,7 @@ func (portal *Portal) Scan(row Scannable) *Portal {
 	portal.AvatarURL, _ = id.ParseContentURI(avatarURL.String)
 	portal.FirstEventID = id.EventID(firstEventID.String)
 	portal.NextBatchID = id.BatchID(nextBatchID.String)
+	portal.RelayUserID = id.UserID(relayUserID.String)
 	return portal
 }
 
@@ -146,17 +149,24 @@ func (portal *Portal) mxidPtr() *id.RoomID {
 	return nil
 }
 
+func (portal *Portal) relayUserPtr() *id.UserID {
+	if len(portal.RelayUserID) > 0 {
+		return &portal.RelayUserID
+	}
+	return nil
+}
+
 func (portal *Portal) Insert() {
-	_, err := portal.db.Exec("INSERT INTO portal (jid, receiver, mxid, name, topic, avatar, avatar_url, encrypted, first_event_id, next_batch_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
-		portal.Key.JID, portal.Key.Receiver, portal.mxidPtr(), portal.Name, portal.Topic, portal.Avatar, portal.AvatarURL.String(), portal.Encrypted, portal.FirstEventID.String(), portal.NextBatchID.String())
+	_, err := portal.db.Exec("INSERT INTO portal (jid, receiver, mxid, name, topic, avatar, avatar_url, encrypted, first_event_id, next_batch_id, relay_user_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)",
+		portal.Key.JID, portal.Key.Receiver, portal.mxidPtr(), portal.Name, portal.Topic, portal.Avatar, portal.AvatarURL.String(), portal.Encrypted, portal.FirstEventID.String(), portal.NextBatchID.String(), portal.relayUserPtr())
 	if err != nil {
 		portal.log.Warnfln("Failed to insert %s: %v", portal.Key, err)
 	}
 }
 
 func (portal *Portal) Update() {
-	_, err := portal.db.Exec("UPDATE portal SET mxid=$1, name=$2, topic=$3, avatar=$4, avatar_url=$5, encrypted=$6, first_event_id=$7, next_batch_id=$8 WHERE jid=$9 AND receiver=$10",
-		portal.mxidPtr(), portal.Name, portal.Topic, portal.Avatar, portal.AvatarURL.String(), portal.Encrypted, portal.FirstEventID.String(), portal.NextBatchID.String(), portal.Key.JID, portal.Key.Receiver)
+	_, err := portal.db.Exec("UPDATE portal SET mxid=$3, name=$4, topic=$5, avatar=$6, avatar_url=$7, encrypted=$8, first_event_id=$9, next_batch_id=$10, relay_user_id=$11 WHERE jid=$1 AND receiver=$2",
+		portal.Key.JID, portal.Key.Receiver, portal.mxidPtr(), portal.Name, portal.Topic, portal.Avatar, portal.AvatarURL.String(), portal.Encrypted, portal.FirstEventID.String(), portal.NextBatchID.String(), portal.relayUserPtr())
 	if err != nil {
 		portal.log.Warnfln("Failed to update %s: %v", portal.Key, err)
 	}

+ 12 - 0
database/upgrades/2021-10-28-portal-relay-user.go

@@ -0,0 +1,12 @@
+package upgrades
+
+import (
+	"database/sql"
+)
+
+func init() {
+	upgrades[28] = upgrade{"Add relay user field to portal table", func(tx *sql.Tx, ctx context) error {
+		_, err := tx.Exec(`ALTER TABLE portal ADD COLUMN relay_user_id TEXT`)
+		return err
+	}}
+}

+ 1 - 1
database/upgrades/upgrades.go

@@ -39,7 +39,7 @@ type upgrade struct {
 	fn      upgradeFunc
 }
 
-const NumberOfUpgrades = 28
+const NumberOfUpgrades = 29
 
 var upgrades [NumberOfUpgrades]upgrade
 

+ 5 - 8
example-config.yaml

@@ -204,15 +204,12 @@ bridge:
         "example.com": user
         "@admin:example.com": admin
 
-    relaybot:
-        # Whether or not relaybot support is enabled.
+    relay:
+        # Whether relay mode should be allowed. If allowed, `!signal set-relay` can be used to turn any
+        # authenticated user into a relaybot for that chat.
         enabled: false
-        # The management room for the bot. This is where all status notifications are posted and
-        # in this room, you can use `!wa <command>` instead of `!wa relaybot <command>`. Omitting
-        # the command prefix completely like in user management rooms is not possible.
-        management: "!foo:example.com"
-        # List of users to invite to all created rooms that include the relaybot.
-        invites: []
+        # Should only admins be allowed to set themselves as relay users?
+        admin_only: true
         # The formats to use when sending messages to WhatsApp via the relaybot.
         message_formats:
             m.text: "<b>{{ .Sender.Displayname }}</b>: {{ .Message }}"

+ 15 - 24
main.go

@@ -47,21 +47,29 @@ import (
 	"maunium.net/go/mautrix-whatsapp/database/upgrades"
 )
 
+// The name and repo URL of the bridge.
 var (
-	// These are static
 	Name = "mautrix-whatsapp"
 	URL  = "https://github.com/mautrix/whatsapp"
-	// This is changed when making a release
-	Version = "0.1.8"
-	// This is filled by init()
-	WAVersion     = ""
-	VersionString = ""
-	// These are filled at build time with the -X linker flag
+)
+
+// Information to find out exactly which commit the bridge was built from.
+// These are filled at build time with the -X linker flag.
+var (
 	Tag       = "unknown"
 	Commit    = "unknown"
 	BuildTime = "unknown"
 )
 
+var (
+	// Version is the version number of the bridge. Changed manually when making a release.
+	Version = "0.1.8"
+	// WAVersion is the version number exposed to WhatsApp. Filled in init()
+	WAVersion = ""
+	// VersionString is the bridge version, plus commit information. Filled in init() using the build-time values.
+	VersionString = ""
+)
+
 func init() {
 	if len(Tag) > 0 && Tag[0] == 'v' {
 		Tag = Tag[1:]
@@ -151,7 +159,6 @@ type Bridge struct {
 	Provisioning   *ProvisioningAPI
 	Bot            *appservice.IntentAPI
 	Formatter      *Formatter
-	Relaybot       *User
 	Crypto         Crypto
 	Metrics        *MetricsHandler
 	WAContainer    *sqlstore.Container
@@ -320,7 +327,6 @@ func (bridge *Bridge) Start() {
 		bridge.Log.Debugln("Initializing provisioning API")
 		bridge.Provisioning.Init()
 	}
-	bridge.LoadRelaybot()
 	bridge.Log.Debugln("Starting application service HTTP server")
 	go bridge.AS.Start()
 	bridge.Log.Debugln("Starting event processor")
@@ -353,21 +359,6 @@ func (bridge *Bridge) ResendBridgeInfo() {
 	bridge.Log.Infoln("Finished re-sending bridge info state events")
 }
 
-func (bridge *Bridge) LoadRelaybot() {
-	if !bridge.Config.Bridge.Relaybot.Enabled {
-		return
-	}
-	bridge.Relaybot = bridge.GetUserByMXID("relaybot")
-	if bridge.Relaybot.HasSession() {
-		bridge.Log.Debugln("Relaybot is enabled")
-	} else {
-		bridge.Log.Debugln("Relaybot is enabled, but not logged in")
-	}
-	bridge.Relaybot.ManagementRoom = bridge.Config.Bridge.Relaybot.ManagementRoom
-	bridge.Relaybot.IsRelaybot = true
-	bridge.Relaybot.Connect()
-}
-
 func (bridge *Bridge) UpdateBotProfile() {
 	bridge.Log.Debugln("Updating bot profile")
 	botConfig := bridge.Config.AppService.Bot

+ 0 - 6
matrix.go

@@ -114,12 +114,6 @@ func (mx *MatrixHandler) HandleBotInvite(evt *event.Event) {
 		return
 	}
 
-	if evt.RoomID == mx.bridge.Config.Bridge.Relaybot.ManagementRoom {
-		_, _ = intent.SendNotice(evt.RoomID, "This is the relaybot management room. Send `!wa help` to get a list of commands.")
-		mx.log.Debugln("Joined relaybot management room", evt.RoomID, "after invite from", evt.Sender)
-		return
-	}
-
 	hasPuppets := false
 	for mxid, _ := range members.Joined {
 		if mxid == intent.UserID || mxid == evt.Sender {

+ 35 - 57
portal.go

@@ -190,7 +190,7 @@ type Portal struct {
 
 	messages chan PortalMessage
 
-	hasRelaybot *bool
+	relayUser *User
 }
 
 func (portal *Portal) handleMessageLoop() {
@@ -519,14 +519,17 @@ func (portal *Portal) SyncParticipants(source *User, metadata *types.GroupInfo)
 	participantMap := make(map[types.JID]bool)
 	for _, participant := range metadata.Participants {
 		participantMap[participant.JID] = true
-		user := portal.bridge.GetUserByJID(participant.JID)
-		portal.userMXIDAction(user, portal.ensureMXIDInvited)
-
 		puppet := portal.bridge.GetPuppetByJID(participant.JID)
 		puppet.SyncContact(source, true)
-		err = puppet.IntentFor(portal).EnsureJoined(portal.MXID)
-		if err != nil {
-			portal.log.Warnfln("Failed to make puppet of %s join %s: %v", participant.JID, portal.MXID, err)
+		user := portal.bridge.GetUserByJID(participant.JID)
+		if user != nil {
+			portal.ensureUserInvited(user)
+		}
+		if user == nil || !puppet.IntentFor(portal).IsCustomPuppet {
+			err = puppet.IntentFor(portal).EnsureJoined(portal.MXID)
+			if err != nil {
+				portal.log.Warnfln("Failed to make puppet of %s join %s: %v", participant.JID, portal.MXID, err)
+			}
 		}
 
 		expectedLevel := 0
@@ -692,20 +695,6 @@ func (portal *Portal) UpdateMetadata(user *User) bool {
 	return update
 }
 
-func (portal *Portal) userMXIDAction(user *User, fn func(mxid id.UserID)) {
-	if user == nil {
-		return
-	}
-
-	if user == portal.bridge.Relaybot {
-		for _, mxid := range portal.bridge.Config.Bridge.Relaybot.InviteUsers {
-			fn(mxid)
-		}
-	} else {
-		fn(user.MXID)
-	}
-}
-
 func (portal *Portal) ensureMXIDInvited(mxid id.UserID) {
 	err := portal.MainIntent().EnsureInvited(portal.MXID, mxid)
 	if err != nil {
@@ -713,12 +702,7 @@ func (portal *Portal) ensureMXIDInvited(mxid id.UserID) {
 	}
 }
 
-func (portal *Portal) ensureUserInvited(user *User) {
-	if user.IsRelaybot {
-		portal.userMXIDAction(user, portal.ensureMXIDInvited)
-		return
-	}
-
+func (portal *Portal) ensureUserInvited(user *User) (ok bool) {
 	inviteContent := event.Content{
 		Parsed: &event.MemberEventContent{
 			Membership: event.MembershipInvite,
@@ -734,26 +718,28 @@ func (portal *Portal) ensureUserInvited(user *User) {
 	var httpErr mautrix.HTTPError
 	if err != nil && errors.As(err, &httpErr) && httpErr.RespError != nil && strings.Contains(httpErr.RespError.Err, "is already in the room") {
 		portal.bridge.StateStore.SetMembership(portal.MXID, user.MXID, event.MembershipJoin)
+		ok = true
 	} else if err != nil {
 		portal.log.Warnfln("Failed to invite %s: %v", user.MXID, err)
+	} else {
+		ok = true
 	}
 
 	if customPuppet != nil && customPuppet.CustomIntent() != nil {
 		err = customPuppet.CustomIntent().EnsureJoined(portal.MXID)
 		if err != nil {
 			portal.log.Warnfln("Failed to auto-join portal as %s: %v", user.MXID, err)
+			ok = false
+		} else {
+			ok = true
 		}
 	}
+	return
 }
 
 func (portal *Portal) Sync(user *User) bool {
 	portal.log.Infoln("Syncing portal for", user.MXID)
 
-	if user.IsRelaybot {
-		yes := true
-		portal.hasRelaybot = &yes
-	}
-
 	if len(portal.MXID) == 0 {
 		err := portal.CreateMatrixRoom(user)
 		if err != nil {
@@ -1299,9 +1285,6 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
 	}
 
 	var invite []id.UserID
-	if user.IsRelaybot {
-		invite = portal.bridge.Config.Bridge.Relaybot.InviteUsers
-	}
 
 	if portal.bridge.Config.Bridge.Encryption.Default {
 		initialState = append(initialState, &event.Event{
@@ -1354,7 +1337,7 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
 	//if broadcastMetadata != nil {
 	//	portal.SyncBroadcastRecipients(user, broadcastMetadata)
 	//}
-	if portal.IsPrivateChat() && !user.IsRelaybot {
+	if portal.IsPrivateChat() {
 		puppet := user.bridge.GetPuppetByJID(portal.Key.JID)
 
 		if portal.bridge.Config.Bridge.Encryption.Default {
@@ -1397,15 +1380,16 @@ func (portal *Portal) IsStatusBroadcastList() bool {
 }
 
 func (portal *Portal) HasRelaybot() bool {
-	if portal.bridge.Relaybot == nil {
-		return false
-	} else if portal.hasRelaybot == nil {
-		// FIXME
-		//val := portal.bridge.Relaybot.IsInPortal(portal.Key)
-		val := true
-		portal.hasRelaybot = &val
+	return portal.bridge.Config.Bridge.Relay.Enabled && len(portal.RelayUserID) > 0
+}
+
+func (portal *Portal) GetRelayUser() *User {
+	if !portal.HasRelaybot() {
+		return nil
+	} else if portal.relayUser == nil {
+		portal.relayUser = portal.bridge.GetUserByMXID(portal.RelayUserID)
 	}
-	return *portal.hasRelaybot
+	return portal.relayUser
 }
 
 func (portal *Portal) MainIntent() *appservice.IntentAPI {
@@ -1426,8 +1410,8 @@ func (portal *Portal) SetReply(content *event.MessageEventContent, replyToID typ
 			portal.log.Warnln("Failed to get reply target:", err)
 			return
 		}
+		_ = evt.Content.ParseRaw(evt.Type)
 		if evt.Type == event.EventEncrypted {
-			_ = evt.Content.ParseRaw(evt.Type)
 			decryptedEvt, err := portal.bridge.Crypto.Decrypt(evt)
 			if err != nil {
 				portal.log.Warnln("Failed to decrypt reply target:", err)
@@ -1435,7 +1419,6 @@ func (portal *Portal) SetReply(content *event.MessageEventContent, replyToID typ
 				evt = decryptedEvt
 			}
 		}
-		_ = evt.Content.ParseRaw(evt.Type)
 		content.SetReply(evt)
 	}
 	return
@@ -2176,7 +2159,7 @@ func (portal *Portal) addRelaybotFormat(sender *User, content *event.MessageEven
 		content.FormattedBody = strings.Replace(html.EscapeString(content.Body), "\n", "<br/>", -1)
 		content.Format = event.FormatHTML
 	}
-	data, err := portal.bridge.Config.Bridge.Relaybot.FormatMessage(content, sender.MXID, member)
+	data, err := portal.bridge.Config.Bridge.Relay.FormatMessage(content, sender.MXID, member)
 	if err != nil {
 		portal.log.Errorln("Failed to apply relaybot format:", err)
 	}
@@ -2243,18 +2226,13 @@ func (portal *Portal) convertMatrixMessage(sender *User, evt *event.Event) (*waP
 		}
 	}
 	relaybotFormatted := false
-	if sender.NeedsRelaybot(portal) {
+	if !sender.HasSession() {
 		if !portal.HasRelaybot() {
-			if sender.HasSession() {
-				portal.log.Debugln("Database says", sender.MXID, "not in chat and no relaybot, but trying to send anyway")
-			} else {
-				portal.log.Debugln("Ignoring message from", sender.MXID, "in chat with no relaybot")
-				return nil, sender
-			}
-		} else {
-			relaybotFormatted = portal.addRelaybotFormat(sender, content)
-			sender = portal.bridge.Relaybot
+			portal.log.Debugln("Ignoring message from", sender.MXID, "in chat with no relaybot")
+			return nil, sender
 		}
+		relaybotFormatted = portal.addRelaybotFormat(sender, content)
+		sender = portal.GetRelayUser()
 	}
 	if evt.Type == event.EventSticker {
 		content.MsgType = event.MsgImage

+ 0 - 4
user.go

@@ -58,8 +58,6 @@ type User struct {
 	Whitelisted         bool
 	RelaybotWhitelisted bool
 
-	IsRelaybot bool
-
 	mgmtCreateLock sync.Mutex
 	connLock       sync.Mutex
 
@@ -179,8 +177,6 @@ func (bridge *Bridge) NewUser(dbUser *database.User) *User {
 		log:    bridge.Log.Sub("User").Sub(string(dbUser.MXID)),
 
 		historySyncs: make(chan *events.HistorySync, 32),
-
-		IsRelaybot: false,
 	}
 	user.RelaybotWhitelisted = user.bridge.Config.Bridge.Permissions.IsRelaybotWhitelisted(user.MXID)
 	user.Whitelisted = user.bridge.Config.Bridge.Permissions.IsWhitelisted(user.MXID)