{"id":41080186,"url":"https://github.com/photon-hq/imessage-kit","last_synced_at":"2026-01-22T13:37:44.160Z","repository":{"id":319943865,"uuid":"1078665833","full_name":"photon-hq/imessage-kit","owner":"photon-hq","description":"A type-safe, elegant iMessage SDK for macOS with zero dependencies","archived":false,"fork":false,"pushed_at":"2026-01-13T03:48:10.000Z","size":4412,"stargazers_count":1038,"open_issues_count":0,"forks_count":99,"subscribers_count":33,"default_branch":"main","last_synced_at":"2026-01-13T06:50:11.692Z","etag":null,"topics":["agent","ai","apple","imessage","sms","typescript"],"latest_commit_sha":null,"homepage":"https://photon.codes","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/photon-hq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-18T06:44:03.000Z","updated_at":"2026-01-13T06:11:12.000Z","dependencies_parsed_at":"2025-10-29T10:32:58.393Z","dependency_job_id":null,"html_url":"https://github.com/photon-hq/imessage-kit","commit_stats":null,"previous_names":["sg-hq/imessage-kit","photon-hq/imessage-kit"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/photon-hq/imessage-kit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/photon-hq%2Fimessage-kit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/photon-hq%2Fimessage-kit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/photon-hq%2Fimessage-kit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/photon-hq%2Fimessage-kit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/photon-hq","download_url":"https://codeload.github.com/photon-hq/imessage-kit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/photon-hq%2Fimessage-kit/sbom","scorecard":{"id":1241363,"data":{"date":"2026-01-13T03:45:52Z","repo":{"name":"github.com/photon-hq/imessage-kit","commit":"28c9dda26e845d8e7bd940289d50c9327209428a"},"scorecard":{"version":"v5.0.0","commit":"ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4"},"score":4.4,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#binary-artifacts"}},{"name":"Branch-Protection","score":3,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Warn: 'branch protection settings apply to administrators' is disable on branch 'main'","Warn: 'stale review dismissal' is disable on branch 'main'","Warn: branch 'main' does not require approvers","Warn: codeowners review is not required on branch 'main'","Warn: 'last push approval' is disable on branch 'main'","Warn: 'up-to-date branches' is disable on branch 'main'","Info: status check found to merge onto on branch 'main'","Info: PRs are required in order to make changes on branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#branch-protection"}},{"name":"CI-Tests","score":10,"reason":"11 out of 11 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#ci-tests"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#cii-best-practices"}},{"name":"Code-Review","score":0,"reason":"Found 1/11 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#code-review"}},{"name":"Contributors","score":10,"reason":"project has 11 contributing companies or organizations","details":["Info: SwiftGGTeam contributor org/company found, ResightApp contributor org/company found, Track-Mate contributor org/company found, photon contributor org/company found, LinkUpProject contributor org/company found, XRealityZone contributor org/company found, BlackDreamCompany contributor org/company found, AdventureX-RGE contributor org/company found, PornEra contributor org/company found, photon-hq contributor org/company found, institute of disaster prevention science and technology contributor org/company found, "],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#contributors"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#dangerous-workflow"}},{"name":"Dependency-Update-Tool","score":0,"reason":"no update tool detected","details":["Warn: no dependency update tool configurations found"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#dependency-update-tool"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#license"}},{"name":"Maintained","score":0,"reason":"project was created in last 90 days. please review its contents carefully","details":["Warn: Repository was created in last 90 days."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#maintained"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:44"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":4,"reason":"dependency not pinned by hash detected -- score normalized to 4","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:54: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:75: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:78: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:100: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:103: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:63: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:129: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecards.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/scorecards.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/scorecards.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/scorecards.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecards.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/scorecards.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecards.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/scorecards.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/stale.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/photon-hq/imessage-kit/stale.yml/main?enable=pin","Info:   0 out of  20 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   6 third-party GitHubAction dependencies pinned","Info:   6 out of   6 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":8,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 18 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#sast"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#security-policy"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v2.1.0 not signed: https://api.github.com/repos/photon-hq/imessage-kit/releases/271377342","Warn: release artifact v2.0.2 not signed: https://api.github.com/repos/photon-hq/imessage-kit/releases/270253196","Warn: release artifact v2.0.1 not signed: https://api.github.com/repos/photon-hq/imessage-kit/releases/265957320","Warn: release artifact v2.0.0 not signed: https://api.github.com/repos/photon-hq/imessage-kit/releases/261323042","Warn: release artifact v1.1.3 not signed: https://api.github.com/repos/photon-hq/imessage-kit/releases/259863503","Warn: release artifact v2.1.0 does not have provenance: https://api.github.com/repos/photon-hq/imessage-kit/releases/271377342","Warn: release artifact v2.0.2 does not have provenance: https://api.github.com/repos/photon-hq/imessage-kit/releases/270253196","Warn: release artifact v2.0.1 does not have provenance: https://api.github.com/repos/photon-hq/imessage-kit/releases/265957320","Warn: release artifact v2.0.0 does not have provenance: https://api.github.com/repos/photon-hq/imessage-kit/releases/261323042","Warn: release artifact v1.1.3 does not have provenance: https://api.github.com/repos/photon-hq/imessage-kit/releases/259863503"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#signed-releases"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:19","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:20","Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Info: topLevel permissions set to 'read-all': .github/workflows/codeql-analysis.yml:12","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release.yml:9","Info: topLevel permissions set to 'read-all': .github/workflows/scorecards.yml:11","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#token-permissions"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ea7e27ed41b76ab879c862fa0ca4cc9c61764ee4/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2026-01-13T06:50:12.535Z","repository_id":319943865,"created_at":"2026-01-13T06:50:12.535Z","updated_at":"2026-01-13T06:50:12.535Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28663804,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T01:17:37.254Z","status":"online","status_checked_at":"2026-01-22T02:00:07.137Z","response_time":144,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","ai","apple","imessage","sms","typescript"],"created_at":"2026-01-22T13:37:41.946Z","updated_at":"2026-01-22T13:37:44.143Z","avatar_url":"https://github.com/photon-hq.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \n![Banner](./.github/assets/banner.png)\n\n# @photon-ai/imessage-kit\n\n\u003e A type-safe, elegant iMessage SDK for macOS with cross-runtime support\n\n\u003c/div\u003e\n\n[![npm version](https://img.shields.io/npm/v/@photon-ai/imessage-kit.svg)](https://www.npmjs.com/package/@photon-ai/imessage-kit)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)\n[![Discord](https://img.shields.io/badge/Discord-Join-5865F2.svg?logo=discord\u0026logoColor=white)](https://discord.gg/bZd4CMd2H5)\n\nA full-featured iMessage SDK for **reading**, **sending**, and **automating** iMessage conversations on macOS. Perfect for building AI agents, automation tools, and chat-first applications.\n\n\u003e [!NOTE]\n\u003e **✨ Looking for advanced features like threaded replies, tapbacks, message editing, unsending, live typing indicators? Check out [Advanced iMessage Kit](https://github.com/photon-hq/advanced-imessage-kit) and contact us at daniel@photon.codes.**\n\n---\n\n## Features\n\n| Feature | Method | Example |\n|---------|--------|---------|\n| [Send Messages](#send-messages) | `sdk.send()` | [01-send-text.ts](./examples/01-send-text.ts) |\n| [Send Images](#send-images) | `sdk.send()` | [02-send-image.ts](./examples/02-send-image.ts) |\n| [Send Files](#send-files) | `sdk.sendFile()` | [03-send-file.ts](./examples/03-send-file.ts) |\n| [Send to Groups](#send-to-groups) | `sdk.send()` | [04-send-group.ts](./examples/04-send-group.ts) |\n| [Query Messages](#query-messages) | `sdk.getMessages()` | [05-query-messages.ts](./examples/05-query-messages.ts) |\n| [List Chats](#list-chats) | `sdk.listChats()` | [06-list-chats.ts](./examples/06-list-chats.ts) |\n| [Real-time Watching](#real-time-watching) | `sdk.startWatching()` | [07-watch-messages.ts](./examples/07-watch-messages.ts) |\n| [Auto Reply](#auto-reply) | `sdk.message()` | [08-auto-reply.ts](./examples/08-auto-reply.ts) |\n| Batch Send | `sdk.sendBatch()` | [09-batch-send.ts](./examples/09-batch-send.ts) |\n| Get Sent Message | `sdk.send()` | [10-get-sent-message.ts](./examples/10-get-sent-message.ts) |\n| [Plugin System](#plugin-system) | `sdk.use()` | [11-plugin.ts](./examples/11-plugin.ts) |\n| [Error Handling](#error-handling) | `SendError` | [12-error-handling.ts](./examples/12-error-handling.ts) |\n| Watch Own Messages | `sdk.startWatching()` | [13-watch-own-messages.ts](./examples/13-watch-own-messages.ts) |\n| [Scheduled Messages](#scheduled-messages) | `MessageScheduler` | [14-scheduled-messages.ts](./examples/14-scheduled-messages.ts) |\n| [Smart Reminders](#smart-reminders) | `Reminders` | [15-smart-reminders.ts](./examples/15-smart-reminders.ts) |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# For Bun (zero dependencies)\nbun add @photon-ai/imessage-kit\n\n# For Node.js (requires better-sqlite3)\nnpm install @photon-ai/imessage-kit better-sqlite3\n```\n\n### Basic Usage\n\n```typescript\nimport { IMessageSDK } from '@photon-ai/imessage-kit'\n\nconst sdk = new IMessageSDK()\n\n// Send a message\nawait sdk.send('+1234567890', 'Hello from iMessage Kit!')\n\n// Clean up\nawait sdk.close()\n```\n\n### Configuration\n\n```typescript\ninterface IMessageConfig {\n    debug?: boolean              // Enable debug logging\n    maxConcurrent?: number       // Max concurrent sends (default: 5)\n    scriptTimeout?: number       // AppleScript timeout in ms\n    databasePath?: string        // Custom database path\n    plugins?: Plugin[]           // Plugins\n    watcher?: {\n        pollInterval?: number    // Polling interval (default: 2000)\n        unreadOnly?: boolean     // Only watch unread (default: false)\n        excludeOwnMessages?: boolean  // Exclude own messages (default: true)\n    }\n    webhook?: {\n        url: string\n        headers?: Record\u003cstring, string\u003e\n    }\n}\n```\n\n### Granting Permission\n\n`IMessageKit` requires **Full Disk Access** to read your chat history and perform automation tasks.\n\n1. Open **System Settings → Privacy \u0026 Security → Full Disk Access**\n2. Click **\"+\"** and add your IDE or terminal (e.g., Cursor, VS Code, Terminal, Warp)\n\n---\n\n## Messages\n\n\u003e Examples: [01-send-text.ts](./examples/01-send-text.ts) | [02-send-image.ts](./examples/02-send-image.ts) | [03-send-file.ts](./examples/03-send-file.ts) | [05-query-messages.ts](./examples/05-query-messages.ts)\n\n### Send Messages\n\n```typescript\n// Send text\nawait sdk.send('+1234567890', 'Hello World!')\n\n// Send to email\nawait sdk.send('user@example.com', 'Hello!')\n```\n\n### Send Images\n\n```typescript\n// Send local images\nawait sdk.send('+1234567890', { \n    images: ['image1.jpg', 'image2.png'] \n})\n\n// Send network images (auto-download)\nawait sdk.send('+1234567890', { \n    images: ['https://example.com/image.jpg'] \n})\n\n// Text with images\nawait sdk.send('+1234567890', { \n    text: 'Check this out!',\n    images: ['photo.jpg']\n})\n```\n\n### Send Files\n\n```typescript\n// Send files (PDF, CSV, VCF, etc.)\nawait sdk.send('+1234567890', { \n    files: ['document.pdf', 'data.csv', 'contact.vcf'] \n})\n\n// Convenience methods\nawait sdk.sendFile('+1234567890', '/path/to/document.pdf')\nawait sdk.sendFiles('+1234567890', ['file1.pdf', 'file2.csv'], 'Multiple files')\n```\n\n### Query Messages\n\n```typescript\n// Get messages with filters\nconst result = await sdk.getMessages({\n    sender: '+1234567890',\n    unreadOnly: true,\n    limit: 20,\n    since: new Date('2025-01-01'),\n    search: 'meeting'\n})\n\n// Get unread messages grouped by sender\nconst unread = await sdk.getUnreadMessages()\nconsole.log(`${unread.total} unread from ${unread.senderCount} senders`)\n```\n\n---\n\n## Chats\n\n\u003e Examples: [04-send-group.ts](./examples/04-send-group.ts) | [06-list-chats.ts](./examples/06-list-chats.ts)\n\n### List Chats\n\n```typescript\n// Get all chats\nconst all = await sdk.listChats()\n\n// Filter chats\nconst groups = await sdk.listChats({\n    type: 'group',\n    hasUnread: true,\n    sortBy: 'recent',\n    search: 'Project',\n    limit: 20\n})\n\n// Each chat includes\nfor (const chat of groups) {\n    console.log({\n        chatId: chat.chatId,\n        name: chat.displayName,\n        isGroup: chat.isGroup,\n        unread: chat.unreadCount\n    })\n}\n```\n\n### Send to Groups\n\n```typescript\n// Get group chatId from listChats()\nconst groups = await sdk.listChats({ type: 'group' })\nconst chatId = groups[0].chatId  // e.g., 'chat45e2b868...'\n\n// Send to group\nawait sdk.send(chatId, 'Hello group!')\nawait sdk.send(chatId, {\n    text: 'Check these files',\n    files: ['report.pdf']\n})\n```\n\n---\n\n## Real-time Events\n\n\u003e Examples: [07-watch-messages.ts](./examples/07-watch-messages.ts) | [08-auto-reply.ts](./examples/08-auto-reply.ts) | [13-watch-own-messages.ts](./examples/13-watch-own-messages.ts)\n\n### Real-time Watching\n\n```typescript\nawait sdk.startWatching({\n    // All messages\n    onMessage: (msg) =\u003e {\n        console.log(`New: ${msg.text}`)\n    },\n    \n    // DMs only\n    onDirectMessage: (msg) =\u003e {\n        console.log(`DM from ${msg.sender}`)\n    },\n    \n    // Groups only\n    onGroupMessage: (msg) =\u003e {\n        console.log(`Group: ${msg.chatId}`)\n    },\n    \n    onError: (error) =\u003e {\n        console.error(error)\n    }\n})\n\n// Stop watching\nsdk.stopWatching()\n```\n\n### Auto Reply\n\n```typescript\nawait sdk.startWatching({\n    onDirectMessage: async (msg) =\u003e {\n        await sdk.message(msg)\n            .ifFromOthers()\n            .matchText(/hello/i)\n            .replyText('Hi there!')\n            .execute()\n    }\n})\n```\n\n### Message Chain API\n\n```typescript\nawait sdk.message(msg)\n    .ifUnread()\n    .ifNotReaction()   // Skip tapback reactions\n    .ifGroupChat()\n    .when(m =\u003e m.sender.startsWith('+1'))\n    .matchText(/photo/i)\n    .replyImage(['photo.jpg'])\n    .execute()\n```\n\n---\n\n## Attachments\n\n\u003e Examples: [02-send-image.ts](./examples/02-send-image.ts) | [03-send-file.ts](./examples/03-send-file.ts)\n\n### Attachment Helpers\n\n```typescript\nimport {\n    attachmentExists,\n    downloadAttachment,\n    getAttachmentSize,\n    isImageAttachment,\n    isVideoAttachment,\n    isAudioAttachment\n} from '@photon-ai/imessage-kit'\n\nconst msg = await sdk.getMessages({ hasAttachments: true, limit: 1 })\nconst attachment = msg.messages[0].attachments[0]\n\nif (await attachmentExists(attachment)) {\n    const size = await getAttachmentSize(attachment)\n    \n    if (isImageAttachment(attachment)) {\n        await downloadAttachment(attachment, '/path/to/save.jpg')\n    }\n}\n```\n\n### Supported File Types\n\n- **Documents**: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT, RTF\n- **Images**: JPG, PNG, GIF, HEIC, WEBP, AVIF\n- **Contact Cards**: VCF (vCard)\n- **Data Files**: CSV, JSON, XML\n- **Archives**: ZIP, RAR, 7Z\n- **Media**: MP4, MOV, MP3, M4A\n\n---\n\n## Scheduling\n\n\u003e Examples: [14-scheduled-messages.ts](./examples/14-scheduled-messages.ts) | [15-smart-reminders.ts](./examples/15-smart-reminders.ts)\n\n### Scheduled Messages\n\n```typescript\nimport { IMessageSDK, MessageScheduler } from '@photon-ai/imessage-kit'\n\nconst sdk = new IMessageSDK()\nconst scheduler = new MessageScheduler(sdk, { debug: true }, {\n    onSent: (msg, result) =\u003e console.log(`✅ Sent: ${msg.id}`),\n    onError: (msg, error) =\u003e console.error(`❌ Failed: ${error.message}`),\n    onComplete: (msg) =\u003e console.log(`🏁 Completed: ${msg.id}`)\n})\n\n// One-time message\nconst id = scheduler.schedule({\n    to: '+1234567890',\n    content: 'Reminder!',\n    sendAt: new Date(Date.now() + 5 * 60 * 1000)  // 5 minutes\n})\n\n// Recurring daily\nscheduler.scheduleRecurring({\n    to: '+1234567890',\n    content: 'Good morning! ☀️',\n    startAt: new Date('2025-01-01T08:00:00'),\n    interval: 'daily',  // 'hourly' | 'daily' | 'weekly' | 'monthly' | number\n    endAt: new Date('2025-12-31')\n})\n\n// Manage\nscheduler.reschedule(id, newDate)\nscheduler.cancel(id)\nscheduler.getPending()\n\n// Persistence\nconst data = scheduler.export()\nscheduler.import(data)\n\n// Cleanup\nscheduler.destroy()\n```\n\n### Smart Reminders\n\nA human-friendly wrapper for scheduling with natural language:\n\n```typescript\nimport { IMessageSDK, Reminders } from '@photon-ai/imessage-kit'\n\nconst sdk = new IMessageSDK()\nconst reminders = new Reminders(sdk)\n\n// Relative time\nreminders.in('5 minutes', '+1234567890', 'Take a break!')\nreminders.in('2 hours', '+1234567890', 'Call the client')\nreminders.in('1 day', '+1234567890', 'Follow up')\n\n// Specific time\nreminders.at('5pm', '+1234567890', 'End of day review')\nreminders.at('tomorrow 9am', '+1234567890', 'Morning standup')\nreminders.at('friday 2pm', '+1234567890', 'Weekly sync')\n\n// Exact date\nreminders.exact(new Date('2025-12-25T10:00:00'), '+1234567890', 'Merry Christmas!')\n\n// Manage\nreminders.list()    // List pending\nreminders.count()   // Count pending\nreminders.cancel(id)\nreminders.destroy()\n```\n\n**Supported formats:**\n- Duration: `\"5 minutes\"`, `\"2 hours\"`, `\"1 day\"`, `\"30 seconds\"`, `\"1 week\"`\n- Time: `\"5pm\"`, `\"5:30pm\"`, `\"17:30\"`\n- Day + Time: `\"tomorrow 9am\"`, `\"friday 2pm\"`\n\n---\n\n## Plugin System\n\n\u003e Example: [11-plugin.ts](./examples/11-plugin.ts)\n\n```typescript\nimport { loggerPlugin } from '@photon-ai/imessage-kit'\n\n// Built-in logger\nsdk.use(loggerPlugin({\n    level: 'info',\n    colored: true\n}))\n\n// Custom plugin\nsdk.use({\n    name: 'my-plugin',\n    onInit: async () =\u003e console.log('Initialized'),\n    onBeforeSend: async (to, content) =\u003e {\n        console.log('Sending to:', to)\n        return { to, content }\n    },\n    onAfterSend: async (result) =\u003e {\n        console.log('Sent:', result)\n    },\n    onDestroy: async () =\u003e console.log('Destroyed')\n})\n```\n\n---\n\n## Error Handling\n\n\u003e Example: [12-error-handling.ts](./examples/12-error-handling.ts)\n\n```typescript\nimport { SendError, DatabaseError, PlatformError } from '@photon-ai/imessage-kit'\n\ntry {\n    await sdk.send('+1234567890', 'Hello')\n} catch (error) {\n    if (error instanceof SendError) {\n        console.error('Send failed:', error.message)\n    } else if (error instanceof DatabaseError) {\n        console.error('Database error:', error.message)\n    } else if (error instanceof PlatformError) {\n        console.error('Platform error:', error.message)\n    }\n}\n```\n\n---\n\n## Examples\n\nRun any example with Bun:\n\n```bash\nbun run examples/\u003cfilename\u003e.ts\n```\n\n### Getting Started\n- [01-send-text.ts](./examples/01-send-text.ts) - Basic text message\n- [02-send-image.ts](./examples/02-send-image.ts) - Send images\n- [03-send-file.ts](./examples/03-send-file.ts) - Send files\n\n### Message Operations\n- [05-query-messages.ts](./examples/05-query-messages.ts) - Query messages\n- [09-batch-send.ts](./examples/09-batch-send.ts) - Batch sending\n- [10-get-sent-message.ts](./examples/10-get-sent-message.ts) - Get sent message\n\n### Chats \u0026 Groups\n- [04-send-group.ts](./examples/04-send-group.ts) - Send to group\n- [06-list-chats.ts](./examples/06-list-chats.ts) - List chats\n\n### Real-time \u0026 Automation\n- [07-watch-messages.ts](./examples/07-watch-messages.ts) - Watch messages\n- [08-auto-reply.ts](./examples/08-auto-reply.ts) - Auto-reply bot\n- [13-watch-own-messages.ts](./examples/13-watch-own-messages.ts) - Watch own messages\n\n### Scheduling\n- [14-scheduled-messages.ts](./examples/14-scheduled-messages.ts) - Scheduled messages\n- [15-smart-reminders.ts](./examples/15-smart-reminders.ts) - Smart reminders\n\n### Advanced\n- [11-plugin.ts](./examples/11-plugin.ts) - Custom plugin\n- [12-error-handling.ts](./examples/12-error-handling.ts) - Error handling\n\n---\n\n## API Reference\n\n### Core Methods\n\n| Method | Description |\n|--------|-------------|\n| `getMessages(filter?)` | Query messages with filters |\n| `getUnreadMessages()` | Get unread messages grouped by sender |\n| `listChats(options?)` | List chats with filtering/sorting |\n| `send(to, content)` | Send text, images, and/or files |\n| `sendFile(to, path, text?)` | Send a single file |\n| `sendFiles(to, paths, text?)` | Send multiple files |\n| `sendBatch(messages)` | Send multiple messages concurrently |\n| `message(msg)` | Create message processing chain |\n| `startWatching(events?)` | Start monitoring new messages |\n| `stopWatching()` | Stop monitoring |\n| `use(plugin)` | Register plugin |\n| `close()` | Close SDK and release resources |\n\n### Types\n\n```typescript\ninterface Message {\n    id: string\n    guid: string\n    text: string | null\n    sender: string\n    senderName: string | null\n    chatId: string\n    isGroupChat: boolean\n    isFromMe: boolean\n    isRead: boolean\n    service: 'iMessage' | 'SMS' | 'RCS'\n    attachments: Attachment[]\n    date: Date\n    // Reaction fields\n    isReaction: boolean\n    reactionType: 'love' | 'like' | 'dislike' | 'laugh' | 'emphasize' | 'question' | null\n    isReactionRemoval: boolean\n    associatedMessageGuid: string | null\n}\n\ninterface SendResult {\n    sentAt: Date\n    message?: Message  // Available if watcher is running\n}\n```\n\n---\n\n## Requirements\n\n- **OS**: macOS only\n- **Runtime**: Node.js \u003e= 18.0.0 or Bun \u003e= 1.0.0\n- **Permissions**: Full Disk Access\n\n---\n\n## LLMs\n\nDownload `llms.txt` for language model context:\n\n- [Download llms.txt](./llms.txt)\n\n### Context7 MCP\n\n- [Context7 Docs](https://context7.com/photon-hq/imessage-kit)\n\nAdd [Context7 MCP](https://context7.com/docs/installation) to your IDE, then use:\n\n```\nuse context7: photon-hq/imessage-kit\n```\n\n---\n\n## License\n\n[MIT License](./LICENSE)\n\n---\n\n**Note**: This SDK is for educational and development purposes. Always respect user privacy and follow Apple's terms of service.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphoton-hq%2Fimessage-kit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphoton-hq%2Fimessage-kit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphoton-hq%2Fimessage-kit/lists"}