forked from MirrorHub/mautrix-whatsapp
Sync broadcast list recipients too
This commit is contained in:
parent
a911a0c1a9
commit
ac2ca08007
4 changed files with 75 additions and 43 deletions
|
@ -164,7 +164,7 @@ func (puppet *Puppet) ProcessResponse(resp *mautrix.RespSync, _ string) error {
|
||||||
}
|
}
|
||||||
for roomID, events := range resp.Rooms.Join {
|
for roomID, events := range resp.Rooms.Join {
|
||||||
portal := puppet.bridge.GetPortalByMXID(roomID)
|
portal := puppet.bridge.GetPortalByMXID(roomID)
|
||||||
if portal == nil {
|
if portal == nil || portal.IsBroadcastList() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, evt := range events.Ephemeral.Events {
|
for _, evt := range events.Ephemeral.Events {
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -16,4 +16,4 @@ require (
|
||||||
maunium.net/go/mautrix v0.8.3
|
maunium.net/go/mautrix v0.8.3
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/Rhymen/go-whatsapp => github.com/tulir/go-whatsapp v0.3.22-0.20210221121735-6d3eaaa7bdc5
|
replace github.com/Rhymen/go-whatsapp => github.com/tulir/go-whatsapp v0.3.22-0.20210221124355-8c89650e6a9e
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -337,6 +337,8 @@ github.com/tulir/go-whatsapp v0.3.22-0.20210221000549-ec31478c7b94 h1:G4YvxLMW80
|
||||||
github.com/tulir/go-whatsapp v0.3.22-0.20210221000549-ec31478c7b94/go.mod h1:rwwuTh1bKqhgrRvOBAr8hDqtuz8Cc1Quqw/0BeXb+/E=
|
github.com/tulir/go-whatsapp v0.3.22-0.20210221000549-ec31478c7b94/go.mod h1:rwwuTh1bKqhgrRvOBAr8hDqtuz8Cc1Quqw/0BeXb+/E=
|
||||||
github.com/tulir/go-whatsapp v0.3.22-0.20210221121735-6d3eaaa7bdc5 h1:4Y5xQdpuLEt4DQavhnP/Ium1zpwIE+LeOFwVyiW4qoY=
|
github.com/tulir/go-whatsapp v0.3.22-0.20210221121735-6d3eaaa7bdc5 h1:4Y5xQdpuLEt4DQavhnP/Ium1zpwIE+LeOFwVyiW4qoY=
|
||||||
github.com/tulir/go-whatsapp v0.3.22-0.20210221121735-6d3eaaa7bdc5/go.mod h1:rwwuTh1bKqhgrRvOBAr8hDqtuz8Cc1Quqw/0BeXb+/E=
|
github.com/tulir/go-whatsapp v0.3.22-0.20210221121735-6d3eaaa7bdc5/go.mod h1:rwwuTh1bKqhgrRvOBAr8hDqtuz8Cc1Quqw/0BeXb+/E=
|
||||||
|
github.com/tulir/go-whatsapp v0.3.22-0.20210221124355-8c89650e6a9e h1:jQGaSyVl7gx44KYH1UY9JnhoLAqTEKysIhLjQJZZKVY=
|
||||||
|
github.com/tulir/go-whatsapp v0.3.22-0.20210221124355-8c89650e6a9e/go.mod h1:rwwuTh1bKqhgrRvOBAr8hDqtuz8Cc1Quqw/0BeXb+/E=
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
|
|
112
portal.go
112
portal.go
|
@ -359,6 +359,43 @@ func (portal *Portal) finishHandling(source *User, message *waProto.WebMessageIn
|
||||||
portal.log.Debugln("Handled message", message.GetKey().GetId(), "->", mxid)
|
portal.log.Debugln("Handled message", message.GetKey().GetId(), "->", mxid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (portal *Portal) kickExtraUsers(participantMap map[whatsapp.JID]bool) {
|
||||||
|
members, err := portal.MainIntent().JoinedMembers(portal.MXID)
|
||||||
|
if err != nil {
|
||||||
|
portal.log.Warnln("Failed to get member list:", err)
|
||||||
|
} else {
|
||||||
|
for member := range members.Joined {
|
||||||
|
jid, ok := portal.bridge.ParsePuppetMXID(member)
|
||||||
|
if ok {
|
||||||
|
_, shouldBePresent := participantMap[jid]
|
||||||
|
if !shouldBePresent {
|
||||||
|
_, err := portal.MainIntent().KickUser(portal.MXID, &mautrix.ReqKickUser{
|
||||||
|
UserID: member,
|
||||||
|
Reason: "User had left this WhatsApp chat",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
portal.log.Warnfln("Failed to kick user %s who had left: %v", member, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (portal *Portal) SyncBroadcastRecipients(metadata *whatsapp.BroadcastListInfo) {
|
||||||
|
participantMap := make(map[whatsapp.JID]bool)
|
||||||
|
for _, recipient := range metadata.Recipients {
|
||||||
|
participantMap[recipient.JID] = true
|
||||||
|
|
||||||
|
puppet := portal.bridge.GetPuppetByJID(recipient.JID)
|
||||||
|
err := puppet.DefaultIntent().EnsureJoined(portal.MXID)
|
||||||
|
if err != nil {
|
||||||
|
portal.log.Warnfln("Failed to make puppet of %s join %s: %v", recipient.JID, portal.MXID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portal.kickExtraUsers(participantMap)
|
||||||
|
}
|
||||||
|
|
||||||
func (portal *Portal) SyncParticipants(metadata *whatsapp.GroupInfo) {
|
func (portal *Portal) SyncParticipants(metadata *whatsapp.GroupInfo) {
|
||||||
changed := false
|
changed := false
|
||||||
levels, err := portal.MainIntent().PowerLevels(portal.MXID)
|
levels, err := portal.MainIntent().PowerLevels(portal.MXID)
|
||||||
|
@ -366,7 +403,7 @@ func (portal *Portal) SyncParticipants(metadata *whatsapp.GroupInfo) {
|
||||||
levels = portal.GetBasePowerLevels()
|
levels = portal.GetBasePowerLevels()
|
||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
participantMap := make(map[string]bool)
|
participantMap := make(map[whatsapp.JID]bool)
|
||||||
for _, participant := range metadata.Participants {
|
for _, participant := range metadata.Participants {
|
||||||
participantMap[participant.JID] = true
|
participantMap[participant.JID] = true
|
||||||
user := portal.bridge.GetUserByJID(participant.JID)
|
user := portal.bridge.GetUserByJID(participant.JID)
|
||||||
|
@ -395,26 +432,7 @@ func (portal *Portal) SyncParticipants(metadata *whatsapp.GroupInfo) {
|
||||||
portal.log.Errorln("Failed to change power levels:", err)
|
portal.log.Errorln("Failed to change power levels:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
members, err := portal.MainIntent().JoinedMembers(portal.MXID)
|
portal.kickExtraUsers(participantMap)
|
||||||
if err != nil {
|
|
||||||
portal.log.Warnln("Failed to get member list:", err)
|
|
||||||
} else {
|
|
||||||
for member := range members.Joined {
|
|
||||||
jid, ok := portal.bridge.ParsePuppetMXID(member)
|
|
||||||
if ok {
|
|
||||||
_, shouldBePresent := participantMap[jid]
|
|
||||||
if !shouldBePresent {
|
|
||||||
_, err := portal.MainIntent().KickUser(portal.MXID, &mautrix.ReqKickUser{
|
|
||||||
UserID: member,
|
|
||||||
Reason: "User had left this WhatsApp chat",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
portal.log.Warnfln("Failed to kick user %s who had left: %v", member, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (portal *Portal) UpdateAvatar(user *User, avatar *whatsapp.ProfilePicInfo, updateInfo bool) bool {
|
func (portal *Portal) UpdateAvatar(user *User, avatar *whatsapp.ProfilePicInfo, updateInfo bool) bool {
|
||||||
|
@ -469,7 +487,7 @@ func (portal *Portal) UpdateAvatar(user *User, avatar *whatsapp.ProfilePicInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (portal *Portal) UpdateName(name string, setBy whatsapp.JID, intent *appservice.IntentAPI, updateInfo bool) bool {
|
func (portal *Portal) UpdateName(name string, setBy whatsapp.JID, intent *appservice.IntentAPI, updateInfo bool) bool {
|
||||||
if name == "" && portal.IsBroadcastRoom() {
|
if name == "" && portal.IsBroadcastList() {
|
||||||
name = UnnamedBroadcastName
|
name = UnnamedBroadcastName
|
||||||
}
|
}
|
||||||
if portal.Name != name {
|
if portal.Name != name {
|
||||||
|
@ -522,12 +540,12 @@ func (portal *Portal) UpdateTopic(topic string, setBy whatsapp.JID, intent *apps
|
||||||
func (portal *Portal) UpdateMetadata(user *User) bool {
|
func (portal *Portal) UpdateMetadata(user *User) bool {
|
||||||
if portal.IsPrivateChat() {
|
if portal.IsPrivateChat() {
|
||||||
return false
|
return false
|
||||||
} else if portal.IsStatusBroadcastRoom() {
|
} else if portal.IsStatusBroadcastList() {
|
||||||
update := false
|
update := false
|
||||||
update = portal.UpdateName(StatusBroadcastName, "", nil, false) || update
|
update = portal.UpdateName(StatusBroadcastName, "", nil, false) || update
|
||||||
update = portal.UpdateTopic(StatusBroadcastTopic, "", nil, false) || update
|
update = portal.UpdateTopic(StatusBroadcastTopic, "", nil, false) || update
|
||||||
return update
|
return update
|
||||||
} else if portal.IsBroadcastRoom() {
|
} else if portal.IsBroadcastList() {
|
||||||
update := false
|
update := false
|
||||||
contact, _ := user.Conn.Store.Contacts[portal.Key.JID]
|
contact, _ := user.Conn.Store.Contacts[portal.Key.JID]
|
||||||
update = portal.UpdateName(contact.Name, "", nil, false) || update
|
update = portal.UpdateName(contact.Name, "", nil, false) || update
|
||||||
|
@ -612,7 +630,7 @@ func (portal *Portal) Sync(user *User, contact whatsapp.Contact) {
|
||||||
|
|
||||||
update := false
|
update := false
|
||||||
update = portal.UpdateMetadata(user) || update
|
update = portal.UpdateMetadata(user) || update
|
||||||
if !portal.IsPrivateChat() && !portal.IsBroadcastRoom() && portal.Avatar == "" {
|
if !portal.IsPrivateChat() && !portal.IsBroadcastList() && portal.Avatar == "" {
|
||||||
update = portal.UpdateAvatar(user, nil, false) || update
|
update = portal.UpdateAvatar(user, nil, false) || update
|
||||||
}
|
}
|
||||||
if update {
|
if update {
|
||||||
|
@ -988,6 +1006,7 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
|
||||||
portal.log.Infoln("Creating Matrix room. Info source:", user.MXID)
|
portal.log.Infoln("Creating Matrix room. Info source:", user.MXID)
|
||||||
|
|
||||||
var metadata *whatsapp.GroupInfo
|
var metadata *whatsapp.GroupInfo
|
||||||
|
var broadcastMetadata *whatsapp.BroadcastListInfo
|
||||||
if portal.IsPrivateChat() {
|
if portal.IsPrivateChat() {
|
||||||
puppet := portal.bridge.GetPuppetByJID(portal.Key.JID)
|
puppet := portal.bridge.GetPuppetByJID(portal.Key.JID)
|
||||||
if portal.bridge.Config.Bridge.PrivateChatPortalMeta {
|
if portal.bridge.Config.Bridge.PrivateChatPortalMeta {
|
||||||
|
@ -998,14 +1017,19 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
|
||||||
portal.Name = ""
|
portal.Name = ""
|
||||||
}
|
}
|
||||||
portal.Topic = "WhatsApp private chat"
|
portal.Topic = "WhatsApp private chat"
|
||||||
} else if portal.IsStatusBroadcastRoom() {
|
} else if portal.IsStatusBroadcastList() {
|
||||||
portal.Name = "WhatsApp Status Broadcast"
|
portal.Name = "WhatsApp Status Broadcast"
|
||||||
portal.Topic = "WhatsApp status updates from your contacts"
|
portal.Topic = "WhatsApp status updates from your contacts"
|
||||||
} else if portal.IsBroadcastRoom() {
|
} else if portal.IsBroadcastList() {
|
||||||
contact, ok := user.Conn.Store.Contacts[portal.Key.JID]
|
var err error
|
||||||
if ok {
|
broadcastMetadata, err = user.Conn.GetBroadcastMetadata(portal.Key.JID)
|
||||||
portal.Name = contact.Name
|
if err == nil && broadcastMetadata.Status == 0 {
|
||||||
|
portal.Name = broadcastMetadata.Name
|
||||||
} else {
|
} else {
|
||||||
|
contact, _ := user.Conn.Store.Contacts[portal.Key.JID]
|
||||||
|
portal.Name = contact.Name
|
||||||
|
}
|
||||||
|
if len(portal.Name) == 0 {
|
||||||
portal.Name = UnnamedBroadcastName
|
portal.Name = UnnamedBroadcastName
|
||||||
}
|
}
|
||||||
portal.Topic = BroadcastTopic
|
portal.Topic = BroadcastTopic
|
||||||
|
@ -1097,6 +1121,9 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
|
||||||
_ = customPuppet.CustomIntent().EnsureJoined(portal.MXID)
|
_ = customPuppet.CustomIntent().EnsureJoined(portal.MXID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if broadcastMetadata != nil {
|
||||||
|
portal.SyncBroadcastRecipients(broadcastMetadata)
|
||||||
|
}
|
||||||
user.addPortalToCommunity(portal)
|
user.addPortalToCommunity(portal)
|
||||||
if portal.IsPrivateChat() {
|
if portal.IsPrivateChat() {
|
||||||
puppet := user.bridge.GetPuppetByJID(portal.Key.JID)
|
puppet := user.bridge.GetPuppetByJID(portal.Key.JID)
|
||||||
|
@ -1126,7 +1153,7 @@ func (portal *Portal) IsPrivateChat() bool {
|
||||||
return *portal.isPrivate
|
return *portal.isPrivate
|
||||||
}
|
}
|
||||||
|
|
||||||
func (portal *Portal) IsBroadcastRoom() bool {
|
func (portal *Portal) IsBroadcastList() bool {
|
||||||
if portal.isBroadcast == nil {
|
if portal.isBroadcast == nil {
|
||||||
val := strings.HasSuffix(portal.Key.JID, whatsapp.BroadcastSuffix)
|
val := strings.HasSuffix(portal.Key.JID, whatsapp.BroadcastSuffix)
|
||||||
portal.isBroadcast = &val
|
portal.isBroadcast = &val
|
||||||
|
@ -1134,7 +1161,7 @@ func (portal *Portal) IsBroadcastRoom() bool {
|
||||||
return *portal.isBroadcast
|
return *portal.isBroadcast
|
||||||
}
|
}
|
||||||
|
|
||||||
func (portal *Portal) IsStatusBroadcastRoom() bool {
|
func (portal *Portal) IsStatusBroadcastList() bool {
|
||||||
return portal.Key.JID == "status@broadcast"
|
return portal.Key.JID == "status@broadcast"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1310,8 +1337,9 @@ func (portal *Portal) HandleTextMessage(source *User, message whatsapp.TextMessa
|
||||||
}
|
}
|
||||||
|
|
||||||
func (portal *Portal) HandleStubMessage(source *User, message whatsapp.StubMessage, isBackfill bool) {
|
func (portal *Portal) HandleStubMessage(source *User, message whatsapp.StubMessage, isBackfill bool) {
|
||||||
if portal.bridge.Config.Bridge.ChatMetaSync {
|
if portal.bridge.Config.Bridge.ChatMetaSync && (!portal.IsBroadcastList() || isBackfill) {
|
||||||
// Chat meta sync is enabled, so we use chat update commands and full-syncs instead of message history
|
// Chat meta sync is enabled, so we use chat update commands and full-syncs instead of message history
|
||||||
|
// However, broadcast lists don't have update commands, so we handle these if it's not a backfill
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
intent := portal.startHandling(source, message.Info)
|
intent := portal.startHandling(source, message.Info)
|
||||||
|
@ -1341,9 +1369,9 @@ func (portal *Portal) HandleStubMessage(source *User, message whatsapp.StubMessa
|
||||||
eventID = portal.RestrictMessageSending(message.FirstParam == "on")
|
eventID = portal.RestrictMessageSending(message.FirstParam == "on")
|
||||||
case waProto.WebMessageInfo_GROUP_CHANGE_RESTRICT:
|
case waProto.WebMessageInfo_GROUP_CHANGE_RESTRICT:
|
||||||
eventID = portal.RestrictMetadataChanges(message.FirstParam == "on")
|
eventID = portal.RestrictMetadataChanges(message.FirstParam == "on")
|
||||||
case waProto.WebMessageInfo_GROUP_PARTICIPANT_ADD, waProto.WebMessageInfo_GROUP_PARTICIPANT_INVITE:
|
case waProto.WebMessageInfo_GROUP_PARTICIPANT_ADD, waProto.WebMessageInfo_GROUP_PARTICIPANT_INVITE, waProto.WebMessageInfo_BROADCAST_ADD:
|
||||||
portal.HandleWhatsAppInvite(senderJID, intent, message.Params)
|
portal.HandleWhatsAppInvite(senderJID, intent, message.Params)
|
||||||
case waProto.WebMessageInfo_GROUP_PARTICIPANT_REMOVE, waProto.WebMessageInfo_GROUP_PARTICIPANT_LEAVE:
|
case waProto.WebMessageInfo_GROUP_PARTICIPANT_REMOVE, waProto.WebMessageInfo_GROUP_PARTICIPANT_LEAVE, waProto.WebMessageInfo_BROADCAST_REMOVE:
|
||||||
portal.HandleWhatsAppKick(source, senderJID, message.Params)
|
portal.HandleWhatsAppKick(source, senderJID, message.Params)
|
||||||
case waProto.WebMessageInfo_GROUP_PARTICIPANT_PROMOTE:
|
case waProto.WebMessageInfo_GROUP_PARTICIPANT_PROMOTE:
|
||||||
eventID = portal.ChangeAdminStatus(message.Params, true)
|
eventID = portal.ChangeAdminStatus(message.Params, true)
|
||||||
|
@ -1525,13 +1553,15 @@ func (portal *Portal) HandleWhatsAppKick(source *User, senderJID string, jids []
|
||||||
puppet := portal.bridge.GetPuppetByJID(jid)
|
puppet := portal.bridge.GetPuppetByJID(jid)
|
||||||
portal.removeUser(puppet.JID == sender.JID, senderIntent, puppet.MXID, puppet.DefaultIntent())
|
portal.removeUser(puppet.JID == sender.JID, senderIntent, puppet.MXID, puppet.DefaultIntent())
|
||||||
|
|
||||||
user := portal.bridge.GetUserByJID(jid)
|
if !portal.IsBroadcastList() {
|
||||||
if user != nil {
|
user := portal.bridge.GetUserByJID(jid)
|
||||||
var customIntent *appservice.IntentAPI
|
if user != nil {
|
||||||
if puppet.CustomMXID == user.MXID {
|
var customIntent *appservice.IntentAPI
|
||||||
customIntent = puppet.CustomIntent()
|
if puppet.CustomMXID == user.MXID {
|
||||||
|
customIntent = puppet.CustomIntent()
|
||||||
|
}
|
||||||
|
portal.removeUser(puppet.JID == sender.JID, senderIntent, user.MXID, customIntent)
|
||||||
}
|
}
|
||||||
portal.removeUser(puppet.JID == sender.JID, senderIntent, user.MXID, customIntent)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue