Browse Source

Handle leaving and kicking from Matrix. Fixes #47

Tulir Asokan 5 years ago
parent
commit
fed6756ae5
3 changed files with 53 additions and 8 deletions
  1. 1 0
      matrix.go
  2. 46 1
      portal.go
  3. 6 7
      puppet.go

+ 1 - 0
matrix.go

@@ -142,6 +142,7 @@ func (mx *MatrixHandler) HandleMembership(evt *event.Event) {
 	content := evt.Content.AsMember()
 	if content.Membership == event.MembershipInvite && id.UserID(evt.GetStateKey()) == mx.as.BotMXID() {
 		mx.HandleBotInvite(evt)
+		return
 	}
 
 	portal := mx.bridge.GetPortalByMXID(evt.RoomID)

+ 46 - 1
portal.go

@@ -1929,6 +1929,35 @@ func (portal *Portal) Delete() {
 	portal.bridge.portalsLock.Unlock()
 }
 
+func (portal *Portal) GetMatrixUsers() ([]id.UserID, error) {
+	members, err := portal.MainIntent().JoinedMembers(portal.MXID)
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to get member list")
+	}
+	var users []id.UserID
+	for userID := range members.Joined {
+		_, isPuppet := portal.bridge.ParsePuppetMXID(userID)
+		if !isPuppet && userID != portal.bridge.Bot.UserID {
+			users = append(users, userID)
+		}
+	}
+	return users, nil
+}
+
+func (portal *Portal) CleanupIfEmpty() {
+	users, err := portal.GetMatrixUsers()
+	if err != nil {
+		portal.log.Errorfln("Failed to get Matrix user list to determine if portal needs to be cleaned up: %v", err)
+		return
+	}
+
+	if len(users) == 0 {
+		portal.log.Infoln("Room seems to be empty, cleaning up...")
+		portal.Delete()
+		portal.Cleanup(false)
+	}
+}
+
 func (portal *Portal) Cleanup(puppetsOnly bool) {
 	if len(portal.MXID) == 0 {
 		return
@@ -1975,9 +2004,25 @@ func (portal *Portal) HandleMatrixLeave(sender *User) {
 		portal.Delete()
 		portal.Cleanup(false)
 		return
+	} else {
+		resp, err := sender.Conn.LeaveGroup(portal.Key.JID)
+		if err != nil {
+			portal.log.Errorfln("Failed to leave group as %s: %v", sender.MXID, err)
+			return
+		}
+		portal.log.Infoln("Leave response:", <-resp)
+		portal.CleanupIfEmpty()
 	}
 }
 
 func (portal *Portal) HandleMatrixKick(sender *User, event *event.Event) {
-	// TODO
+	puppet := portal.bridge.GetPuppetByMXID(id.UserID(event.GetStateKey()))
+	if puppet != nil {
+		resp, err := sender.Conn.RemoveMember(portal.Key.JID, []string{puppet.JID})
+		if err != nil {
+			portal.log.Errorfln("Failed to kick %s from group as %s: %v", puppet.JID, sender.MXID, err)
+			return
+		}
+		portal.log.Infoln("Kick %s response: %s", puppet.JID, <-resp)
+	}
 }

+ 6 - 7
puppet.go

@@ -23,7 +23,6 @@ import (
 	"strings"
 
 	"github.com/Rhymen/go-whatsapp"
-
 	log "maunium.net/go/maulogger/v2"
 
 	"maunium.net/go/mautrix/appservice"
@@ -34,13 +33,13 @@ import (
 	"maunium.net/go/mautrix-whatsapp/whatsapp-ext"
 )
 
+var userIDRegex *regexp.Regexp
+
 func (bridge *Bridge) ParsePuppetMXID(mxid id.UserID) (types.WhatsAppID, bool) {
-	userIDRegex, err := regexp.Compile(fmt.Sprintf("^@%s:%s$",
-		bridge.Config.Bridge.FormatUsername("([0-9]+)"),
-		bridge.Config.Homeserver.Domain))
-	if err != nil {
-		bridge.Log.Warnln("Failed to compile puppet user ID regex:", err)
-		return "", false
+	if userIDRegex == nil {
+		userIDRegex = regexp.MustCompile(fmt.Sprintf("^@%s:%s$",
+			bridge.Config.Bridge.FormatUsername("([0-9]+)"),
+			bridge.Config.Homeserver.Domain))
 	}
 	match := userIDRegex.FindStringSubmatch(string(mxid))
 	if match == nil || len(match) != 2 {