Documentation Index
Fetch the complete documentation index at: https://docs.photon.codes/docs/llms.txt
Use this file to discover all available pages before exploring further.
definePlatform is the entry point for building your own provider. It takes a name and a definition object, and returns a callable that:
- exposes a
.config()method for registering the provider onSpectrum() - accepts a Spectrum instance, space, or message for narrowing
- carries any
staticproperties you declare (like iMessage’stapbacks)
Shape
Field reference
| Field | Required | Description |
|---|---|---|
config | Yes | A Zod schema that validates the object passed to platform.config(). If every field is optional, platform.config() can be called with no arguments. |
user.resolve | Yes | Resolves a user from a string ID. Returns at minimum { id: string }. |
user.schema | No | Optional Zod schema for extra user properties. |
space.resolve | Yes | Resolves or creates a conversation. Receives an array of users plus optional params. |
space.schema | No | Optional Zod schema for the resolved space. |
space.params | No | Zod schema for additional space creation parameters — surfaces as the second arg to platform(app).space(). |
space.actions | No | A map of content-builder factories that become sugar methods on the resolved space. Each space.<name>(...args) delegates to space.send(factory(...args)). Names that collide with built-in Space methods (send, edit, startTyping, stopTyping, responding, getMessage) are skipped at runtime with a warning. |
lifecycle.createClient | Yes | Creates the platform client. Receives config, projectId, projectSecret (both may be undefined), and store. |
lifecycle.destroyClient | No | Tears down the client on shutdown. Omit if no cleanup is needed. |
messages | Yes | Async generator that yields incoming messages. |
send | Yes | Dispatches a content item to a space. All content types — text, attachments, reactions, replies, edits, typing indicators — flow through this single action. Return a ProviderMessageRecord for content that produces a message, or undefined for fire-and-forget signals (reactions, typing, edits). |
actions.getMessage | No | Fetches a message by ID from a space. Powers space.getMessage(id). |
events.[custom] | No | Additional async generators for platform-specific events — exposed on app.[eventName]. |
message.schema | No | Zod schema for extra properties on incoming messages. |
static | No | Constants attached to the platform object (e.g. tapback names). |
Event producers
Every event generator receives{ client, config, store } and returns an AsyncIterable. The signature is .
The core messages stream lives at the top level of the definition. Optional custom event streams (presence, read receipts, etc.) live inside events:
app.presence) and the narrowed platform instance (myPlatform(app).presence).
Message extras
Declare amessage.schema to add extra typed fields to every incoming message. The extractor surfaces them through a narrowed message:
Registering your platform
Exported platforms work like the built-ins — register with.config() and use narrowing for the typed surface: