Group chat parameters & functionality

Two new fields, group_id and group_name, optional and may be none. Functionality extended to demo.py with the "group" command
This commit is contained in:
JustAHippo 2023-12-05 17:24:33 -05:00
parent ceeb9160ed
commit e073dae22f
2 changed files with 20 additions and 4 deletions

View file

@ -1,5 +1,6 @@
import json import json
import logging import logging
import uuid
from base64 import b64decode, b64encode from base64 import b64decode, b64encode
from subprocess import PIPE, Popen from subprocess import PIPE, Popen
@ -106,6 +107,7 @@ async def main():
async def input_task(im: imessage.iMessageUser): async def input_task(im: imessage.iMessageUser):
current_effect: str | None = None current_effect: str | None = None
current_participants: list[str] = [] current_participants: list[str] = []
current_group_id: uuid.UUID | None = None
def is_cmd(cmd_str: str, name: str) -> bool: def is_cmd(cmd_str: str, name: str) -> bool:
return cmd_str in [name, name[0]] or cmd_str.startswith(f"{name} ") or cmd_str.startswith(f"{name[0]} ") return cmd_str in [name, name[0]] or cmd_str.startswith(f"{name} ") or cmd_str.startswith(f"{name[0]} ")
@ -159,6 +161,11 @@ async def input_task(im: imessage.iMessageUser):
fixed_participants: list[str] = list(map(fixup_handle, participants)) fixed_participants: list[str] = list(map(fixup_handle, participants))
print(f"Filtering to {fixed_participants}") print(f"Filtering to {fixed_participants}")
current_participants = fixed_participants current_participants = fixed_participants
elif is_cmd(cmd, "group"):
if (group_id := get_parameters(cmd, "group [recipients]")) is not None:
print(group_id)
current_group_id: uuid.UUID = uuid.UUID(group_id[0])
print(f"Group ID is {group_id}")
elif is_cmd(cmd, "handle"): elif is_cmd(cmd, "handle"):
handles: list[str] = im.user.handles handles: list[str] = im.user.handles
av_handles: str = "\n".join([f"\t{h}{' (current)' if h == im.user.current_handle else ''}" for h in handles]) av_handles: str = "\n".join([f"\t{h}{' (current)' if h == im.user.current_handle else ''}" for h in handles])
@ -185,7 +192,7 @@ async def input_task(im: imessage.iMessageUser):
if cmd.startswith("\\"): if cmd.startswith("\\"):
cmd = cmd[1:] cmd = cmd[1:]
await im.send(imessage.iMessage.create(im, cmd, current_participants, current_effect)) await im.send(imessage.iMessage.create(im, cmd, current_participants, current_effect, current_group_id))
current_effect = None current_effect = None
else: else:
print("No chat selected") print("No chat selected")

View file

@ -143,6 +143,10 @@ class Message:
"""Internal property representing whether the message should be compressed""" """Internal property representing whether the message should be compressed"""
xml: str | None = None xml: str | None = None
"""XML portion of message, may be None""" """XML portion of message, may be None"""
group_name: str | None = None
"""iMessage group chat name, may be None"""
group_id: int | None = None
"""The ID of the iMessage group chat, may be None"""
@staticmethod @staticmethod
def from_raw(message: bytes, sender: str | None = None) -> "Message": def from_raw(message: bytes, sender: str | None = None) -> "Message":
@ -273,7 +277,7 @@ class iMessage(Message):
effect: str | None = None effect: str | None = None
@staticmethod @staticmethod
def create(user: "iMessageUser", text: str, participants: list[str], effect: str | None) -> "iMessage": def create(user: "iMessageUser", text: str, participants: list[str], effect: str | None, group_id: uuid.UUID | None) -> "iMessage":
"""Creates a basic outgoing `iMessage` from the given text and participants""" """Creates a basic outgoing `iMessage` from the given text and participants"""
sender = user.user.current_handle sender = user.user.current_handle
@ -285,7 +289,8 @@ class iMessage(Message):
sender=sender, sender=sender,
participants=participants, participants=participants,
id=uuid.uuid4(), id=uuid.uuid4(),
effect=effect effect=effect,
group_id=group_id
) )
@staticmethod @staticmethod
@ -311,6 +316,8 @@ class iMessage(Message):
xml=message["x"] if "x" in message else None, # type: ignore xml=message["x"] if "x" in message else None, # type: ignore
_raw=message, # type: ignore _raw=message, # type: ignore
_compressed=compressed, _compressed=compressed,
group_name=message["n"] if "n" in message else None,
group_id=uuid.UUID(message["gid"]) if "gid" in message else None,
effect=message["iid"] if "iid" in message else None, # type: ignore effect=message["iid"] if "iid" in message else None, # type: ignore
) )
@ -322,6 +329,8 @@ class iMessage(Message):
"x": self.xml, "x": self.xml,
"p": self.participants, "p": self.participants,
"r": str(self.id).upper(), "r": str(self.id).upper(),
"gid": str(self.group_id).upper(),
"n": self.group_name,
"pv": 0, "pv": 0,
"gv": "8", "gv": "8",
"v": "1", "v": "1",
@ -341,7 +350,7 @@ class iMessage(Message):
return d return d
def __str__(self): def __str__(self):
return f"[iMessage {self.sender}] '{self.text}'" return f"[iMessage {self.group_name if self.group_name is not None else self.group_id} {self.sender}] '{self.text}'"
MESSAGE_TYPES = { MESSAGE_TYPES = {
100: ("com.apple.madrid", iMessage), 100: ("com.apple.madrid", iMessage),