Handle WhatsApp kicks and Matrix invites
This commit is contained in:
parent
fed6756ae5
commit
326293303d
@ -235,7 +235,7 @@ func (handler *CommandHandler) CommandJoin(ce *CommandEvent) {
|
||||
portal := handler.bridge.GetPortalByJID(database.GroupPortalKey(jid))
|
||||
if len(portal.MXID) > 0 {
|
||||
portal.Sync(ce.User, whatsapp.Contact{Jid: portal.Key.JID})
|
||||
ce.Reply("Successfully joined group \"%s\" and synced portal room", portal.Name)
|
||||
ce.Reply("Successfully joined group \"%s\" and synced portal room: [%s](https://matrix.to/#/%s)", portal.Name, portal.Name, portal.MXID)
|
||||
} else {
|
||||
err = portal.CreateMatrixRoom(ce.User)
|
||||
if err != nil {
|
||||
@ -243,7 +243,7 @@ func (handler *CommandHandler) CommandJoin(ce *CommandEvent) {
|
||||
return
|
||||
}
|
||||
|
||||
ce.Reply("Successfully joined group \"%s\" and created portal room", portal.Name)
|
||||
ce.Reply("Successfully joined group \"%s\" and created portal room: [%s](https://matrix.to/#/%s)", portal.Name, portal.Name, portal.MXID)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,8 +155,10 @@ func (mx *MatrixHandler) HandleMembership(evt *event.Event) {
|
||||
return
|
||||
}
|
||||
|
||||
isSelf := id.UserID(evt.GetStateKey()) == evt.Sender
|
||||
|
||||
if content.Membership == event.MembershipLeave {
|
||||
if id.UserID(evt.GetStateKey()) == evt.Sender {
|
||||
if isSelf {
|
||||
if evt.Unsigned.PrevContent != nil {
|
||||
_ = evt.Unsigned.PrevContent.ParseRaw(evt.Type)
|
||||
prevContent, ok := evt.Unsigned.PrevContent.Parsed.(*event.MemberEventContent)
|
||||
@ -169,6 +171,8 @@ func (mx *MatrixHandler) HandleMembership(evt *event.Event) {
|
||||
} else {
|
||||
portal.HandleMatrixKick(user, evt)
|
||||
}
|
||||
} else if content.Membership == event.MembershipInvite && !isSelf {
|
||||
portal.HandleMatrixInvite(user, evt)
|
||||
}
|
||||
}
|
||||
|
||||
|
64
portal.go
64
portal.go
@ -1281,6 +1281,53 @@ func (portal *Portal) encryptFile(data []byte, mimeType string) ([]byte, string,
|
||||
return file.Encrypt(data), "application/octet-stream", file
|
||||
}
|
||||
|
||||
func (portal *Portal) tryKickUser(userID id.UserID, intent *appservice.IntentAPI) error {
|
||||
_, err := intent.KickUser(portal.MXID, &mautrix.ReqKickUser{UserID: userID})
|
||||
if err != nil {
|
||||
httpErr, ok := err.(mautrix.HTTPError)
|
||||
if ok && httpErr.RespError != nil && httpErr.RespError.ErrCode == "M_FORBIDDEN" {
|
||||
_, err = portal.MainIntent().KickUser(portal.MXID, &mautrix.ReqKickUser{UserID: userID})
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (portal *Portal) removeUser(isSameUser bool, kicker *appservice.IntentAPI, target id.UserID, targetIntent *appservice.IntentAPI) {
|
||||
if !isSameUser || targetIntent == nil {
|
||||
err := portal.tryKickUser(target, kicker)
|
||||
if err != nil {
|
||||
portal.log.Warnfln("Failed to kick %s from %s: %v", target, portal.MXID, err)
|
||||
if targetIntent != nil {
|
||||
_, _ = targetIntent.LeaveRoom(portal.MXID)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_, err := targetIntent.LeaveRoom(portal.MXID)
|
||||
if err != nil {
|
||||
portal.log.Warnfln("Failed to leave portal as %s: %v", target, err)
|
||||
_, _ = portal.MainIntent().KickUser(portal.MXID, &mautrix.ReqKickUser{UserID: target})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (portal *Portal) HandleWhatsAppKick(senderJID string, jids []string) {
|
||||
sender := portal.bridge.GetPuppetByJID(senderJID)
|
||||
senderIntent := sender.IntentFor(portal)
|
||||
for _, jid := range jids {
|
||||
puppet := portal.bridge.GetPuppetByJID(jid)
|
||||
portal.removeUser(puppet.JID == sender.JID, senderIntent, puppet.MXID, puppet.DefaultIntent())
|
||||
|
||||
user := portal.bridge.GetUserByJID(jid)
|
||||
if user != nil {
|
||||
var customIntent *appservice.IntentAPI
|
||||
if puppet.CustomMXID == user.MXID {
|
||||
customIntent = puppet.CustomIntent()
|
||||
}
|
||||
portal.removeUser(puppet.JID == sender.JID, senderIntent, user.MXID, customIntent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type base struct {
|
||||
download func() ([]byte, error)
|
||||
info whatsapp.MessageInfo
|
||||
@ -2005,6 +2052,7 @@ func (portal *Portal) HandleMatrixLeave(sender *User) {
|
||||
portal.Cleanup(false)
|
||||
return
|
||||
} else {
|
||||
// TODO should we somehow deduplicate this call if this leave was sent by the bridge?
|
||||
resp, err := sender.Conn.LeaveGroup(portal.Key.JID)
|
||||
if err != nil {
|
||||
portal.log.Errorfln("Failed to leave group as %s: %v", sender.MXID, err)
|
||||
@ -2015,8 +2063,8 @@ func (portal *Portal) HandleMatrixLeave(sender *User) {
|
||||
}
|
||||
}
|
||||
|
||||
func (portal *Portal) HandleMatrixKick(sender *User, event *event.Event) {
|
||||
puppet := portal.bridge.GetPuppetByMXID(id.UserID(event.GetStateKey()))
|
||||
func (portal *Portal) HandleMatrixKick(sender *User, evt *event.Event) {
|
||||
puppet := portal.bridge.GetPuppetByMXID(id.UserID(evt.GetStateKey()))
|
||||
if puppet != nil {
|
||||
resp, err := sender.Conn.RemoveMember(portal.Key.JID, []string{puppet.JID})
|
||||
if err != nil {
|
||||
@ -2026,3 +2074,15 @@ func (portal *Portal) HandleMatrixKick(sender *User, event *event.Event) {
|
||||
portal.log.Infoln("Kick %s response: %s", puppet.JID, <-resp)
|
||||
}
|
||||
}
|
||||
|
||||
func (portal *Portal) HandleMatrixInvite(sender *User, evt *event.Event) {
|
||||
puppet := portal.bridge.GetPuppetByMXID(id.UserID(evt.GetStateKey()))
|
||||
if puppet != nil {
|
||||
resp, err := sender.Conn.AddMember(portal.Key.JID, []string{puppet.JID})
|
||||
if err != nil {
|
||||
portal.log.Errorfln("Failed to add %s to group as %s: %v", puppet.JID, sender.MXID, err)
|
||||
return
|
||||
}
|
||||
portal.log.Infoln("Add %s response: %s", puppet.JID, <-resp)
|
||||
}
|
||||
}
|
||||
|
18
user.go
18
user.go
@ -861,6 +861,14 @@ func (user *User) HandleChatUpdate(cmd whatsappExt.ChatUpdate) {
|
||||
|
||||
portal := user.GetPortalByJID(cmd.JID)
|
||||
if len(portal.MXID) == 0 {
|
||||
if cmd.Data.Action == whatsappExt.ChatActionIntroduce && cmd.Data.SenderJID != "unknown" {
|
||||
go func() {
|
||||
err := portal.CreateMatrixRoom(user)
|
||||
if err != nil {
|
||||
user.log.Errorln("Failed to create portal room after receiving join event:", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -872,13 +880,19 @@ func (user *User) HandleChatUpdate(cmd whatsappExt.ChatUpdate) {
|
||||
case whatsappExt.ChatActionRemoveTopic:
|
||||
go portal.UpdateTopic("", cmd.Data.SenderJID, true)
|
||||
case whatsappExt.ChatActionPromote:
|
||||
go portal.ChangeAdminStatus(cmd.Data.PermissionChange.JIDs, true)
|
||||
go portal.ChangeAdminStatus(cmd.Data.UserChange.JIDs, true)
|
||||
case whatsappExt.ChatActionDemote:
|
||||
go portal.ChangeAdminStatus(cmd.Data.PermissionChange.JIDs, false)
|
||||
go portal.ChangeAdminStatus(cmd.Data.UserChange.JIDs, false)
|
||||
case whatsappExt.ChatActionAnnounce:
|
||||
go portal.RestrictMessageSending(cmd.Data.Announce)
|
||||
case whatsappExt.ChatActionRestrict:
|
||||
go portal.RestrictMetadataChanges(cmd.Data.Restrict)
|
||||
case whatsappExt.ChatActionRemove:
|
||||
go portal.HandleWhatsAppKick(cmd.Data.SenderJID, cmd.Data.UserChange.JIDs)
|
||||
case whatsappExt.ChatActionIntroduce:
|
||||
if cmd.Data.SenderJID != "unknown" {
|
||||
go portal.Sync(user, whatsapp.Contact{Jid: portal.Key.JID})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ const (
|
||||
ChatActionPromote ChatActionType = "promote"
|
||||
ChatActionDemote ChatActionType = "demote"
|
||||
ChatActionIntroduce ChatActionType = "introduce"
|
||||
ChatActionRemove ChatActionType = "remove"
|
||||
)
|
||||
|
||||
type ChatUpdateData struct {
|
||||
@ -80,7 +81,7 @@ type ChatUpdateData struct {
|
||||
|
||||
Announce bool
|
||||
|
||||
PermissionChange struct {
|
||||
UserChange struct {
|
||||
JIDs []string `json:"participants"`
|
||||
}
|
||||
}
|
||||
@ -127,8 +128,8 @@ func (cud *ChatUpdateData) UnmarshalJSON(data []byte) error {
|
||||
unmarshalTo = &cud.Restrict
|
||||
case ChatActionAnnounce:
|
||||
unmarshalTo = &cud.Announce
|
||||
case ChatActionPromote, ChatActionDemote:
|
||||
unmarshalTo = &cud.PermissionChange
|
||||
case ChatActionPromote, ChatActionDemote, ChatActionRemove:
|
||||
unmarshalTo = &cud.UserChange
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
@ -137,8 +138,8 @@ func (cud *ChatUpdateData) UnmarshalJSON(data []byte) error {
|
||||
return err
|
||||
}
|
||||
cud.NameChange.SetBy = strings.Replace(cud.NameChange.SetBy, OldUserSuffix, NewUserSuffix, 1)
|
||||
for index, jid := range cud.PermissionChange.JIDs {
|
||||
cud.PermissionChange.JIDs[index] = strings.Replace(jid, OldUserSuffix, NewUserSuffix, 1)
|
||||
for index, jid := range cud.UserChange.JIDs {
|
||||
cud.UserChange.JIDs[index] = strings.Replace(jid, OldUserSuffix, NewUserSuffix, 1)
|
||||
}
|
||||
for index, jid := range cud.Introduce.SuperAdmins {
|
||||
cud.Introduce.SuperAdmins[index] = strings.Replace(jid, OldUserSuffix, NewUserSuffix, 1)
|
||||
|
Loading…
Reference in New Issue
Block a user