Skyline normalizes every interface into the same Space, Message, and Content shapes. When you need interface-specific fields or actions, narrow on platform.

Message narrowing

for await (const [space, message] of app.messages) {
  if (message.platform === "imessage" && message.content.type === "app") {
    console.log(message.content.appId, message.content.data);
  }

  if (message.platform === "whatsapp_business" && message.content.type === "text") {
    await space.send(wa.template({ name: "order_update", language: "en" }));
  }
}

Space narrowing

Check space.platform before calling verbs that only exist on one interface:
if (space.platform === "imessage") {
  await space.send("🎉", { effect: "confetti" });
} else {
  await space.send("🎉");
}
Unsupported verbs throw a catchable error — e.g. group.setName is not supported on whatsapp_business.

Provider imports

Import only the providers you need:
import { imessage } from "@interactions-hq/skyline/providers/imessage";
import { whatsappBusiness } from "@interactions-hq/skyline/providers/whatsapp-business";
See Providers for the full list and combination patterns.