From fed6756ae559de321043b3a97697bc090594938c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 25 Jun 2020 23:33:11 +0300 Subject: [PATCH] Handle leaving and kicking from Matrix. Fixes #47 --- matrix.go | 1 + portal.go | 47 ++++++++++++++++++++++++++++++++++++++++++++++- puppet.go | 13 ++++++------- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/matrix.go b/matrix.go index 44a473d..319e1e1 100644 --- a/matrix.go +++ b/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) diff --git a/portal.go b/portal.go index beb87c2..148b7fe 100644 --- a/portal.go +++ b/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) + } } diff --git a/puppet.go b/puppet.go index 9e496a4..dd6880d 100644 --- a/puppet.go +++ b/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 {