1
0
Fork 0

feat: group creation and affiliation changes

This commit is contained in:
nicoco 2024-02-17 14:51:10 +01:00
parent 4c88f75a88
commit e3c36becdc
3 changed files with 81 additions and 2 deletions

View File

@ -3,7 +3,7 @@ from datetime import datetime, timezone
from typing import TYPE_CHECKING, Optional
from slidge.group import LegacyBookmarks, LegacyMUC, LegacyParticipant, MucType
from slidge.util.types import Mention
from slidge.util.types import Mention, MucAffiliation
from slixmpp.exceptions import XMPPError
from .generated import whatsapp
@ -88,13 +88,15 @@ class MUC(LegacyMUC[str, str, Participant, str]):
if data.Action == whatsapp.GroupParticipantActionRemove:
self.remove_participant(participant)
else:
participant.affiliation = "member"
if data.Affiliation == whatsapp.GroupAffiliationAdmin:
participant.affiliation = "admin"
participant.role = "moderator"
elif data.Affiliation == whatsapp.GroupAffiliationOwner:
participant.affiliation = "owner"
participant.role = "moderator"
else:
participant.affiliation = "member"
participant.role = "participant"
def replace_mentions(self, t: str):
return replace_whatsapp_mentions(
@ -128,6 +130,29 @@ class MUC(LegacyMUC[str, str, Participant, str]):
if self.subject != subject:
self.session.whatsapp.SetGroupTopic(self.legacy_id, subject)
async def on_set_affiliation(
self,
contact: "Contact", # type:ignore
affiliation: MucAffiliation,
reason: Optional[str],
nickname: Optional[str],
):
if affiliation == "member":
if contact in self._participants_by_contacts:
change = "demote"
else:
change = "add"
elif affiliation == "admin":
change = "promote"
elif affiliation == "outcast" or affiliation == "none":
change = "remove"
else:
raise XMPPError(
"bad-request",
f"You can't make a participant '{affiliation}' in whatsapp",
)
self.session.whatsapp.SetAffiliation(self.legacy_id, contact.legacy_id, change)
class Bookmarks(LegacyBookmarks[str, MUC]):
session: "Session"

View File

@ -453,6 +453,32 @@ func (s *Session) GetGroups() ([]Group, error) {
return groups, nil
}
// CreateGroup attempts to create a new WhatsApp group for the given human-readable name and
// participant JIDs given.
func (s *Session) CreateGroup(name string, participants []string) (Group, error) {
if s.client == nil || s.client.Store.ID == nil {
return Group{}, fmt.Errorf("Cannot create group for unauthenticated session")
}
var jids []types.JID
for _, p := range participants {
jid, err := types.ParseJID(p)
if err != nil {
return Group{}, fmt.Errorf("Could not parse participant JID: %s", err)
}
jids = append(jids, jid)
}
req := whatsmeow.ReqCreateGroup{Name: name, Participants: jids}
info, err := s.client.CreateGroup(req)
if err != nil {
return Group{}, fmt.Errorf("Could not create group: %s", err)
}
return newGroup(s.client, info), nil
}
// GetAvatar fetches a profile picture for the Contact or Group JID given. If a non-empty `avatarID`
// is also given, GetAvatar will return an empty [Avatar] instance with no error if the remote state
// for the given ID has not changed.
@ -543,6 +569,23 @@ func (s *Session) SetGroupTopic(resourceID, topic string) error {
return s.client.SetGroupTopic(jid, "", "", topic)
}
func (s *Session) SetAffiliation(groupID, participantID string, change whatsmeow.ParticipantChange) ([]types.GroupParticipant, error) {
if s.client == nil || s.client.Store.ID == nil {
return make([]types.GroupParticipant, 0), fmt.Errorf("Cannot set affiliation for unauthenticated session")
}
groupJID, err := types.ParseJID(groupID)
if err != nil {
return make([]types.GroupParticipant, 0), fmt.Errorf("Could not parse JID for affiliation change: %s", err)
}
participantJID, err := types.ParseJID(participantID)
if err != nil {
return make([]types.GroupParticipant, 0), fmt.Errorf("Could not parse JID for affiliation change: %s", err)
}
return s.client.UpdateGroupParticipants(groupJID, []types.JID{participantJID}, change)
}
// FindContact attempts to check for a registered contact on WhatsApp corresponding to the given
// phone number, returning a concrete instance if found; typically, only the contact JID is set. No
// error is returned if no contact was found, but any unexpected errors will otherwise be returned

View File

@ -443,6 +443,17 @@ class Session(BaseSession[str, Recipient]):
"""
self.whatsapp.SetAvatar("", await get_bytes_temp(bytes_) if bytes_ else "")
async def on_create_group(
self, name: str, contacts: list[Contact] # type:ignore
):
"""
Creates a WhatsApp group for the given human-readable name and participant list.
"""
group = self.whatsapp.CreateGroup(
name, go.Slice_string([c.legacy_id for c in contacts])
)
return await self.bookmarks.legacy_id_to_jid_local_part(group.JID)
async def on_search(self, form_values: dict[str, str]):
"""
Searches for, and automatically adds, WhatsApp contact based on phone number. Phone numbers