Add better support for broadcast lists

This commit is contained in:
Tulir Asokan 2021-02-21 14:18:15 +02:00
parent fcad5fb057
commit a911a0c1a9
5 changed files with 54 additions and 17 deletions

View file

@ -40,7 +40,7 @@ func GroupPortalKey(jid whatsapp.JID) PortalKey {
} }
func NewPortalKey(jid, receiver whatsapp.JID) PortalKey { func NewPortalKey(jid, receiver whatsapp.JID) PortalKey {
if strings.HasSuffix(jid, "@g.us") { if strings.HasSuffix(jid, whatsapp.GroupSuffix) {
receiver = jid receiver = jid
} }
return PortalKey{ return PortalKey{

2
go.mod
View file

@ -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.20210221000549-ec31478c7b94 replace github.com/Rhymen/go-whatsapp => github.com/tulir/go-whatsapp v0.3.22-0.20210221121735-6d3eaaa7bdc5

2
go.sum
View file

@ -335,6 +335,8 @@ github.com/tulir/go-whatsapp v0.3.22-0.20210218211744-b9f35ff6257a h1:8JSW6oIAgI
github.com/tulir/go-whatsapp v0.3.22-0.20210218211744-b9f35ff6257a/go.mod h1:rwwuTh1bKqhgrRvOBAr8hDqtuz8Cc1Quqw/0BeXb+/E= github.com/tulir/go-whatsapp v0.3.22-0.20210218211744-b9f35ff6257a/go.mod h1:rwwuTh1bKqhgrRvOBAr8hDqtuz8Cc1Quqw/0BeXb+/E=
github.com/tulir/go-whatsapp v0.3.22-0.20210221000549-ec31478c7b94 h1:G4YvxLMW80U7xhcRXHZANZ6N9xnIGBNp6wlqzuSqtw4= github.com/tulir/go-whatsapp v0.3.22-0.20210221000549-ec31478c7b94 h1:G4YvxLMW80U7xhcRXHZANZ6N9xnIGBNp6wlqzuSqtw4=
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/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=

View file

@ -55,6 +55,11 @@ import (
"maunium.net/go/mautrix-whatsapp/database" "maunium.net/go/mautrix-whatsapp/database"
) )
const StatusBroadcastTopic = "WhatsApp status updates from your contacts"
const StatusBroadcastName = "WhatsApp Status Broadcast"
const BroadcastTopic = "WhatsApp broadcast list"
const UnnamedBroadcastName = "Unnamed broadcast list"
func (bridge *Bridge) GetPortalByMXID(mxid id.RoomID) *Portal { func (bridge *Bridge) GetPortalByMXID(mxid id.RoomID) *Portal {
bridge.portalsLock.Lock() bridge.portalsLock.Lock()
defer bridge.portalsLock.Unlock() defer bridge.portalsLock.Unlock()
@ -180,6 +185,7 @@ type Portal struct {
messages chan PortalMessage messages chan PortalMessage
isPrivate *bool isPrivate *bool
isBroadcast *bool
hasRelaybot *bool hasRelaybot *bool
} }
@ -463,6 +469,9 @@ 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() {
name = UnnamedBroadcastName
}
if portal.Name != name { if portal.Name != name {
portal.log.Debugfln("Updating name %s -> %s", portal.Name, name) portal.log.Debugfln("Updating name %s -> %s", portal.Name, name)
portal.Name = name portal.Name = name
@ -515,8 +524,14 @@ func (portal *Portal) UpdateMetadata(user *User) bool {
return false return false
} else if portal.IsStatusBroadcastRoom() { } else if portal.IsStatusBroadcastRoom() {
update := false update := false
update = portal.UpdateName("WhatsApp Status Broadcast", "", nil, false) || update update = portal.UpdateName(StatusBroadcastName, "", nil, false) || update
update = portal.UpdateTopic("WhatsApp status updates from your contacts", "", nil, false) || update update = portal.UpdateTopic(StatusBroadcastTopic, "", nil, false) || update
return update
} else if portal.IsBroadcastRoom() {
update := false
contact, _ := user.Conn.Store.Contacts[portal.Key.JID]
update = portal.UpdateName(contact.Name, "", nil, false) || update
update = portal.UpdateTopic(BroadcastTopic, "", nil, false) || update
return update return update
} }
metadata, err := user.Conn.GetGroupMetaData(portal.Key.JID) metadata, err := user.Conn.GetGroupMetaData(portal.Key.JID)
@ -595,13 +610,9 @@ func (portal *Portal) Sync(user *User, contact whatsapp.Contact) {
portal.ensureUserInvited(user) portal.ensureUserInvited(user)
} }
if portal.IsPrivateChat() {
return
}
update := false update := false
update = portal.UpdateMetadata(user) || update update = portal.UpdateMetadata(user) || update
if !portal.IsStatusBroadcastRoom() && portal.Avatar == "" { if !portal.IsPrivateChat() && !portal.IsBroadcastRoom() && portal.Avatar == "" {
update = portal.UpdateAvatar(user, nil, false) || update update = portal.UpdateAvatar(user, nil, false) || update
} }
if update { if update {
@ -990,6 +1001,14 @@ func (portal *Portal) CreateMatrixRoom(user *User) error {
} else if portal.IsStatusBroadcastRoom() { } else if portal.IsStatusBroadcastRoom() {
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() {
contact, ok := user.Conn.Store.Contacts[portal.Key.JID]
if ok {
portal.Name = contact.Name
} else {
portal.Name = UnnamedBroadcastName
}
portal.Topic = BroadcastTopic
} else { } else {
var err error var err error
metadata, err = user.Conn.GetGroupMetaData(portal.Key.JID) metadata, err = user.Conn.GetGroupMetaData(portal.Key.JID)
@ -1107,6 +1126,18 @@ func (portal *Portal) IsPrivateChat() bool {
return *portal.isPrivate return *portal.isPrivate
} }
func (portal *Portal) IsBroadcastRoom() bool {
if portal.isBroadcast == nil {
val := strings.HasSuffix(portal.Key.JID, whatsapp.BroadcastSuffix)
portal.isBroadcast = &val
}
return *portal.isBroadcast
}
func (portal *Portal) IsStatusBroadcastRoom() bool {
return portal.Key.JID == "status@broadcast"
}
func (portal *Portal) HasRelaybot() bool { func (portal *Portal) HasRelaybot() bool {
if portal.bridge.Relaybot == nil { if portal.bridge.Relaybot == nil {
return false return false
@ -1117,10 +1148,6 @@ func (portal *Portal) HasRelaybot() bool {
return *portal.hasRelaybot return *portal.hasRelaybot
} }
func (portal *Portal) IsStatusBroadcastRoom() bool {
return portal.Key.JID == "status@broadcast"
}
func (portal *Portal) MainIntent() *appservice.IntentAPI { func (portal *Portal) MainIntent() *appservice.IntentAPI {
if portal.IsPrivateChat() { if portal.IsPrivateChat() {
return portal.bridge.GetPuppetByJID(portal.Key.JID).DefaultIntent() return portal.bridge.GetPuppetByJID(portal.Key.JID).DefaultIntent()

16
user.go
View file

@ -779,14 +779,14 @@ func (user *User) UpdateDirectChats(chats map[id.UserID][]id.RoomID) {
} }
func (user *User) HandleContactList(contacts []whatsapp.Contact) { func (user *User) HandleContactList(contacts []whatsapp.Contact) {
contactMap := make(map[string]whatsapp.Contact) contactMap := make(map[whatsapp.JID]whatsapp.Contact)
for _, contact := range contacts { for _, contact := range contacts {
contactMap[contact.JID] = contact contactMap[contact.JID] = contact
} }
go user.syncPuppets(contactMap) go user.syncPuppets(contactMap)
} }
func (user *User) syncPuppets(contacts map[string]whatsapp.Contact) { func (user *User) syncPuppets(contacts map[whatsapp.JID]whatsapp.Contact) {
if contacts == nil { if contacts == nil {
contacts = user.Conn.Store.Contacts contacts = user.Conn.Store.Contacts
} }
@ -805,6 +805,9 @@ func (user *User) syncPuppets(contacts map[string]whatsapp.Contact) {
if strings.HasSuffix(jid, whatsapp.NewUserSuffix) { if strings.HasSuffix(jid, whatsapp.NewUserSuffix) {
puppet := user.bridge.GetPuppetByJID(contact.JID) puppet := user.bridge.GetPuppetByJID(contact.JID)
puppet.Sync(user, contact) puppet.Sync(user, contact)
} else if strings.HasSuffix(jid, whatsapp.BroadcastSuffix) {
portal := user.GetPortalByJID(contact.JID)
portal.Sync(user, contact)
} }
} }
user.log.Infoln("Finished syncing puppet info from contacts") user.log.Infoln("Finished syncing puppet info from contacts")
@ -960,8 +963,13 @@ func (user *User) HandleNewContact(contact whatsapp.Contact) {
if strings.HasSuffix(contact.JID, whatsapp.OldUserSuffix) { if strings.HasSuffix(contact.JID, whatsapp.OldUserSuffix) {
contact.JID = strings.Replace(contact.JID, whatsapp.OldUserSuffix, whatsapp.NewUserSuffix, -1) contact.JID = strings.Replace(contact.JID, whatsapp.OldUserSuffix, whatsapp.NewUserSuffix, -1)
} }
puppet := user.bridge.GetPuppetByJID(contact.JID) if strings.HasSuffix(contact.JID, whatsapp.NewUserSuffix) {
puppet.UpdateName(user, contact) puppet := user.bridge.GetPuppetByJID(contact.JID)
puppet.UpdateName(user, contact)
} else if strings.HasSuffix(contact.JID, whatsapp.BroadcastSuffix) {
portal := user.GetPortalByJID(contact.JID)
portal.UpdateName(contact.Name, "", nil, true)
}
} }
func (user *User) HandleBatteryMessage(battery whatsapp.BatteryMessage) { func (user *User) HandleBatteryMessage(battery whatsapp.BatteryMessage) {