{"id":41748556,"url":"https://github.com/photon-hq/advanced-imessage-kit","last_synced_at":"2026-02-19T10:09:12.123Z","repository":{"id":322248550,"uuid":"1086278068","full_name":"photon-hq/advanced-imessage-kit","owner":"photon-hq","description":"The Typescript SDK for Next Level iMessage Automation","archived":false,"fork":false,"pushed_at":"2026-02-17T05:13:20.000Z","size":1149,"stargazers_count":143,"open_issues_count":0,"forks_count":14,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-17T11:30:39.833Z","etag":null,"topics":["agent","ai","apple","imessage","ims","message","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-30T07:41:18.000Z","updated_at":"2026-02-17T05:13:16.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/photon-hq/advanced-imessage-kit","commit_stats":null,"previous_names":["photon-hq/advanced-imessage-kit"],"tags_count":43,"template":false,"template_full_name":null,"purl":"pkg:github/photon-hq/advanced-imessage-kit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/photon-hq%2Fadvanced-imessage-kit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/photon-hq%2Fadvanced-imessage-kit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/photon-hq%2Fadvanced-imessage-kit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/photon-hq%2Fadvanced-imessage-kit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/photon-hq","download_url":"https://codeload.github.com/photon-hq/advanced-imessage-kit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/photon-hq%2Fadvanced-imessage-kit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29609531,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T06:47:36.664Z","status":"ssl_error","status_checked_at":"2026-02-19T06:45:47.551Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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","ims","message","typescript"],"created_at":"2026-01-25T01:07:38.250Z","updated_at":"2026-02-19T10:09:12.089Z","avatar_url":"https://github.com/photon-hq.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n![Banner](./.github/assets/banner.png)\n\n# Advanced iMessage Kit\n\n\u003e A powerful TypeScript SDK for iMessage with real-time messaging support\n\n\u003c/div\u003e\n\n[![TypeScript](https://img.shields.io/badge/TypeScript-^5-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/RSJUUHTV)\n\nAdvanced iMessage Kit is a full-featured iMessage SDK for **reading**, **sending**, and **automating** iMessage conversations on macOS. Perfect for building **AI agents**, **automation tools**, and **chat applications**.\n\n---\n\n## Features\n\n| Feature                                                    | Description                                   | Method                                       | Example                                                                         |\n| ---------------------------------------------------------- | --------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------- |\n| [Send Messages](#send-messages)                            | Send text messages to any contact             | `messages.sendMessage()`                     | [message-send.ts](./examples/message-send.ts)                                   |\n| [Reply to Messages](#send-messages)                        | Reply inline to a specific message            | `messages.sendMessage()`                     | [message-reply.ts](./examples/message-reply.ts)                                 |\n| [Message Effects](#send-messages)                          | Send with effects (confetti, fireworks, etc.) | `messages.sendMessage()`                     | [message-effects.ts](./examples/message-effects.ts)                             |\n| [Send Rich Links](#send-messages)                          | Send URLs with rich link previews             | `messages.sendMessage()`                     | [message-rich-link.ts](./examples/message-rich-link.ts)                         |\n| [Schedule Messages](#scheduled-messages)                   | Send once or on a recurring schedule          | `scheduledMessages.createScheduledMessage()` | [scheduled-message-once.ts](./examples/scheduled-message-once.ts)               |\n| [Unsend Messages](#unsend-messages)                        | Retract a sent message                        | `messages.unsendMessage()`                   | [message-unsend.ts](./examples/message-unsend.ts)                               |\n| [Edit Messages](#edit-messages)                            | Edit a sent message                           | `messages.editMessage()`                     | [message-edit.ts](./examples/message-edit.ts)                                   |\n| [Send Tapbacks](#send-tapbacks)                            | React with ❤️ 👍 👎 😂 ‼️ ❓                  | `messages.sendReaction()`                    | [message-reaction.ts](./examples/message-reaction.ts)                           |\n| [Query Messages](#query-messages)                          | Search and filter message history             | `messages.getMessages()`                     | [message-search.ts](./examples/message-search.ts)                               |\n| [Destination Caller ID](#query-messages)                   | See which of your addresses sent/received     | `messages.getMessages()`                     | [message-destination-caller-id.ts](./examples/message-destination-caller-id.ts) |\n| [Message History](#get-chat-messages)                      | View messages, reactions, polls, stickers     | `chats.getChatMessages()`                    | [message-history.ts](./examples/message-history.ts)                             |\n| [Send Attachments](#send-attachments)                      | Send images, files, documents                 | `attachments.sendAttachment()`               | [message-attachment.ts](./examples/message-attachment.ts)                       |\n| [Send Audio Messages](#send-audio-messages)                | Send voice messages                           | `attachments.sendAttachment()`               | [message-audio.ts](./examples/message-audio.ts)                                 |\n| [Send Stickers](#send-stickers)                            | Send sticker as standalone message            | `attachments.sendSticker()`                  | [message-sticker.ts](./examples/message-sticker.ts)                             |\n| [Reply Stickers](#send-stickers)                           | Attach sticker to a message bubble            | `attachments.sendSticker()`                  | [message-reply-sticker.ts](./examples/message-reply-sticker.ts)                 |\n| [Download Attachments](#download-attachments)              | Download received files and media             | `attachments.downloadAttachment()`           | [attachment-download.ts](./examples/attachment-download.ts)                     |\n| [Get Chats](#get-chats)                                    | List all conversations                        | `chats.getChats()`                           | [chat-fetch.ts](./examples/chat-fetch.ts)                                       |\n| [Get Chat Participants](#get-chat-participants)            | View group chat participants                  | `chats.getChat()`                            | [chat-participants.ts](./examples/chat-participants.ts)                         |\n| [Manage Group Chats](#manage-group-chats)                  | Add/remove members, rename groups             | `chats.addParticipant()`                     | [chat-group.ts](./examples/chat-group.ts)                                       |\n| [Typing Indicators](#typing-indicators)                    | Show \"typing...\" status                       | `chats.startTyping()`                        | [message-typing.ts](./examples/message-typing.ts)                               |\n| [Get Contacts](#get-contacts)                              | Fetch device contacts                         | `contacts.getContacts()`                     | [contact-list.ts](./examples/contact-list.ts)                                   |\n| [Share Contact Card](#share-contact-card)                  | Share your contact info in chat               | `contacts.shareContactCard()`                | [message-contact-card.ts](./examples/message-contact-card.ts)                   |\n| [Check iMessage Availability](#check-service-availability) | Verify if contact uses iMessage               | `handles.getHandleAvailability()`            | [service-check.ts](./examples/service-check.ts)                                 |\n| [Server Info](#get-server-info)                            | Get server status and config                  | `server.getServerInfo()`                     | [server-info.ts](./examples/server-info.ts)                                     |\n| [Message Statistics](#message-statistics)                  | Get message counts and analytics              | `server.getMessageStats()`                   | [message-stats.ts](./examples/message-stats.ts)                                 |\n| [Create Polls](#create-polls)                              | Create interactive polls in chat              | `polls.create()`                             | [poll-create.ts](./examples/poll-create.ts)                                     |\n| [Vote on Polls](#vote-on-polls)                            | Vote or unvote on poll options                | `polls.vote()`                               | [poll-vote.ts](./examples/poll-vote.ts)                                         |\n| [Add Poll Options](#add-poll-options)                      | Add options to existing polls                 | `polls.addOption()`                          | [poll-add-option.ts](./examples/poll-add-option.ts)                             |\n| [Find My Friends](#find-my-friends)                        | Get friends' locations                        | `icloud.refreshFindMyFriends()`              | [findmy-friends.ts](./examples/findmy-friends.ts)                               |\n| [Set Chat Background](#chat-background)                    | Set custom background image for chat          | `chats.setBackground()`                      | [background-set.ts](./examples/background-set.ts)                               |\n| [Remove Chat Background](#chat-background)                 | Remove background from chat                   | `chats.removeBackground()`                   | [background-remove.ts](./examples/background-remove.ts)                         |\n| [Real-time Events](#real-time-events)                      | Listen for new messages, typing, etc.         | `sdk.on()`                                   | [listen-simple.ts](./examples/listen-simple.ts)                                 |\n| [Auto Reply](#real-time-events)                            | Build automated reply bots                    | `sdk.on()`                                   | [auto-reply-hey.ts](./examples/auto-reply-hey.ts)                               |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\nnpm install @photon-ai/advanced-imessage-kit\n# or\nbun add @photon-ai/advanced-imessage-kit\n```\n\n### Basic Usage\n\n```typescript\nimport { SDK } from \"@photon-ai/advanced-imessage-kit\";\n\nconst sdk = SDK({\n  serverUrl: \"http://localhost:1234\",\n});\n\nawait sdk.connect();\n\nsdk.on(\"new-message\", (message) =\u003e {\n  console.log(\"New message:\", message.text);\n});\n\nawait sdk.messages.sendMessage({\n  chatGuid: \"iMessage;-;+1234567890\",\n  message: \"Hello World!\",\n});\n\nawait sdk.close();\n```\n\n### Configuration\n\n```typescript\ninterface ClientConfig {\n  serverUrl?: string; // Server URL, defaults to \"http://localhost:1234\"\n  apiKey?: string; // API key (if server requires authentication)\n  logLevel?: \"debug\" | \"info\" | \"warn\" | \"error\"; // Log level, defaults to \"info\"\n  logToFile?: boolean; // Enable writing logs to ~/Library/Logs/AdvancedIMessageKit (default true)\n}\n```\n\n---\n\n## Core Concepts\n\n### chatGuid Format\n\n`chatGuid` is the unique identifier for a conversation. The format is `service;-;address`:\n\n- **iMessage DM**: `iMessage;-;+1234567890` or `iMessage;-;email@example.com`\n- **SMS DM**: `SMS;-;+1234567890`\n- **Group chat**: `iMessage;+;chat123456789`\n- **Auto-detect**: `any;-;+1234567890` (SDK automatically detects the service type)\n\n### How to Get IDs\n\n```\n┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐\n│  Phone / Email  │────▶│  Build chatGuid │────▶│  Send Message   │\n│  +1234567890    │     │ any;-;+123...   │     │  sendMessage()  │\n└─────────────────┘     └─────────────────┘     └─────────────────┘\n\n┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐\n│   getChats()    │────▶│  Get chat.guid  │────▶│  Use for other  │\n│   List chats    │     │                 │     │  operations     │\n└─────────────────┘     └─────────────────┘     └─────────────────┘\n\n┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐\n│  sendMessage()  │────▶│ Get message.guid│────▶│  edit/unsend    │\n│   Send message  │     │                 │     │  sendReaction   │\n└─────────────────┘     └─────────────────┘     └─────────────────┘\n```\n\n---\n\n## Messages\n\n\u003e Examples: [message-send.ts](./examples/message-send.ts) | [message-unsend.ts](./examples/message-unsend.ts) | [message-edit.ts](./examples/message-edit.ts) | [message-reaction.ts](./examples/message-reaction.ts) | [message-rich-link.ts](./examples/message-rich-link.ts) | [message-search.ts](./examples/message-search.ts)\n\n### Send Messages\n\n```typescript\n// Send a text message\nconst message = await sdk.messages.sendMessage({\n  chatGuid: \"iMessage;-;+1234567890\",\n  message: \"Hello!\",\n});\n\n// With subject and effect\nawait sdk.messages.sendMessage({\n  chatGuid: \"iMessage;-;+1234567890\",\n  message: \"Happy Birthday!\",\n  subject: \"Wishes\",\n  effectId: \"com.apple.messages.effect.CKConfettiEffect\",\n});\n\n// Reply to a message\nawait sdk.messages.sendMessage({\n  chatGuid: \"iMessage;-;+1234567890\",\n  message: \"This is a reply\",\n  selectedMessageGuid: \"original-message-guid\",\n});\n\n// Send a rich link preview\nawait sdk.messages.sendMessage({\n  chatGuid: \"iMessage;-;+1234567890\",\n  message: \"https://photon.codes/\",\n  richLink: true,\n});\n```\n\n**Message Effects**:\n\n| Effect        | effectId                                          |\n| ------------- | ------------------------------------------------- |\n| Confetti      | `com.apple.messages.effect.CKConfettiEffect`      |\n| Fireworks     | `com.apple.messages.effect.CKFireworksEffect`     |\n| Balloons      | `com.apple.messages.effect.CKBalloonEffect`       |\n| Hearts        | `com.apple.messages.effect.CKHeartEffect`         |\n| Lasers        | `com.apple.messages.effect.CKHappyBirthdayEffect` |\n| Shooting Star | `com.apple.messages.effect.CKShootingStarEffect`  |\n| Sparkles      | `com.apple.messages.effect.CKSparklesEffect`      |\n| Echo          | `com.apple.messages.effect.CKEchoEffect`          |\n| Spotlight     | `com.apple.messages.effect.CKSpotlightEffect`     |\n| Gentle        | `com.apple.MobileSMS.expressivesend.gentle`       |\n| Loud          | `com.apple.MobileSMS.expressivesend.loud`         |\n| Slam          | `com.apple.MobileSMS.expressivesend.impact`       |\n| Invisible Ink | `com.apple.MobileSMS.expressivesend.invisibleink` |\n\n\u003e Example: [message-effects.ts](./examples/message-effects.ts)\n\n### Query Messages\n\n```typescript\n// Get a single message\nconst message = await sdk.messages.getMessage(\"message-guid\");\n\n// Query messages\nconst messages = await sdk.messages.getMessages({\n  chatGuid: \"iMessage;-;+1234567890\",\n  limit: 50,\n  offset: 0,\n  sort: \"DESC\", // DESC = newest first, ASC = oldest first\n  before: Date.now(),\n  after: Date.now() - 86400000, // Last 24 hours\n});\n\n// Search messages\nconst results = await sdk.messages.searchMessages({\n  query: \"keyword\",\n  chatGuid: \"iMessage;-;+1234567890\", // Optional\n  limit: 20,\n});\n\n// Get counts\nconst total = await sdk.messages.getMessageCount();\nconst sent = await sdk.messages.getSentMessageCount();\nconst updated = await sdk.messages.getUpdatedMessageCount();\n```\n\n### Unsend Messages\n\n```typescript\nawait sdk.messages.unsendMessage({\n  messageGuid: \"message-guid-to-unsend\",\n  partIndex: 0, // Optional\n});\n```\n\n\u003e Example: [message-unsend.ts](./examples/message-unsend.ts)\n\n### Edit Messages\n\n```typescript\nconst editedMessage = await sdk.messages.editMessage({\n  messageGuid: \"message-guid-to-edit\",\n  editedMessage: \"New text content\",\n  backwardsCompatibilityMessage: \"New text content\", // Optional, defaults to editedMessage\n  partIndex: 0, // Optional, defaults to 0\n});\n\nconsole.log(`Edited: ${editedMessage.guid}`);\nconsole.log(`New text: ${editedMessage.text}`);\nconsole.log(`Date edited: ${editedMessage.dateEdited}`);\n```\n\n\u003e Example: [message-edit.ts](./examples/message-edit.ts)\n\n### Send Tapbacks\n\n```typescript\nawait sdk.messages.sendReaction({\n  chatGuid: \"iMessage;-;+1234567890\",\n  messageGuid: \"target-message-guid\",\n  reaction: \"love\", // love, like, dislike, laugh, emphasize, question\n  partIndex: 0, // Optional\n});\n\n// Remove a Tapback (prefix with -)\nawait sdk.messages.sendReaction({\n  chatGuid: \"iMessage;-;+1234567890\",\n  messageGuid: \"target-message-guid\",\n  reaction: \"-love\", // -love, -like, -dislike, -laugh, -emphasize, -question\n});\n```\n\n\u003e Example: [message-reaction.ts](./examples/message-reaction.ts)\n\n### Other Message Operations\n\n```typescript\n// Trigger message notification\nawait sdk.messages.notifyMessage(\"message-guid\");\n\n// Get embedded media\nconst media = await sdk.messages.getEmbeddedMedia(\"message-guid\");\n```\n\n---\n\n## Scheduled Messages\n\n\u003e Examples: [scheduled-message-once.ts](./examples/scheduled-message-once.ts) | [scheduled-message-recurring.ts](./examples/scheduled-message-recurring.ts) | [scheduled-message-manage.ts](./examples/scheduled-message-manage.ts)\n\n### Schedule a one-time message\n\n```typescript\nconst scheduled = await sdk.scheduledMessages.createScheduledMessage({\n  type: \"send-message\",\n  payload: {\n    chatGuid: \"any;-;+1234567890\",\n    message: \"This is a scheduled message!\",\n    method: \"apple-script\",\n  },\n  scheduledFor: Date.now() + 3 * 1000,\n  schedule: { type: \"once\" },\n});\n```\n\n### Schedule a recurring message\n\n```typescript\nconst tomorrow9am = new Date();\ntomorrow9am.setDate(tomorrow9am.getDate() + 1);\ntomorrow9am.setHours(9, 0, 0, 0);\n\nconst daily = await sdk.scheduledMessages.createScheduledMessage({\n  type: \"send-message\",\n  payload: {\n    chatGuid: \"any;-;+1234567890\",\n    message: \"Good morning!\",\n    method: \"apple-script\",\n  },\n  scheduledFor: tomorrow9am.getTime(),\n  schedule: {\n    type: \"recurring\",\n    intervalType: \"daily\", // hourly, daily, weekly, monthly, yearly\n    interval: 1,\n  },\n});\n```\n\n### Manage scheduled messages\n\n```typescript\nconst scheduledMessages = await sdk.scheduledMessages.getScheduledMessages();\n\nconst updated = await sdk.scheduledMessages.updateScheduledMessage(\n  \"scheduled-id\",\n  {\n    type: \"send-message\",\n    payload: {\n      chatGuid: \"any;-;+1234567890\",\n      message: \"Updated message!\",\n      method: \"apple-script\",\n    },\n    scheduledFor: Date.now() + 10 * 60 * 1000,\n    schedule: { type: \"once\" },\n  }\n);\n\nawait sdk.scheduledMessages.deleteScheduledMessage(\"scheduled-id\");\n```\n\n---\n\n## Chats\n\n\u003e Examples: [chat-fetch.ts](./examples/chat-fetch.ts) | [chat-group.ts](./examples/chat-group.ts) | [message-typing.ts](./examples/message-typing.ts) | [background-set.ts](./examples/background-set.ts) | [background-remove.ts](./examples/background-remove.ts)\n\n### Get Chats\n\n```typescript\nconst chats = await sdk.chats.getChats({\n  withLastMessage: true, // Include last message\n  withArchived: false, // Include archived chats\n  offset: 0,\n  limit: 50,\n});\n\n// Get chat count\nconst count = await sdk.chats.getChatCount();\n```\n\n### Get Single Chat\n\n```typescript\nconst chat = await sdk.chats.getChat(\"chat-guid\", {\n  with: [\"participants\", \"lastMessage\"],\n});\n```\n\n### Get Chat Participants\n\nGet participants from group chats and display them with contact names:\n\n```typescript\nconst chats = await sdk.chats.getChats();\nconst groups = chats.filter((chat) =\u003e chat.style === 43); // Filter group chats\n\n// Get contacts for name mapping\nconst contacts = await sdk.contacts.getContacts();\nconst nameMap = new Map\u003cstring, string\u003e();\nfor (const c of contacts) {\n  const name = c.displayName || c.firstName || \"\";\n  if (!name) continue;\n  for (const p of c.phoneNumbers || []) nameMap.set(p.address, name);\n  for (const e of c.emails || []) nameMap.set(e.address, name);\n}\n\n// Display participants\ngroups.forEach((group) =\u003e {\n  console.log(`Group: ${group.displayName || group.chatIdentifier}`);\n  group.participants?.forEach((p) =\u003e {\n    const name = nameMap.get(p.address);\n    const display = name ? `${name} \u003c${p.address}\u003e` : p.address;\n    console.log(`  - ${display} (${p.service})`);\n  });\n});\n```\n\n\u003e Example: [chat-participants.ts](./examples/chat-participants.ts)\n\n### Create Chat\n\n```typescript\nconst newChat = await sdk.chats.createChat({\n  addresses: [\"+1234567890\", \"+0987654321\"],\n  message: \"Hello everyone!\", // Optional initial message\n  service: \"iMessage\", // \"iMessage\" or \"SMS\"\n  method: \"private-api\", // \"apple-script\" or \"private-api\"\n});\n```\n\n### Chat Status\n\n```typescript\n// Mark as read/unread\nawait sdk.chats.markChatRead(\"chat-guid\");\nawait sdk.chats.markChatUnread(\"chat-guid\");\n\n// Delete chat\nawait sdk.chats.deleteChat(\"chat-guid\");\n```\n\n### Typing Indicators\n\n```typescript\n// Show \"typing...\"\nawait sdk.chats.startTyping(\"chat-guid\");\n\n// Stop showing\nawait sdk.chats.stopTyping(\"chat-guid\");\n```\n\n\u003e Example: [message-typing.ts](./examples/message-typing.ts)\n\n### Get Chat Messages\n\n```typescript\nconst messages = await sdk.chats.getChatMessages(\"chat-guid\", {\n  limit: 100,\n  offset: 0,\n  sort: \"DESC\",\n  before: Date.now(),\n  after: Date.now() - 86400000,\n});\n```\n\n### Manage Group Chats\n\n```typescript\n// Rename group\nawait sdk.chats.updateChat(\"chat-guid\", {\n  displayName: \"New Group Name\",\n});\n\n// Add participant\nawait sdk.chats.addParticipant(\"chat-guid\", \"+1234567890\");\n\n// Remove participant\nawait sdk.chats.removeParticipant(\"chat-guid\", \"+1234567890\");\n\n// Leave group\nawait sdk.chats.leaveChat(\"chat-guid\");\n```\n\n### Group Icon\n\n```typescript\n// Set group icon\nawait sdk.chats.setGroupIcon(\"chat-guid\", \"/path/to/image.jpg\");\n\n// Get group icon\nconst iconBuffer = await sdk.chats.getGroupIcon(\"chat-guid\");\n\n// Remove group icon\nawait sdk.chats.removeGroupIcon(\"chat-guid\");\n```\n\n\u003e Example: [chat-group.ts](./examples/chat-group.ts)\n\n### Chat Background\n\nSet, get, or remove custom background images for individual chats:\n\n```typescript\n// Get current background info\nconst bgInfo = await sdk.chats.getBackground(\"chat-guid\");\nconsole.log(`Has background: ${bgInfo.hasBackground}`);\nif (bgInfo.hasBackground) {\n  console.log(`Background ID: ${bgInfo.backgroundId}`);\n  console.log(`Image URL: ${bgInfo.imageUrl}`);\n}\n\n// Set a background image (using file path)\nawait sdk.chats.setBackground(\"chat-guid\", {\n  filePath: \"/path/to/image.png\",\n});\n\n// Set a background image (using base64)\nimport fs from \"node:fs\";\nconst imageBuffer = fs.readFileSync(\"/path/to/image.png\");\nawait sdk.chats.setBackground(\"chat-guid\", {\n  fileData: imageBuffer.toString(\"base64\"),\n});\n\n// Remove background\nawait sdk.chats.removeBackground(\"chat-guid\");\n```\n\n\u003e Examples: [background-set.ts](./examples/background-set.ts) | [background-remove.ts](./examples/background-remove.ts)\n\n---\n\n## Attachments\n\n\u003e Examples: [message-attachment.ts](./examples/message-attachment.ts) | [message-audio.ts](./examples/message-audio.ts) | [message-reply-sticker.ts](./examples/message-reply-sticker.ts) | [attachment-download.ts](./examples/attachment-download.ts)\n\n### Send Attachments\n\n```typescript\nconst message = await sdk.attachments.sendAttachment({\n  chatGuid: \"iMessage;-;+1234567890\",\n  filePath: \"/path/to/file.jpg\",\n  fileName: \"custom-name.jpg\", // Optional\n});\n```\n\n### Send Audio Messages\n\n```typescript\nconst message = await sdk.attachments.sendAttachment({\n  chatGuid: \"iMessage;-;+1234567890\",\n  filePath: \"/path/to/audio.m4a\",\n  isAudioMessage: true,\n});\n```\n\n\u003e Example: [message-audio.ts](./examples/message-audio.ts)\n\n### Send Stickers\n\nStickers can be sent in two ways:\n\n**Standalone Sticker** - Sends as its own message (like sending an image, but with sticker styling):\n\n```typescript\nawait sdk.attachments.sendSticker({\n  chatGuid: \"iMessage;-;+1234567890\",\n  filePath: \"/path/to/sticker.png\",\n});\n```\n\n\u003e Example: [message-sticker.ts](./examples/message-sticker.ts)\n\n**Reply Sticker (Tapback Sticker)** - Attaches to an existing message bubble:\n\n```typescript\nawait sdk.attachments.sendSticker({\n  chatGuid: \"iMessage;-;+1234567890\",\n  filePath: \"/path/to/sticker.png\",\n  selectedMessageGuid: \"target-message-guid\", // Required for reply sticker\n  stickerX: 0.5, // Position X (0-1), default: 0.5\n  stickerY: 0.5, // Position Y (0-1), default: 0.5\n  stickerScale: 0.75, // Scale (0-1), default: 0.75\n  stickerRotation: 0, // Rotation in radians, default: 0\n  stickerWidth: 300, // Width in pixels, default: 300\n});\n```\n\n\u003e Example: [message-reply-sticker.ts](./examples/message-reply-sticker.ts)\n\n### Get Attachment Info\n\n```typescript\n// Get attachment details\nconst attachment = await sdk.attachments.getAttachment(\"attachment-guid\");\n\n// Get total count\nconst count = await sdk.attachments.getAttachmentCount();\n```\n\n### Download Attachments\n\n```typescript\n// Download attachment\nconst buffer = await sdk.attachments.downloadAttachment(\"attachment-guid\", {\n  original: true, // Download original file\n  force: false, // Force re-download\n  width: 800, // Image width (for thumbnails)\n  height: 600, // Image height\n  quality: 80, // Image quality\n});\n\n// Download Live Photo video\nconst liveBuffer = await sdk.attachments.downloadAttachmentLive(\n  \"attachment-guid\"\n);\n\n// Get blurhash (for placeholders)\nconst blurhash = await sdk.attachments.getAttachmentBlurhash(\"attachment-guid\");\n```\n\n\u003e Example: [attachment-download.ts](./examples/attachment-download.ts)\n\n---\n\n## Contacts\n\n\u003e Example: [contact-list.ts](./examples/contact-list.ts)\n\n### Get Contacts\n\n```typescript\nconst contacts = await sdk.contacts.getContacts();\n```\n\n### Get Contact Card\n\n```typescript\n// Get contact card by phone or email\nconst card = await sdk.contacts.getContactCard(\"+1234567890\");\n// {\n//   firstName: \"John\",\n//   lastName: \"Doe\",\n//   emails: [\"john@example.com\"],\n//   phones: [\"+1234567890\"],\n//   ...\n// }\n```\n\n### Share Contact Card\n\nShare your contact card with a chat:\n\n```typescript\n// chatGuid is the chat identifier (e.g. the `guid` field you get from chat APIs/events)\n// Check whether the SDK recommends sharing your contact card in this chat.\n//\n// Returns:\n// - true: sharing is recommended (typically when the other side shared theirs and you haven't shared yours yet)\n// - false: NOT recommended (e.g. you've already shared, OR the other side hasn't shared theirs yet)\nconst shouldShare = await sdk.contacts.shouldShareContact(\"chat-guid\");\n\nif (shouldShare) {\n  // Share your contact card (iMessage \"Share Name and Photo\")\n  await sdk.contacts.shareContactCard(\"chat-guid\");\n}\n```\n\n\u003e Example: [message-contact-card.ts](./examples/message-contact-card.ts)\n\n---\n\n## Handles\n\n\u003e Examples: [service-check.ts](./examples/service-check.ts) | [handle-query.ts](./examples/handle-query.ts)\n\nA Handle represents a messaging address (phone number or email).\n\n### Query Handles\n\n```typescript\n// Query handles\nconst result = await sdk.handles.queryHandles({\n  address: \"+1234567890\", // Optional, filter by address\n  with: [\"chats\"], // Optional, include related chats\n  offset: 0,\n  limit: 50,\n});\n\n// Get single handle\nconst handle = await sdk.handles.getHandle(\"handle-guid\");\n\n// Get total count\nconst count = await sdk.handles.getHandleCount();\n```\n\n### Check Service Availability\n\nCheck if a phone/email supports iMessage or FaceTime:\n\n```typescript\n// First parameter is the address (phone or email), not handle guid\nconst hasIMessage = await sdk.handles.getHandleAvailability(\n  \"+1234567890\",\n  \"imessage\"\n);\nconst hasFaceTime = await sdk.handles.getHandleAvailability(\n  \"+1234567890\",\n  \"facetime\"\n);\n\n// Choose service based on availability\nconst chatGuid = hasIMessage ? `iMessage;-;+1234567890` : `SMS;-;+1234567890`;\n```\n\n\u003e Example: [service-check.ts](./examples/service-check.ts)\n\n### Get Focus Status\n\n```typescript\nconst focusStatus = await sdk.handles.getHandleFocusStatus(\"handle-guid\");\n```\n\n---\n\n## Server\n\n\u003e Examples: [message-stats.ts](./examples/message-stats.ts) | [server-info.ts](./examples/server-info.ts)\n\n### Get Server Info\n\n```typescript\nconst info = await sdk.server.getServerInfo();\n// {\n//   os_version: \"14.0\",\n//   server_version: \"1.0.0\",\n//   private_api: true,\n//   helper_connected: true,\n//   detected_icloud: \"user@icloud.com\",\n//   ...\n// }\n```\n\n### Message Statistics\n\n```typescript\nconst stats = await sdk.server.getMessageStats();\n// {\n//   total: 12345,\n//   sent: 5000,\n//   received: 7345,\n//   last24h: 50,\n//   last7d: 300,\n//   last30d: 1000,\n// }\n```\n\n### Media Statistics\n\n```typescript\n// All media stats\nconst mediaStats = await sdk.server.getMediaStatistics();\n\n// Per-chat media stats\nconst chatMediaStats = await sdk.server.getMediaStatisticsByChat();\n```\n\n### Server Logs\n\n```typescript\nconst logs = await sdk.server.getServerLogs(100); // Get last 100 logs\n```\n\n---\n\n## Polls\n\n\u003e Examples: [poll-create.ts](./examples/poll-create.ts) | [poll-vote.ts](./examples/poll-vote.ts) | [poll-unvote.ts](./examples/poll-unvote.ts) | [poll-add-option.ts](./examples/poll-add-option.ts)\n\n### Create Polls\n\n```typescript\nconst pollMessage = await sdk.polls.create({\n  chatGuid: \"iMessage;-;+1234567890\",\n  title: \"What should we do?\", // Optional\n  options: [\"Option A\", \"Option B\", \"Option C\"],\n});\n\nconsole.log(\"Poll GUID:\", pollMessage.guid);\n```\n\n\u003e Example: [poll-create.ts](./examples/poll-create.ts)\n\n### Add Poll Options\n\n```typescript\nawait sdk.polls.addOption({\n  chatGuid: \"iMessage;-;+1234567890\",\n  pollMessageGuid: \"poll-message-guid\",\n  optionText: \"New Option D\",\n});\n```\n\n\u003e Example: [poll-add-option.ts](./examples/poll-add-option.ts)\n\n### Vote on Polls\n\n```typescript\n// Vote on a poll option\nawait sdk.polls.vote({\n  chatGuid: \"iMessage;-;+1234567890\",\n  pollMessageGuid: \"poll-message-guid\",\n  optionIdentifier: \"option-uuid\", // UUID of the option to vote for\n});\n\n// Remove your vote\nawait sdk.polls.unvote({\n  chatGuid: \"iMessage;-;+1234567890\",\n  pollMessageGuid: \"poll-message-guid\",\n  optionIdentifier: \"option-uuid\",\n});\n```\n\n\u003e Examples: [poll-vote.ts](./examples/poll-vote.ts) | [poll-unvote.ts](./examples/poll-unvote.ts)\n\n### Parse Poll Messages\n\nUse the `poll-utils` helper functions to parse and display poll messages:\n\n```typescript\nimport {\n  isPollMessage,\n  isPollVote,\n  parsePollDefinition,\n  parsePollVotes,\n  getPollSummary,\n  getOptionTextById,\n} from \"@photon-ai/advanced-imessage-kit\";\n\nsdk.on(\"new-message\", (message) =\u003e {\n  if (isPollMessage(message)) {\n    if (isPollVote(message)) {\n      // Parse vote data\n      const voteData = parsePollVotes(message);\n      console.log(\"Votes:\", voteData?.votes);\n\n      // Get option text for each vote\n      voteData?.votes.forEach((vote) =\u003e {\n        const optionText = getOptionTextById(vote.voteOptionIdentifier);\n        console.log(`${vote.participantHandle} voted for \"${optionText}\"`);\n      });\n    } else {\n      // Parse poll definition\n      const pollData = parsePollDefinition(message);\n      console.log(\"Poll title:\", pollData?.title);\n      console.log(\"Options:\", pollData?.options);\n    }\n\n    // Or get a formatted summary\n    console.log(getPollSummary(message));\n  }\n});\n```\n\n**Note**: Poll definitions are automatically cached when received. When a vote arrives, the SDK looks up the corresponding option text from the cache. If you receive a vote for a poll that was created before the SDK started, the option text won't be available and will show the UUID instead.\n\n---\n\n## iCloud\n\n\u003e Example: [findmy-friends.ts](./examples/findmy-friends.ts)\n\n### Find My Friends\n\n```typescript\n// Refresh and get friends' locations\nconst locations = await sdk.icloud.refreshFindMyFriends();\n\n// Each location contains:\n// - handle: phone number or email\n// - coordinates: [latitude, longitude]\n// - long_address: street address (optional)\n// - expiry: timestamp when location expires (optional)\n\n// Find specific friend\nconst friend = locations.find((loc) =\u003e loc.handle === \"+1234567890\");\nif (friend) {\n  console.log(\n    `Coordinates: ${friend.coordinates[0]}, ${friend.coordinates[1]}`\n  );\n  console.log(\n    `Maps: https://maps.google.com/?q=${friend.coordinates[0]},${friend.coordinates[1]}`\n  );\n  if (friend.long_address) console.log(`Address: ${friend.long_address}`);\n}\n\n// List all friends\nconsole.log(`All Friends (${locations.length}):`);\nfor (const loc of locations) {\n  console.log(`${loc.handle}: ${loc.coordinates[0]}, ${loc.coordinates[1]}`);\n}\n```\n\n\u003e Example: [findmy-friends.ts](./examples/findmy-friends.ts)\n\n---\n\n## Real-time Events\n\n\u003e Examples: [listen-simple.ts](./examples/listen-simple.ts) | [listen-advanced.ts](./examples/listen-advanced.ts) | [auto-reply-hey.ts](./examples/auto-reply-hey.ts)\n\nThe SDK receives real-time events from the server via Socket.IO.\n\n### Connection Events\n\n```typescript\nsdk.on(\"ready\", () =\u003e {\n  console.log(\"SDK connected and ready\");\n});\n\nsdk.on(\"disconnect\", () =\u003e {\n  console.log(\"Disconnected\");\n});\n\nsdk.on(\"error\", (error) =\u003e {\n  console.error(\"Error:\", error);\n});\n```\n\n### Message Events\n\n```typescript\n// New message\nsdk.on(\"new-message\", (message) =\u003e {\n  console.log(\"New message:\", message.text);\n  console.log(\"From:\", message.handle?.address);\n  console.log(\"From me:\", message.isFromMe);\n});\n\n// Message status update (delivered, read, etc.)\nsdk.on(\"updated-message\", (message) =\u003e {\n  if (message.dateRead) console.log(\"Message read\");\n  else if (message.dateDelivered) console.log(\"Message delivered\");\n});\n\n// Send failed\nsdk.on(\"message-send-error\", (data) =\u003e {\n  console.error(\"Send failed:\", data);\n});\n```\n\n### Chat Events\n\n```typescript\n// Chat read status changed\nsdk.on(\"chat-read-status-changed\", ({ chatGuid, read }) =\u003e {\n  console.log(`Chat ${chatGuid} marked as ${read ? \"read\" : \"unread\"}`);\n});\n```\n\n### Typing Indicators\n\n```typescript\nsdk.on(\"typing-indicator\", ({ display, guid }) =\u003e {\n  console.log(`${guid} ${display ? \"is typing\" : \"stopped typing\"}`);\n});\n```\n\n### Group Events\n\n```typescript\nsdk.on(\"group-name-change\", (message) =\u003e {\n  console.log(\"Group renamed to:\", message.groupTitle);\n});\n\nsdk.on(\"participant-added\", (message) =\u003e {\n  console.log(\"Someone joined the group\");\n});\n\nsdk.on(\"participant-removed\", (message) =\u003e {\n  console.log(\"Someone was removed from the group\");\n});\n\nsdk.on(\"participant-left\", (message) =\u003e {\n  console.log(\"Someone left the group\");\n});\n\nsdk.on(\"group-icon-changed\", (message) =\u003e {\n  console.log(\"Group icon changed\");\n});\n\nsdk.on(\"group-icon-removed\", (message) =\u003e {\n  console.log(\"Group icon removed\");\n});\n```\n\n### Find My Friends Events\n\n```typescript\nsdk.on(\"new-findmy-location\", (location) =\u003e {\n  console.log(`${location.handle} location updated:`, location.coordinates);\n});\n```\n\n### Remove Event Listeners\n\n```typescript\nconst handler = (message) =\u003e console.log(message);\nsdk.on(\"new-message\", handler);\n\n// Remove specific listener\nsdk.off(\"new-message\", handler);\n\n// Remove all listeners\nsdk.removeAllListeners(\"new-message\");\n```\n\n---\n\n## Best Practices\n\n### Resource Management\n\n```typescript\n// Graceful shutdown\nprocess.on(\"SIGINT\", async () =\u003e {\n  await sdk.close();\n  process.exit(0);\n});\n```\n\n### Message Deduplication\n\nThe SDK includes built-in message deduplication to prevent processing duplicates during network instability:\n\n```typescript\n// Clear processed messages (prevent memory leaks)\nsdk.clearProcessedMessages(1000);\n\n// Get processed message count\nconst count = sdk.getProcessedMessageCount();\n```\n\n### Error Handling\n\n```typescript\ntry {\n  await sdk.messages.sendMessage({\n    chatGuid: \"invalid-guid\",\n    message: \"test\",\n  });\n} catch (error) {\n  if (error.response?.status === 404) {\n    console.error(\"Chat not found\");\n  } else {\n    console.error(\"Send failed:\", error.message);\n  }\n}\n```\n\n### Auto-create Chats\n\nWhen sending to a contact you've never messaged before, the SDK automatically creates the chat:\n\n```typescript\n// Works even without existing chat history\nawait sdk.messages.sendMessage({\n  chatGuid: \"any;-;+1234567890\",\n  message: \"Hi, this is John\",\n});\n// SDK detects the chat doesn't exist, creates it, then sends\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\n| File                                                      | Description                            |\n| --------------------------------------------------------- | -------------------------------------- |\n| [listen-simple.ts](./examples/listen-simple.ts)           | Listen with formatted output           |\n| [listen-advanced.ts](./examples/listen-advanced.ts)       | Listen with full JSON and startup info |\n| [message-send.ts](./examples/message-send.ts)             | Send text messages                     |\n| [message-attachment.ts](./examples/message-attachment.ts) | Send attachments                       |\n| [message-audio.ts](./examples/message-audio.ts)           | Send audio messages                    |\n\n### Message Operations\n\n| File                                                                            | Description           |\n| ------------------------------------------------------------------------------- | --------------------- |\n| [message-reply.ts](./examples/message-reply.ts)                                 | Reply to messages     |\n| [message-unsend.ts](./examples/message-unsend.ts)                               | Unsend messages       |\n| [message-edit.ts](./examples/message-edit.ts)                                   | Edit messages         |\n| [message-reaction.ts](./examples/message-reaction.ts)                           | Send Tapbacks         |\n| [message-effects.ts](./examples/message-effects.ts)                             | Message effects       |\n| [message-search.ts](./examples/message-search.ts)                               | Search messages       |\n| [message-history.ts](./examples/message-history.ts)                             | Message history       |\n| [message-destination-caller-id.ts](./examples/message-destination-caller-id.ts) | Destination caller ID |\n\n### Chats \u0026 Groups\n\n| File                                                    | Description            |\n| ------------------------------------------------------- | ---------------------- |\n| [chat-fetch.ts](./examples/chat-fetch.ts)               | Get chat list          |\n| [chat-participants.ts](./examples/chat-participants.ts) | Get group participants |\n| [chat-group.ts](./examples/chat-group.ts)               | Manage groups          |\n| [message-typing.ts](./examples/message-typing.ts)       | Typing indicators      |\n| [background-set.ts](./examples/background-set.ts)       | Set chat background    |\n| [background-remove.ts](./examples/background-remove.ts) | Remove chat background |\n\n### Contacts \u0026 Services\n\n| File                                                            | Description                   |\n| --------------------------------------------------------------- | ----------------------------- |\n| [contact-list.ts](./examples/contact-list.ts)                   | Get contacts                  |\n| [message-contact-card.ts](./examples/message-contact-card.ts)   | Share contact card            |\n| [service-check.ts](./examples/service-check.ts)                 | Check iMessage availability   |\n| [message-service-check.ts](./examples/message-service-check.ts) | Monitor message service types |\n\n### Attachments \u0026 Media\n\n| File                                                            | Description              |\n| --------------------------------------------------------------- | ------------------------ |\n| [attachment-download.ts](./examples/attachment-download.ts)     | Download attachments     |\n| [message-sticker.ts](./examples/message-sticker.ts)             | Send standalone stickers |\n| [message-reply-sticker.ts](./examples/message-reply-sticker.ts) | Send reply stickers      |\n\n### Polls\n\n| File                                                | Description      |\n| --------------------------------------------------- | ---------------- |\n| [poll-create.ts](./examples/poll-create.ts)         | Create polls     |\n| [poll-vote.ts](./examples/poll-vote.ts)             | Vote on polls    |\n| [poll-unvote.ts](./examples/poll-unvote.ts)         | Unvote on polls  |\n| [poll-add-option.ts](./examples/poll-add-option.ts) | Add poll options |\n\n### Server \u0026 Advanced\n\n| File                                              | Description          |\n| ------------------------------------------------- | -------------------- |\n| [server-info.ts](./examples/server-info.ts)       | Server info and logs |\n| [message-stats.ts](./examples/message-stats.ts)   | Message statistics   |\n| [findmy-friends.ts](./examples/findmy-friends.ts) | Find My Friends      |\n| [auto-reply-hey.ts](./examples/auto-reply-hey.ts) | Auto reply bot       |\n\n---\n\n## LLMs\n\nDownload `llms.txt` for language model context:\n\n- [Download llms.txt](./llms.txt)\n\n---\n\n## License\n\nMIT License\n\n## Author\n\n[@Artist-MOBAI](https://github.com/Artist-MOBAI)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphoton-hq%2Fadvanced-imessage-kit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphoton-hq%2Fadvanced-imessage-kit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphoton-hq%2Fadvanced-imessage-kit/lists"}