A space is one open conversation, addressed by a handle (to). app.space() and app.channel() are the same object — prefer space in new code.

Open a space

const space = app.space("+15551234567");
Pass a group chat GUID directly when the conversation is already a group:
const group = app.space("iMessage;+;chat1234567890");

Send messages

await space.send("plain text");
await space.send("tada", { effect: "confetti" });
await space.reply(message.guid!, "threaded reply");
await space.react(message.guid!, "love");
await space.edit(message.guid!, "typo fixed");
await space.unsend(message.guid!);

Typing and read state

await space.typing(true);
await space.typing(false);
await space.read();

Attachments

await space.sendFile({
  path: "/tmp/receipt.pdf",
  name: "receipt.pdf",
});

Users

Every inbound message carries a sender: User with at least id (the platform-specific address). In groups, message.group.participant identifies who sent within the chat.
for await (const [space, message] of app.messages) {
  console.log(message.sender.id, message.sender.displayName);
}

Group operations

await space.group.setName("Launch crew");
await space.group.add("+15557654321");
const members = await space.group.participants();
Branch on space.platform when a verb is not supported — Skyline throws a clear error you can catch.