-
Notifications
You must be signed in to change notification settings - Fork 57
Add iMessage adapter #137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
underthestars-zhy
wants to merge
33
commits into
vercel:main
Choose a base branch
from
photon-hq:feat/imessage
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+3,494
−47
Open
Add iMessage adapter #137
Changes from 19 commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
ce9dc00
Add iMessage adapter package scaffold
underthestars-zhy 17418b6
Add remote config support to iMessage adapter
underthestars-zhy 077ac9b
Remove userName config from iMessage adapter
underthestars-zhy 0f4347c
Store chat instance in iMessage adapter
underthestars-zhy 62a85c3
Add iMessage adapter tests and types
underthestars-zhy 31d7133
Implement postMessage for iMessage adapter
underthestars-zhy 28cf6f1
Add remote mode connection and ready wait in iMessage adapter
underthestars-zhy 2e4484b
Implement editMessage for iMessage remote adapter
underthestars-zhy 3b13c2f
Add `parseMessage` implementation and tests for iMessage adapter
underthestars-zhy f9ae490
Implement `fetchThread` for iMessage remote mode
underthestars-zhy 19e25cb
Implement addReaction/removeReaction for iMessage adapter
underthestars-zhy a4a9129
Implement startTyping for iMessage remote mode
underthestars-zhy 605df2b
Add iMessage format converter and shared adapter dependency
underthestars-zhy b691e46
add meta
underthestars-zhy 504e74d
Add iMessage adapter docs and README
underthestars-zhy f664c6f
Implement fetchMessages for iMessage adapter
underthestars-zhy f113029
Update imessage.mdx
underthestars-zhy 37691f9
support file
underthestars-zhy 5bca3ca
Update README to include iMessage adapter
underthestars-zhy 4c55f14
Update index.mdx
underthestars-zhy dd8a456
Merge upstream/main into feat/imessage
underthestars-zhy e5a86ed
Fix Teams file upload support status in adapter docs
underthestars-zhy f4693bb
Add validation to iMessage `decodeThreadId` for wrong adapter
underthestars-zhy fee6bd0
Fix handleGatewayMessage to use processMessage and pass options
underthestars-zhy 9ce26fb
Update README.md
underthestars-zhy da14fab
Update apps/docs/content/docs/adapters/index.mdx
underthestars-zhy 9fb33da
Update apps/docs/content/docs/adapters/index.mdx
underthestars-zhy a367666
Fix gateway listener closing shared SDK in remote mode
underthestars-zhy 3bcc3aa
Update imessage.mdx
underthestars-zhy a448148
Merge branch 'feat/imessage' of https://github.com/photon-hq/vercel-c…
underthestars-zhy 8696487
Remove webhook forwarding from iMessage adapter
underthestars-zhy b08ad8d
Separate webhook token from remote API key in iMessage adapter
underthestars-zhy 585c8c1
Remove webhook mode from iMessage adapter
underthestars-zhy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,184 @@ | ||
| --- | ||
| title: iMessage | ||
| description: Configure the iMessage adapter with local (on-device) or remote (server-based) integration. | ||
| type: integration | ||
| prerequisites: | ||
| - /docs/getting-started | ||
| --- | ||
|
|
||
| ## Installation | ||
|
|
||
| ```sh title="Terminal" | ||
| pnpm add @chat-adapter/imessage | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| The adapter supports two modes: **local** (running directly on a Mac with iMessage) and **remote** (connecting to a [Photon](https://photon.codes) iMessage server). The mode is auto-detected from the `IMESSAGE_LOCAL` environment variable. | ||
|
|
||
| ### Remote mode | ||
|
|
||
| Recommended for production. Connects to [Photon](https://photon.codes)'s managed iMessage service over HTTP and Socket.IO, so your bot can run on any platform. | ||
|
|
||
| ```typescript title="lib/bot.ts" lineNumbers | ||
| import { Chat } from "chat"; | ||
| import { createiMessageAdapter } from "@chat-adapter/imessage"; | ||
|
|
||
| const bot = new Chat({ | ||
| userName: "mybot", | ||
| adapters: { | ||
| imessage: createiMessageAdapter({ | ||
| local: false, | ||
| }), | ||
| }, | ||
| }); | ||
|
|
||
| bot.onNewMention(async (thread, message) => { | ||
| await thread.post("Hello from iMessage!"); | ||
| }); | ||
| ``` | ||
|
|
||
| ### Local mode | ||
|
|
||
| For development or self-hosted deployments using [imessage-kit](https://github.com/photon-hq/imessage-kit). Reads from the local iMessage database and sends via AppleScript. Must run on macOS with **Full Disk Access** granted. | ||
|
|
||
| ```typescript title="lib/bot.ts" lineNumbers | ||
| import { Chat } from "chat"; | ||
| import { createiMessageAdapter } from "@chat-adapter/imessage"; | ||
|
|
||
| const bot = new Chat({ | ||
| userName: "mybot", | ||
| adapters: { | ||
| imessage: createiMessageAdapter({ | ||
| local: true, | ||
| }), | ||
| }, | ||
| }); | ||
|
|
||
| bot.onNewMention(async (thread, message) => { | ||
| await thread.post("Hello from iMessage!"); | ||
| }); | ||
| ``` | ||
|
|
||
| ## Setup | ||
|
|
||
| ### Remote mode | ||
|
|
||
| Remote mode connects to a [Photon](https://photon.codes) iMessage server, which handles the macOS-side integration on your behalf. You'll need an active Photon subscription to get your server credentials. | ||
|
|
||
| 1. [Request access](https://photon.codes) from Photon to get your server credentials | ||
| 2. Copy your **server URL** and **API key** from the Photon dashboard | ||
| 3. Set `IMESSAGE_SERVER_URL` and `IMESSAGE_API_KEY` environment variables | ||
| 4. Set `IMESSAGE_LOCAL=false` | ||
|
|
||
| ### Local mode | ||
|
|
||
| Local mode requires the adapter to run directly on a macOS machine with iMessage. It uses `@photon-ai/imessage-kit` to read from the local `chat.db` database and send messages via AppleScript. | ||
|
|
||
| 1. Grant **Full Disk Access** to your terminal or application in **System Settings → Privacy & Security → Full Disk Access** | ||
| 2. Ensure iMessage is signed in and working on the Mac | ||
| 3. No additional environment variables are required — local mode is the default | ||
underthestars-zhy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ## Receiving messages | ||
|
|
||
| The adapter supports multiple ways to receive incoming messages: | ||
|
|
||
| ### Gateway listener (recommended) | ||
|
|
||
| Call `startGatewayListener()` to listen for new messages in real-time. In remote mode, this uses Socket.IO push events. In local mode, it polls the iMessage database. | ||
|
|
||
| You can optionally provide a `webhookUrl` to forward events to your webhook endpoint: | ||
|
|
||
| ```typescript title="lib/bot.ts" | ||
| const adapter = bot.getAdapter("imessage"); | ||
| await adapter.startGatewayListener({ | ||
| handleMessage: async (message) => { | ||
| // Process message directly (no webhook needed) | ||
| }, | ||
underthestars-zhy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| }); | ||
| ``` | ||
|
|
||
| ### Webhook | ||
|
|
||
| The adapter handles two webhook formats: | ||
|
|
||
| - **Forwarded gateway events**: Messages forwarded from `startGatewayListener()` with a `GATEWAY_` type prefix, authenticated via the `x-imessage-gateway-token` header | ||
| - **iMessage Kit webhooks** (local mode only): Messages posted directly by `imessage-kit` when configured with a `webhook` URL | ||
|
|
||
| Both formats are automatically detected and handled by `handleWebhook()`. | ||
|
|
||
| ## Configuration | ||
|
|
||
| | Option | Required | Description | | ||
| |--------|----------|-------------| | ||
| | `local` | No | `true` for local mode, `false` for remote. Auto-detected from `IMESSAGE_LOCAL` (default: `true`) | | ||
| | `serverUrl` | Remote only | URL of the remote iMessage server. Auto-detected from `IMESSAGE_SERVER_URL` | | ||
| | `apiKey` | Remote only | API key for authentication. Auto-detected from `IMESSAGE_API_KEY` | | ||
| | `logger` | No | Logger instance (defaults to `ConsoleLogger("info")`) | | ||
|
|
||
| ## Environment variables | ||
|
|
||
| ```bash title=".env.local" | ||
| IMESSAGE_LOCAL=false # Set to "false" for remote mode (default: true) | ||
| IMESSAGE_SERVER_URL=http://... # Required for remote mode | ||
| IMESSAGE_API_KEY=... # Required for remote mode | ||
| ``` | ||
|
|
||
| ## Features | ||
|
|
||
| | Feature | Supported | | ||
| |---------|-----------| | ||
| | Mentions | DMs only | | ||
| | Reactions (add/remove) | Remote only | | ||
| | Cards | No | | ||
| | Modals | No | | ||
| | Streaming | No | | ||
| | DMs | Yes | | ||
| | Ephemeral messages | No | | ||
| | File uploads | Yes | | ||
| | Typing indicator | Remote only | | ||
| | Message history | Yes | | ||
| | Message editing | Remote only | | ||
|
|
||
| ## Tapback reactions | ||
|
|
||
| iMessage uses tapbacks instead of emoji reactions. The adapter maps standard emoji names to iMessage tapbacks: | ||
|
|
||
| | Emoji | Tapback | | ||
| |-------|---------| | ||
| | `love` / `heart` | ❤️ Love | | ||
| | `like` / `thumbs_up` | 👍 Like | | ||
| | `dislike` / `thumbs_down` | 👎 Dislike | | ||
| | `laugh` | 😂 Laugh | | ||
| | `emphasize` / `exclamation` | ‼️ Emphasize | | ||
| | `question` | ❓ Question | | ||
|
|
||
| ## Limitations | ||
|
|
||
| - **Local mode**: Only supports sending/receiving messages, message history, and file uploads. Reactions, typing indicators, message editing, and thread fetching require remote mode. | ||
| - **Formatting**: iMessage is plain-text only. Markdown formatting (bold, italic, etc.) is stripped when sending messages, preserving only the text content. | ||
| - **Platform**: Local mode requires macOS. Remote mode can run on any platform — [Photon](https://photon.codes) manages the iMessage infrastructure for you. | ||
| - **Cards and modals**: iMessage has no support for structured card layouts or interactive modals. | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### "serverUrl is required" error | ||
|
|
||
| - Set `IMESSAGE_SERVER_URL` or pass `serverUrl` in config when using remote mode | ||
| - This error occurs when `IMESSAGE_LOCAL=false` but no server URL is provided | ||
|
|
||
| ### "apiKey is required" error | ||
|
|
||
| - Set `IMESSAGE_API_KEY` or pass `apiKey` in config when using remote mode | ||
|
|
||
| ### Local mode not receiving messages | ||
|
|
||
| - Verify **Full Disk Access** is granted to your terminal or application | ||
| - Check that iMessage is signed in and working | ||
| - Messages are polled from the local database — there may be a short delay | ||
|
|
||
| ### Remote mode connection issues | ||
|
|
||
| - Verify the server URL is correct and accessible | ||
| - Check that the API key matches your Photon iMessage service credentials | ||
| - Confirm your Photon subscription is active | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |
| "slack", | ||
| "teams", | ||
| "gchat", | ||
| "imessage", | ||
| "discord", | ||
| "github", | ||
| "linear" | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # @chat-adapter/imessage | ||
|
|
||
| [](https://www.npmjs.com/package/@chat-adapter/imessage) | ||
| [](https://www.npmjs.com/package/@chat-adapter/imessage) | ||
|
|
||
| iMessage adapter for [Chat SDK](https://chat-sdk.dev/docs). Supports both local (on-device) and remote ([photon](https://photon.codes)-based) iMessage integration. | ||
|
|
||
| ## Installation | ||
|
|
||
| ```bash | ||
| npm install chat @chat-adapter/imessage | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| ```typescript | ||
| import { Chat } from "chat"; | ||
| import { createiMessageAdapter } from "@chat-adapter/imessage"; | ||
|
|
||
| const bot = new Chat({ | ||
| userName: "mybot", | ||
| adapters: { | ||
| imessage: createiMessageAdapter({ | ||
| serverUrl: process.env.IMESSAGE_SERVER_URL!, | ||
| apiKey: process.env.IMESSAGE_API_KEY!, | ||
| }), | ||
| }, | ||
| }); | ||
|
|
||
| bot.onNewMention(async (thread, message) => { | ||
| await thread.post("Hello from iMessage!"); | ||
| }); | ||
| ``` | ||
|
|
||
| ## Documentation | ||
|
|
||
| Full setup instructions, configuration reference, and features at [chat-sdk.dev/docs/adapters/imessage](https://chat-sdk.dev/docs/adapters/imessage). | ||
|
|
||
| ## License | ||
|
|
||
| MIT |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.