feat: group creation and affiliation changes
This commit is contained in:
parent
4c88f75a88
commit
e3c36becdc
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue