Skip to content

Commit

Permalink
handlewhatsapp: add support for group info changes
Browse files Browse the repository at this point in the history
  • Loading branch information
tulir committed Sep 26, 2024
1 parent 38393fc commit d7ec1cc
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 1 deletion.
87 changes: 87 additions & 0 deletions pkg/connector/chatinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"go.mau.fi/util/ptr"
"go.mau.fi/whatsmeow"
"go.mau.fi/whatsmeow/types"
"go.mau.fi/whatsmeow/types/events"
"maunium.net/go/mautrix/bridgev2"
"maunium.net/go/mautrix/bridgev2/database"
"maunium.net/go/mautrix/bridgev2/networkid"
Expand Down Expand Up @@ -234,6 +235,92 @@ func (wa *WhatsAppClient) wrapGroupInfo(info *types.GroupInfo) *bridgev2.ChatInf
return wrapped
}

func (wa *WhatsAppClient) wrapGroupInfoChange(evt *events.GroupInfo) *bridgev2.ChatInfoChange {
var changes *bridgev2.ChatInfo
if evt.Name != nil || evt.Topic != nil || evt.Ephemeral != nil || evt.Unlink != nil || evt.Link != nil {
changes = &bridgev2.ChatInfo{}
if evt.Name != nil {
changes.Name = &evt.Name.Name
}
if evt.Topic != nil {
changes.Topic = &evt.Topic.Topic
}
if evt.Ephemeral != nil {
changes.Disappear = &database.DisappearingSetting{
Type: database.DisappearingTypeAfterRead,
Timer: time.Duration(evt.Ephemeral.DisappearingTimer) * time.Second,
}
if !evt.Ephemeral.IsEphemeral {
changes.Disappear = &database.DisappearingSetting{}
}
}
if evt.Unlink != nil {
// TODO ensure this doesn't race with link to a new group?
changes.ParentID = ptr.Ptr(networkid.PortalID(""))
}
if evt.Link != nil && evt.Link.Type == types.GroupLinkChangeTypeParent {
changes.ParentID = ptr.Ptr(waid.MakePortalID(evt.Link.Group.JID))
}
}
var memberChanges *bridgev2.ChatMemberList
if evt.Join != nil || evt.Leave != nil || evt.Promote != nil || evt.Demote != nil {
memberChanges = &bridgev2.ChatMemberList{
MemberMap: make(map[networkid.UserID]bridgev2.ChatMember),
}
for _, userID := range evt.Join {
memberChanges.MemberMap[waid.MakeUserID(userID)] = bridgev2.ChatMember{
EventSender: wa.makeEventSender(userID),
}
}
for _, userID := range evt.Promote {
memberChanges.MemberMap[waid.MakeUserID(userID)] = bridgev2.ChatMember{
EventSender: wa.makeEventSender(userID),
PowerLevel: ptr.Ptr(adminPL),
}
}
for _, userID := range evt.Demote {
memberChanges.MemberMap[waid.MakeUserID(userID)] = bridgev2.ChatMember{
EventSender: wa.makeEventSender(userID),
PowerLevel: ptr.Ptr(defaultPL),
}
}
for _, userID := range evt.Leave {
memberChanges.MemberMap[waid.MakeUserID(userID)] = bridgev2.ChatMember{
EventSender: wa.makeEventSender(userID),
Membership: event.MembershipLeave,
}
}
}
if evt.Announce != nil || evt.Locked != nil {
if memberChanges == nil {
memberChanges = &bridgev2.ChatMemberList{}
}
memberChanges.PowerLevels = &bridgev2.PowerLevelOverrides{}
if evt.Announce != nil {
if evt.Announce.IsAnnounce {
memberChanges.PowerLevels.EventsDefault = ptr.Ptr(adminPL)
} else {
memberChanges.PowerLevels.EventsDefault = ptr.Ptr(defaultPL)
}
}
if evt.Locked != nil {
metaChangePL := defaultPL
if evt.Locked.IsLocked {
metaChangePL = adminPL
}
memberChanges.PowerLevels.Events = map[event.Type]int{
event.StateRoomName: metaChangePL,
event.StateRoomAvatar: metaChangePL,
event.StateTopic: metaChangePL,
}
}
}
return &bridgev2.ChatInfoChange{
ChatInfo: changes,
MemberChanges: memberChanges,
}
}

func (wa *WhatsAppClient) makePortalAvatarFetcher(avatarID string, sender types.JID, ts time.Time) func(context.Context, *bridgev2.Portal) bool {
return func(ctx context.Context, portal *bridgev2.Portal) bool {
jid, _ := waid.ParsePortalID(portal.ID)
Expand Down
24 changes: 23 additions & 1 deletion pkg/connector/handlewhatsapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (wa *WhatsAppClient) handleWAEvent(rawEvt any) {
// TODO

case *events.GroupInfo:
// TODO
wa.handleWAGroupInfoChange(evt)
case *events.JoinedGroup:
// TODO
case *events.NewsletterJoin:
Expand Down Expand Up @@ -490,3 +490,25 @@ func (wa *WhatsAppClient) handleWAPictureUpdate(evt *events.Picture) {
})
}
}

func (wa *WhatsAppClient) handleWAGroupInfoChange(evt *events.GroupInfo) {
eventMeta := simplevent.EventMeta{
Type: bridgev2.RemoteEventChatInfoChange,
LogContext: nil,
PortalKey: wa.makeWAPortalKey(evt.JID),
CreatePortal: true,
Timestamp: evt.Timestamp,
}
if evt.Sender != nil {
eventMeta.Sender = wa.makeEventSender(*evt.Sender)
}
if evt.Delete != nil {
eventMeta.Type = bridgev2.RemoteEventChatDelete
wa.UserLogin.QueueRemoteEvent(&simplevent.ChatDelete{EventMeta: eventMeta})
} else {
wa.UserLogin.QueueRemoteEvent(&simplevent.ChatInfoChange{
EventMeta: eventMeta,
ChatInfoChange: wa.wrapGroupInfoChange(evt),
})
}
}

0 comments on commit d7ec1cc

Please sign in to comment.