@photon-ai/advanced-imessage-kit 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +536 -554
- package/dist/index.cjs +235 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -4
- package/dist/index.d.ts +76 -4
- package/dist/index.js +230 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# Advanced iMessage Kit
|
|
6
6
|
|
|
7
|
-
>
|
|
7
|
+
> A powerful TypeScript SDK for iMessage with real-time messaging support
|
|
8
8
|
|
|
9
9
|
</div>
|
|
10
10
|
|
|
@@ -12,18 +12,38 @@
|
|
|
12
12
|
[](./LICENSE)
|
|
13
13
|
[](https://discord.gg/RSJUUHTV)
|
|
14
14
|
|
|
15
|
-
Advanced iMessage Kit is a
|
|
15
|
+
Advanced 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**.
|
|
16
|
+
|
|
17
|
+
---
|
|
16
18
|
|
|
17
19
|
## Features
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
| Feature | Method | Example |
|
|
22
|
+
| ---------------------------------------------------------- | ---------------------------------- | --------------------------------------------------------------- |
|
|
23
|
+
| [Send Messages](#send-messages) | `messages.sendMessage()` | [message-send.ts](./examples/message-send.ts) |
|
|
24
|
+
| [Reply to Messages](#send-messages) | `messages.sendMessage()` | [message-reply.ts](./examples/message-reply.ts) |
|
|
25
|
+
| [Message Effects](#send-messages) | `messages.sendMessage()` | [message-effects.ts](./examples/message-effects.ts) |
|
|
26
|
+
| [Unsend Messages](#unsend-messages) | `messages.unsendMessage()` | [message-unsend.ts](./examples/message-unsend.ts) |
|
|
27
|
+
| [Send Tapbacks](#send-tapbacks) | `messages.sendReaction()` | [message-reaction.ts](./examples/message-reaction.ts) |
|
|
28
|
+
| [Query Messages](#query-messages) | `messages.getMessages()` | [message-search.ts](./examples/message-search.ts) |
|
|
29
|
+
| [Send Attachments](#send-attachments) | `attachments.sendAttachment()` | [message-attachment.ts](./examples/message-attachment.ts) |
|
|
30
|
+
| [Send Audio Messages](#send-audio-messages) | `attachments.sendAttachment()` | [message-audio.ts](./examples/message-audio.ts) |
|
|
31
|
+
| [Send Stickers](#send-stickers) | `attachments.sendSticker()` | [message-reply-sticker.ts](./examples/message-reply-sticker.ts) |
|
|
32
|
+
| [Download Attachments](#download-attachments) | `attachments.downloadAttachment()` | [attachment-download.ts](./examples/attachment-download.ts) |
|
|
33
|
+
| [Get Chats](#get-chats) | `chats.getChats()` | [chat-fetch.ts](./examples/chat-fetch.ts) |
|
|
34
|
+
| [Manage Group Chats](#manage-group-chats) | `chats.addParticipant()` | [chat-group.ts](./examples/chat-group.ts) |
|
|
35
|
+
| [Typing Indicators](#typing-indicators) | `chats.startTyping()` | [message-typing.ts](./examples/message-typing.ts) |
|
|
36
|
+
| [Get Contacts](#get-contacts) | `contacts.getContacts()` | [contact-list.ts](./examples/contact-list.ts) |
|
|
37
|
+
| [Check iMessage Availability](#check-service-availability) | `handles.getHandleAvailability()` | [service-check.ts](./examples/service-check.ts) |
|
|
38
|
+
| [Server Info](#get-server-info) | `server.getServerInfo()` | [server-info.ts](./examples/server-info.ts) |
|
|
39
|
+
| [Message Statistics](#message-statistics) | `server.getMessageStats()` | [message-stats.ts](./examples/message-stats.ts) |
|
|
40
|
+
| [Create Polls](#create-polls) | `polls.create()` | [poll-create.ts](./examples/poll-create.ts) |
|
|
41
|
+
| [Add Poll Options](#add-poll-options) | `polls.addOption()` | [poll-add-option.ts](./examples/poll-add-option.ts) |
|
|
42
|
+
| [Find My Friends](#find-my-friends) _(WIP)_ | `icloud.getFindMyFriends()` | [findmy-friends.ts](./examples/findmy-friends.ts) |
|
|
43
|
+
| [Real-time Events](#real-time-events) | `sdk.on()` | [listen-simple.ts](./examples/listen-simple.ts) |
|
|
44
|
+
| [Auto Reply](#real-time-events) | `sdk.on()` | [auto-reply-hey.ts](./examples/auto-reply-hey.ts) |
|
|
45
|
+
|
|
46
|
+
---
|
|
27
47
|
|
|
28
48
|
## Quick Start
|
|
29
49
|
|
|
@@ -41,158 +61,266 @@ bun add @photon-ai/advanced-imessage-kit
|
|
|
41
61
|
import { SDK } from "@photon-ai/advanced-imessage-kit";
|
|
42
62
|
|
|
43
63
|
const sdk = SDK({
|
|
44
|
-
serverUrl: "
|
|
64
|
+
serverUrl: "http://localhost:1234",
|
|
45
65
|
});
|
|
46
66
|
|
|
47
|
-
// Connect to the server
|
|
48
67
|
await sdk.connect();
|
|
49
68
|
|
|
50
|
-
// Listen for new messages
|
|
51
69
|
sdk.on("new-message", (message) => {
|
|
52
70
|
console.log("New message:", message.text);
|
|
53
71
|
});
|
|
54
72
|
|
|
55
|
-
// Send a message
|
|
56
73
|
await sdk.messages.sendMessage({
|
|
57
|
-
chatGuid: "
|
|
74
|
+
chatGuid: "iMessage;-;+1234567890",
|
|
58
75
|
message: "Hello World!",
|
|
59
76
|
});
|
|
60
77
|
|
|
61
|
-
// Disconnect when done
|
|
62
78
|
await sdk.close();
|
|
63
79
|
```
|
|
64
80
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
### Initialization & Connection
|
|
81
|
+
### Configuration
|
|
68
82
|
|
|
69
83
|
```typescript
|
|
70
|
-
|
|
84
|
+
interface ClientConfig {
|
|
85
|
+
serverUrl?: string; // Server URL, defaults to "http://localhost:1234"
|
|
86
|
+
apiKey?: string; // API key (if server requires authentication)
|
|
87
|
+
logLevel?: "debug" | "info" | "warn" | "error"; // Log level, defaults to "info"
|
|
88
|
+
}
|
|
89
|
+
```
|
|
71
90
|
|
|
72
|
-
|
|
73
|
-
serverUrl: "{your-subdomain}.imsgd.photon.codes", // Your subdomain is the unique link address assigned to you
|
|
74
|
-
logLevel: "info", // Log level: 'debug' | 'info' | 'warn' | 'error'
|
|
75
|
-
});
|
|
91
|
+
---
|
|
76
92
|
|
|
77
|
-
|
|
78
|
-
await sdk.connect();
|
|
93
|
+
## Core Concepts
|
|
79
94
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
95
|
+
### chatGuid Format
|
|
96
|
+
|
|
97
|
+
`chatGuid` is the unique identifier for a conversation. The format is `service;-;address`:
|
|
98
|
+
|
|
99
|
+
- **iMessage DM**: `iMessage;-;+1234567890` or `iMessage;-;email@example.com`
|
|
100
|
+
- **SMS DM**: `SMS;-;+1234567890`
|
|
101
|
+
- **Group chat**: `iMessage;+;chat123456789`
|
|
102
|
+
- **Auto-detect**: `any;-;+1234567890` (SDK automatically detects the service type)
|
|
103
|
+
|
|
104
|
+
### How to Get IDs
|
|
84
105
|
|
|
85
|
-
// Graceful disconnect
|
|
86
|
-
await sdk.close();
|
|
87
106
|
```
|
|
107
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
108
|
+
│ Phone / Email │────▶│ Build chatGuid │────▶│ Send Message │
|
|
109
|
+
│ +1234567890 │ │ any;-;+123... │ │ sendMessage() │
|
|
110
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
88
111
|
|
|
89
|
-
|
|
112
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
113
|
+
│ getChats() │────▶│ Get chat.guid │────▶│ Use for other │
|
|
114
|
+
│ List chats │ │ │ │ operations │
|
|
115
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
90
116
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
117
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
118
|
+
│ sendMessage() │────▶│ Get message.guid│────▶│ edit/unsend │
|
|
119
|
+
│ Send message │ │ │ │ sendReaction │
|
|
120
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
95
121
|
```
|
|
96
122
|
|
|
97
|
-
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Messages
|
|
98
126
|
|
|
99
|
-
|
|
127
|
+
> Examples: [message-send.ts](./examples/message-send.ts) | [message-unsend.ts](./examples/message-unsend.ts) | [message-reaction.ts](./examples/message-reaction.ts) | [message-search.ts](./examples/message-search.ts)
|
|
128
|
+
|
|
129
|
+
### Send Messages
|
|
100
130
|
|
|
101
131
|
```typescript
|
|
102
|
-
// Send text message
|
|
132
|
+
// Send a text message
|
|
103
133
|
const message = await sdk.messages.sendMessage({
|
|
104
|
-
chatGuid: "
|
|
105
|
-
message: "Hello
|
|
134
|
+
chatGuid: "iMessage;-;+1234567890",
|
|
135
|
+
message: "Hello!",
|
|
106
136
|
});
|
|
107
137
|
|
|
108
|
-
//
|
|
138
|
+
// With subject and effect
|
|
109
139
|
await sdk.messages.sendMessage({
|
|
110
|
-
chatGuid: "
|
|
111
|
-
message: "
|
|
112
|
-
subject: "
|
|
140
|
+
chatGuid: "iMessage;-;+1234567890",
|
|
141
|
+
message: "Happy Birthday!",
|
|
142
|
+
subject: "Wishes",
|
|
113
143
|
effectId: "com.apple.messages.effect.CKConfettiEffect",
|
|
114
144
|
});
|
|
115
145
|
|
|
116
|
-
// Reply to message
|
|
146
|
+
// Reply to a message
|
|
117
147
|
await sdk.messages.sendMessage({
|
|
118
|
-
chatGuid: "
|
|
148
|
+
chatGuid: "iMessage;-;+1234567890",
|
|
119
149
|
message: "This is a reply",
|
|
120
150
|
selectedMessageGuid: "original-message-guid",
|
|
121
151
|
});
|
|
122
152
|
```
|
|
123
153
|
|
|
124
|
-
|
|
154
|
+
**Message Effects**:
|
|
155
|
+
|
|
156
|
+
| Effect | effectId |
|
|
157
|
+
| ------------- | ------------------------------------------------- |
|
|
158
|
+
| Confetti | `com.apple.messages.effect.CKConfettiEffect` |
|
|
159
|
+
| Fireworks | `com.apple.messages.effect.CKFireworksEffect` |
|
|
160
|
+
| Balloons | `com.apple.messages.effect.CKBalloonEffect` |
|
|
161
|
+
| Hearts | `com.apple.messages.effect.CKHeartEffect` |
|
|
162
|
+
| Lasers | `com.apple.messages.effect.CKHappyBirthdayEffect` |
|
|
163
|
+
| Shooting Star | `com.apple.messages.effect.CKShootingStarEffect` |
|
|
164
|
+
| Sparkles | `com.apple.messages.effect.CKSparklesEffect` |
|
|
165
|
+
| Echo | `com.apple.messages.effect.CKEchoEffect` |
|
|
166
|
+
| Spotlight | `com.apple.messages.effect.CKSpotlightEffect` |
|
|
167
|
+
| Gentle | `com.apple.MobileSMS.expressivesend.gentle` |
|
|
168
|
+
| Loud | `com.apple.MobileSMS.expressivesend.loud` |
|
|
169
|
+
| Slam | `com.apple.MobileSMS.expressivesend.impact` |
|
|
170
|
+
| Invisible Ink | `com.apple.MobileSMS.expressivesend.invisibleink` |
|
|
171
|
+
|
|
172
|
+
> Example: [message-effects.ts](./examples/message-effects.ts)
|
|
173
|
+
|
|
174
|
+
### Query Messages
|
|
125
175
|
|
|
126
176
|
```typescript
|
|
127
|
-
// Get
|
|
177
|
+
// Get a single message
|
|
178
|
+
const message = await sdk.messages.getMessage("message-guid");
|
|
179
|
+
|
|
180
|
+
// Query messages
|
|
128
181
|
const messages = await sdk.messages.getMessages({
|
|
129
|
-
chatGuid: "
|
|
182
|
+
chatGuid: "iMessage;-;+1234567890",
|
|
130
183
|
limit: 50,
|
|
131
184
|
offset: 0,
|
|
185
|
+
sort: "DESC", // DESC = newest first, ASC = oldest first
|
|
186
|
+
before: Date.now(),
|
|
187
|
+
after: Date.now() - 86400000, // Last 24 hours
|
|
132
188
|
});
|
|
133
189
|
|
|
134
|
-
//
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
190
|
+
// Search messages
|
|
191
|
+
const results = await sdk.messages.searchMessages({
|
|
192
|
+
query: "keyword",
|
|
193
|
+
chatGuid: "iMessage;-;+1234567890", // Optional
|
|
194
|
+
limit: 20,
|
|
139
195
|
});
|
|
140
196
|
|
|
141
|
-
|
|
197
|
+
// Get counts
|
|
198
|
+
const total = await sdk.messages.getMessageCount();
|
|
199
|
+
const sent = await sdk.messages.getSentMessageCount();
|
|
200
|
+
const updated = await sdk.messages.getUpdatedMessageCount();
|
|
142
201
|
```
|
|
143
202
|
|
|
144
|
-
###
|
|
203
|
+
### Unsend Messages
|
|
145
204
|
|
|
146
205
|
```typescript
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
editedMessage: "Updated text",
|
|
151
|
-
backwardsCompatibilityMessage: "Updated text",
|
|
206
|
+
await sdk.messages.unsendMessage({
|
|
207
|
+
messageGuid: "message-guid-to-unsend",
|
|
208
|
+
partIndex: 0, // Optional
|
|
152
209
|
});
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
> Example: [message-unsend.ts](./examples/message-unsend.ts)
|
|
213
|
+
|
|
214
|
+
### Send Tapbacks
|
|
153
215
|
|
|
154
|
-
|
|
216
|
+
```typescript
|
|
155
217
|
await sdk.messages.sendReaction({
|
|
156
|
-
chatGuid: "
|
|
157
|
-
messageGuid: "message-guid",
|
|
158
|
-
reaction: "love", //
|
|
159
|
-
partIndex: 0, // Optional
|
|
218
|
+
chatGuid: "iMessage;-;+1234567890",
|
|
219
|
+
messageGuid: "target-message-guid",
|
|
220
|
+
reaction: "love", // love, like, dislike, laugh, emphasize, question
|
|
221
|
+
partIndex: 0, // Optional
|
|
160
222
|
});
|
|
161
223
|
|
|
162
|
-
//
|
|
163
|
-
await sdk.messages.
|
|
164
|
-
|
|
224
|
+
// Remove a Tapback (prefix with -)
|
|
225
|
+
await sdk.messages.sendReaction({
|
|
226
|
+
chatGuid: "iMessage;-;+1234567890",
|
|
227
|
+
messageGuid: "target-message-guid",
|
|
228
|
+
reaction: "-love", // -love, -like, -dislike, -laugh, -emphasize, -question
|
|
165
229
|
});
|
|
166
230
|
```
|
|
167
231
|
|
|
168
|
-
|
|
232
|
+
> Example: [message-reaction.ts](./examples/message-reaction.ts)
|
|
233
|
+
|
|
234
|
+
### Other Message Operations
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
// Trigger message notification
|
|
238
|
+
await sdk.messages.notifyMessage("message-guid");
|
|
239
|
+
|
|
240
|
+
// Get embedded media
|
|
241
|
+
const media = await sdk.messages.getEmbeddedMedia("message-guid");
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Chats
|
|
247
|
+
|
|
248
|
+
> Examples: [chat-fetch.ts](./examples/chat-fetch.ts) | [chat-group.ts](./examples/chat-group.ts) | [message-typing.ts](./examples/message-typing.ts)
|
|
169
249
|
|
|
170
|
-
###
|
|
250
|
+
### Get Chats
|
|
171
251
|
|
|
172
252
|
```typescript
|
|
173
|
-
|
|
174
|
-
|
|
253
|
+
const chats = await sdk.chats.getChats({
|
|
254
|
+
withLastMessage: true, // Include last message
|
|
255
|
+
withArchived: false, // Include archived chats
|
|
256
|
+
offset: 0,
|
|
257
|
+
limit: 50,
|
|
258
|
+
});
|
|
175
259
|
|
|
176
|
-
// Get
|
|
260
|
+
// Get chat count
|
|
261
|
+
const count = await sdk.chats.getChatCount();
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Get Single Chat
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
177
267
|
const chat = await sdk.chats.getChat("chat-guid", {
|
|
178
268
|
with: ["participants", "lastMessage"],
|
|
179
269
|
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Create Chat
|
|
180
273
|
|
|
181
|
-
|
|
274
|
+
```typescript
|
|
182
275
|
const newChat = await sdk.chats.createChat({
|
|
183
276
|
addresses: ["+1234567890", "+0987654321"],
|
|
184
|
-
message: "Hello everyone!",
|
|
185
|
-
service: "iMessage", //
|
|
186
|
-
method: "private-api", //
|
|
277
|
+
message: "Hello everyone!", // Optional initial message
|
|
278
|
+
service: "iMessage", // "iMessage" or "SMS"
|
|
279
|
+
method: "private-api", // "apple-script" or "private-api"
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Chat Status
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
// Mark as read/unread
|
|
287
|
+
await sdk.chats.markChatRead("chat-guid");
|
|
288
|
+
await sdk.chats.markChatUnread("chat-guid");
|
|
289
|
+
|
|
290
|
+
// Delete chat
|
|
291
|
+
await sdk.chats.deleteChat("chat-guid");
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Typing Indicators
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
// Show "typing..."
|
|
298
|
+
await sdk.chats.startTyping("chat-guid");
|
|
299
|
+
|
|
300
|
+
// Stop showing
|
|
301
|
+
await sdk.chats.stopTyping("chat-guid");
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
> Example: [message-typing.ts](./examples/message-typing.ts)
|
|
305
|
+
|
|
306
|
+
### Get Chat Messages
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
const messages = await sdk.chats.getChatMessages("chat-guid", {
|
|
310
|
+
limit: 100,
|
|
311
|
+
offset: 0,
|
|
312
|
+
sort: "DESC",
|
|
313
|
+
before: Date.now(),
|
|
314
|
+
after: Date.now() - 86400000,
|
|
187
315
|
});
|
|
188
316
|
```
|
|
189
317
|
|
|
190
|
-
### Group
|
|
318
|
+
### Manage Group Chats
|
|
191
319
|
|
|
192
320
|
```typescript
|
|
193
|
-
//
|
|
321
|
+
// Rename group
|
|
194
322
|
await sdk.chats.updateChat("chat-guid", {
|
|
195
|
-
displayName: "
|
|
323
|
+
displayName: "New Group Name",
|
|
196
324
|
});
|
|
197
325
|
|
|
198
326
|
// Add participant
|
|
@@ -205,7 +333,7 @@ await sdk.chats.removeParticipant("chat-guid", "+1234567890");
|
|
|
205
333
|
await sdk.chats.leaveChat("chat-guid");
|
|
206
334
|
```
|
|
207
335
|
|
|
208
|
-
### Group
|
|
336
|
+
### Group Icon
|
|
209
337
|
|
|
210
338
|
```typescript
|
|
211
339
|
// Set group icon
|
|
@@ -218,699 +346,553 @@ const iconBuffer = await sdk.chats.getGroupIcon("chat-guid");
|
|
|
218
346
|
await sdk.chats.removeGroupIcon("chat-guid");
|
|
219
347
|
```
|
|
220
348
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
```typescript
|
|
224
|
-
// Mark as read/unread
|
|
225
|
-
await sdk.chats.markChatRead("chat-guid");
|
|
226
|
-
await sdk.chats.markChatUnread("chat-guid");
|
|
349
|
+
> Example: [chat-group.ts](./examples/chat-group.ts)
|
|
227
350
|
|
|
228
|
-
|
|
229
|
-
await sdk.chats.startTyping("chat-guid");
|
|
230
|
-
await sdk.chats.stopTyping("chat-guid");
|
|
351
|
+
---
|
|
231
352
|
|
|
232
|
-
|
|
233
|
-
const messages = await sdk.chats.getChatMessages("chat-guid", {
|
|
234
|
-
limit: 100,
|
|
235
|
-
offset: 0,
|
|
236
|
-
sort: "DESC",
|
|
237
|
-
});
|
|
238
|
-
```
|
|
353
|
+
## Attachments
|
|
239
354
|
|
|
240
|
-
|
|
355
|
+
> 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)
|
|
241
356
|
|
|
242
|
-
###
|
|
357
|
+
### Send Attachments
|
|
243
358
|
|
|
244
359
|
```typescript
|
|
245
|
-
// Send file attachment
|
|
246
360
|
const message = await sdk.attachments.sendAttachment({
|
|
247
|
-
chatGuid: "
|
|
361
|
+
chatGuid: "iMessage;-;+1234567890",
|
|
248
362
|
filePath: "/path/to/file.jpg",
|
|
249
363
|
fileName: "custom-name.jpg", // Optional
|
|
250
364
|
});
|
|
251
|
-
|
|
252
|
-
// Send sticker
|
|
253
|
-
await sdk.attachments.sendSticker({
|
|
254
|
-
chatGuid: "any;-;+1234567890",
|
|
255
|
-
filePath: "/path/to/sticker.png",
|
|
256
|
-
selectedMessageGuid: "message-to-reply-to", // Optional
|
|
257
|
-
});
|
|
258
365
|
```
|
|
259
366
|
|
|
260
|
-
###
|
|
261
|
-
|
|
262
|
-
Voice messages differ from regular audio attachments. Ensure the audio file path exists and use common formats like `.m4a` or `.mp3`. In the example script, you can also supply the path via the `AUDIO_FILE_PATH` environment variable.
|
|
367
|
+
### Send Audio Messages
|
|
263
368
|
|
|
264
369
|
```typescript
|
|
265
|
-
// Send voice message
|
|
266
370
|
const message = await sdk.attachments.sendAttachment({
|
|
267
|
-
chatGuid: "
|
|
268
|
-
filePath: "/path/to/audio.
|
|
371
|
+
chatGuid: "iMessage;-;+1234567890",
|
|
372
|
+
filePath: "/path/to/audio.m4a",
|
|
269
373
|
isAudioMessage: true,
|
|
270
374
|
});
|
|
271
|
-
|
|
272
|
-
// Detect and handle incoming audio messages
|
|
273
|
-
sdk.on("new-message", async (msg) => {
|
|
274
|
-
if (msg.isAudioMessage) {
|
|
275
|
-
const att = msg.attachments?.[0];
|
|
276
|
-
if (att) {
|
|
277
|
-
// Download original audio attachment
|
|
278
|
-
const audioBuffer = await sdk.attachments.downloadAttachment(att.guid, {
|
|
279
|
-
original: true,
|
|
280
|
-
});
|
|
281
|
-
// Save or process audioBuffer
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
});
|
|
285
375
|
```
|
|
286
376
|
|
|
287
|
-
|
|
377
|
+
> Example: [message-audio.ts](./examples/message-audio.ts)
|
|
288
378
|
|
|
289
|
-
|
|
290
|
-
// Get attachment details
|
|
291
|
-
const attachment = await sdk.attachments.getAttachment("attachment-guid");
|
|
379
|
+
### Send Stickers
|
|
292
380
|
|
|
293
|
-
|
|
294
|
-
|
|
381
|
+
```typescript
|
|
382
|
+
await sdk.attachments.sendSticker({
|
|
383
|
+
chatGuid: "iMessage;-;+1234567890",
|
|
384
|
+
filePath: "/path/to/sticker.png",
|
|
385
|
+
selectedMessageGuid: "message-to-stick-on", // Optional
|
|
386
|
+
});
|
|
295
387
|
```
|
|
296
388
|
|
|
297
|
-
|
|
389
|
+
> Example: [message-reply-sticker.ts](./examples/message-reply-sticker.ts)
|
|
298
390
|
|
|
299
|
-
###
|
|
391
|
+
### Get Attachment Info
|
|
300
392
|
|
|
301
393
|
```typescript
|
|
302
|
-
// Get
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
// Get contact card
|
|
306
|
-
const contactCard = await sdk.contacts.getContactCard("+1234567890");
|
|
307
|
-
|
|
308
|
-
// Share contact card
|
|
309
|
-
await sdk.contacts.shareContactCard("chat-guid");
|
|
394
|
+
// Get attachment details
|
|
395
|
+
const attachment = await sdk.attachments.getAttachment("attachment-guid");
|
|
310
396
|
|
|
311
|
-
//
|
|
312
|
-
const
|
|
397
|
+
// Get total count
|
|
398
|
+
const count = await sdk.attachments.getAttachmentCount();
|
|
313
399
|
```
|
|
314
400
|
|
|
315
|
-
###
|
|
401
|
+
### Download Attachments
|
|
316
402
|
|
|
317
403
|
```typescript
|
|
318
|
-
//
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
404
|
+
// Download attachment
|
|
405
|
+
const buffer = await sdk.attachments.downloadAttachment("attachment-guid", {
|
|
406
|
+
original: true, // Download original file
|
|
407
|
+
force: false, // Force re-download
|
|
408
|
+
width: 800, // Image width (for thumbnails)
|
|
409
|
+
height: 600, // Image height
|
|
410
|
+
quality: 80, // Image quality
|
|
323
411
|
});
|
|
324
412
|
|
|
325
|
-
//
|
|
326
|
-
const
|
|
327
|
-
"
|
|
328
|
-
"imessage"
|
|
413
|
+
// Download Live Photo video
|
|
414
|
+
const liveBuffer = await sdk.attachments.downloadAttachmentLive(
|
|
415
|
+
"attachment-guid"
|
|
329
416
|
);
|
|
330
417
|
|
|
331
|
-
// Get
|
|
332
|
-
const
|
|
418
|
+
// Get blurhash (for placeholders)
|
|
419
|
+
const blurhash = await sdk.attachments.getAttachmentBlurhash("attachment-guid");
|
|
333
420
|
```
|
|
334
421
|
|
|
335
|
-
|
|
422
|
+
> Example: [attachment-download.ts](./examples/attachment-download.ts)
|
|
336
423
|
|
|
337
|
-
|
|
424
|
+
---
|
|
338
425
|
|
|
339
|
-
|
|
426
|
+
## Contacts
|
|
340
427
|
|
|
341
|
-
|
|
428
|
+
> Example: [contact-list.ts](./examples/contact-list.ts)
|
|
342
429
|
|
|
343
|
-
|
|
430
|
+
### Get Contacts
|
|
344
431
|
|
|
345
432
|
```typescript
|
|
346
|
-
sdk.
|
|
347
|
-
console.log("SDK connected and ready");
|
|
348
|
-
});
|
|
433
|
+
const contacts = await sdk.contacts.getContacts();
|
|
349
434
|
```
|
|
350
435
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
Emitted when Socket.IO connection is established.
|
|
436
|
+
### Get Contact Card
|
|
354
437
|
|
|
355
438
|
```typescript
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
});
|
|
439
|
+
// Get by phone or email
|
|
440
|
+
const card = await sdk.contacts.getContactCard("+1234567890");
|
|
359
441
|
```
|
|
360
442
|
|
|
361
|
-
|
|
443
|
+
---
|
|
362
444
|
|
|
363
|
-
|
|
445
|
+
## Handles
|
|
364
446
|
|
|
365
|
-
|
|
366
|
-
sdk.on("disconnect", () => {
|
|
367
|
-
console.log("Socket.IO disconnected");
|
|
368
|
-
});
|
|
369
|
-
```
|
|
447
|
+
> Examples: [service-check.ts](./examples/service-check.ts) | [handle-query.ts](./examples/handle-query.ts)
|
|
370
448
|
|
|
371
|
-
|
|
449
|
+
A Handle represents a messaging address (phone number or email).
|
|
372
450
|
|
|
373
|
-
|
|
451
|
+
### Query Handles
|
|
374
452
|
|
|
375
453
|
```typescript
|
|
376
|
-
|
|
377
|
-
|
|
454
|
+
// Query handles
|
|
455
|
+
const result = await sdk.handles.queryHandles({
|
|
456
|
+
address: "+1234567890", // Optional, filter by address
|
|
457
|
+
with: ["chats"], // Optional, include related chats
|
|
458
|
+
offset: 0,
|
|
459
|
+
limit: 50,
|
|
378
460
|
});
|
|
379
|
-
```
|
|
380
461
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
#### `new-message`
|
|
384
|
-
|
|
385
|
-
Emitted when a new message is received or sent.
|
|
462
|
+
// Get single handle
|
|
463
|
+
const handle = await sdk.handles.getHandle("handle-guid");
|
|
386
464
|
|
|
387
|
-
|
|
388
|
-
sdk.
|
|
389
|
-
console.log("New message received:", message.text);
|
|
390
|
-
console.log("From:", message.handle?.address);
|
|
391
|
-
console.log("GUID:", message.guid);
|
|
392
|
-
});
|
|
465
|
+
// Get total count
|
|
466
|
+
const count = await sdk.handles.getHandleCount();
|
|
393
467
|
```
|
|
394
468
|
|
|
395
|
-
|
|
469
|
+
### Check Service Availability
|
|
396
470
|
|
|
397
|
-
|
|
471
|
+
Check if a phone/email supports iMessage or FaceTime:
|
|
398
472
|
|
|
399
473
|
```typescript
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
474
|
+
// First parameter is the address (phone or email), not handle guid
|
|
475
|
+
const hasIMessage = await sdk.handles.getHandleAvailability(
|
|
476
|
+
"+1234567890",
|
|
477
|
+
"imessage"
|
|
478
|
+
);
|
|
479
|
+
const hasFaceTime = await sdk.handles.getHandleAvailability(
|
|
480
|
+
"+1234567890",
|
|
481
|
+
"facetime"
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
// Choose service based on availability
|
|
485
|
+
const chatGuid = hasIMessage ? `iMessage;-;+1234567890` : `SMS;-;+1234567890`;
|
|
408
486
|
```
|
|
409
487
|
|
|
410
|
-
|
|
488
|
+
> Example: [service-check.ts](./examples/service-check.ts)
|
|
411
489
|
|
|
412
|
-
|
|
490
|
+
### Get Focus Status
|
|
413
491
|
|
|
414
492
|
```typescript
|
|
415
|
-
sdk.
|
|
416
|
-
console.error("Failed to send message:", data);
|
|
417
|
-
});
|
|
493
|
+
const focusStatus = await sdk.handles.getHandleFocusStatus("handle-guid");
|
|
418
494
|
```
|
|
419
495
|
|
|
420
|
-
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
## Server
|
|
421
499
|
|
|
422
|
-
|
|
500
|
+
> Examples: [message-stats.ts](./examples/message-stats.ts) | [server-info.ts](./examples/server-info.ts)
|
|
423
501
|
|
|
424
|
-
|
|
502
|
+
### Get Server Info
|
|
425
503
|
|
|
426
504
|
```typescript
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
505
|
+
const info = await sdk.server.getServerInfo();
|
|
506
|
+
// {
|
|
507
|
+
// os_version: "14.0",
|
|
508
|
+
// server_version: "1.0.0",
|
|
509
|
+
// private_api: true,
|
|
510
|
+
// helper_connected: true,
|
|
511
|
+
// detected_icloud: "user@icloud.com",
|
|
512
|
+
// ...
|
|
513
|
+
// }
|
|
430
514
|
```
|
|
431
515
|
|
|
432
|
-
###
|
|
516
|
+
### Message Statistics
|
|
433
517
|
|
|
434
|
-
|
|
518
|
+
```typescript
|
|
519
|
+
const stats = await sdk.server.getMessageStats();
|
|
520
|
+
// {
|
|
521
|
+
// total: 12345,
|
|
522
|
+
// sent: 5000,
|
|
523
|
+
// received: 7345,
|
|
524
|
+
// last24h: 50,
|
|
525
|
+
// last7d: 300,
|
|
526
|
+
// last30d: 1000,
|
|
527
|
+
// }
|
|
528
|
+
```
|
|
435
529
|
|
|
436
|
-
|
|
530
|
+
### Media Statistics
|
|
437
531
|
|
|
438
532
|
```typescript
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
});
|
|
442
|
-
```
|
|
533
|
+
// All media stats
|
|
534
|
+
const mediaStats = await sdk.server.getMediaStatistics();
|
|
443
535
|
|
|
444
|
-
|
|
536
|
+
// Per-chat media stats
|
|
537
|
+
const chatMediaStats = await sdk.server.getMediaStatisticsByChat();
|
|
538
|
+
```
|
|
445
539
|
|
|
446
|
-
|
|
540
|
+
### Server Logs
|
|
447
541
|
|
|
448
542
|
```typescript
|
|
449
|
-
sdk.
|
|
450
|
-
console.log(`Participant added to ${data.chat.displayName}`);
|
|
451
|
-
});
|
|
543
|
+
const logs = await sdk.server.getServerLogs(100); // Get last 100 logs
|
|
452
544
|
```
|
|
453
545
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
Emitted when someone is removed from a group chat.
|
|
546
|
+
### Alert Management
|
|
457
547
|
|
|
458
548
|
```typescript
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
549
|
+
// Get alerts
|
|
550
|
+
const alerts = await sdk.server.getAlerts();
|
|
551
|
+
|
|
552
|
+
// Mark alerts as read
|
|
553
|
+
await sdk.server.markAlertAsRead(["alert-id-1", "alert-id-2"]);
|
|
462
554
|
```
|
|
463
555
|
|
|
464
|
-
|
|
556
|
+
> Example: [server-info.ts](./examples/server-info.ts)
|
|
465
557
|
|
|
466
|
-
|
|
558
|
+
---
|
|
467
559
|
|
|
468
|
-
|
|
469
|
-
sdk.on("participant-left", (data) => {
|
|
470
|
-
console.log(`Participant left ${data.chat.displayName}`);
|
|
471
|
-
});
|
|
472
|
-
```
|
|
560
|
+
## Polls
|
|
473
561
|
|
|
474
|
-
|
|
562
|
+
> Examples: [poll-create.ts](./examples/poll-create.ts) | [poll-add-option.ts](./examples/poll-add-option.ts)
|
|
475
563
|
|
|
476
|
-
|
|
564
|
+
### Create Polls
|
|
477
565
|
|
|
478
566
|
```typescript
|
|
479
|
-
sdk.
|
|
480
|
-
|
|
567
|
+
const pollMessage = await sdk.polls.create({
|
|
568
|
+
chatGuid: "iMessage;-;+1234567890",
|
|
569
|
+
title: "What should we do?", // Optional
|
|
570
|
+
options: ["Option A", "Option B", "Option C"],
|
|
481
571
|
});
|
|
572
|
+
|
|
573
|
+
console.log("Poll GUID:", pollMessage.guid);
|
|
482
574
|
```
|
|
483
575
|
|
|
484
|
-
|
|
576
|
+
> Example: [poll-create.ts](./examples/poll-create.ts)
|
|
485
577
|
|
|
486
|
-
|
|
578
|
+
### Add Poll Options
|
|
487
579
|
|
|
488
580
|
```typescript
|
|
489
|
-
sdk.
|
|
490
|
-
|
|
581
|
+
await sdk.polls.addOption({
|
|
582
|
+
chatGuid: "iMessage;-;+1234567890",
|
|
583
|
+
pollMessageGuid: "poll-message-guid",
|
|
584
|
+
optionText: "New Option D",
|
|
491
585
|
});
|
|
492
586
|
```
|
|
493
587
|
|
|
494
|
-
|
|
588
|
+
> Example: [poll-add-option.ts](./examples/poll-add-option.ts)
|
|
495
589
|
|
|
496
|
-
|
|
590
|
+
### Parse Poll Messages
|
|
497
591
|
|
|
498
|
-
|
|
592
|
+
Use the `poll-utils` helper functions to parse and display poll messages:
|
|
499
593
|
|
|
500
594
|
```typescript
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
595
|
+
import {
|
|
596
|
+
isPollMessage,
|
|
597
|
+
isPollVote,
|
|
598
|
+
parsePollDefinition,
|
|
599
|
+
parsePollVotes,
|
|
600
|
+
getPollSummary,
|
|
601
|
+
getOptionTextById,
|
|
602
|
+
} from "@photon-ai/advanced-imessage-kit/lib/poll-utils";
|
|
507
603
|
|
|
508
|
-
|
|
604
|
+
sdk.on("new-message", (message) => {
|
|
605
|
+
if (isPollMessage(message)) {
|
|
606
|
+
if (isPollVote(message)) {
|
|
607
|
+
// Parse vote data
|
|
608
|
+
const voteData = parsePollVotes(message);
|
|
609
|
+
console.log("Votes:", voteData?.votes);
|
|
610
|
+
|
|
611
|
+
// Get option text for each vote
|
|
612
|
+
voteData?.votes.forEach((vote) => {
|
|
613
|
+
const optionText = getOptionTextById(vote.voteOptionIdentifier);
|
|
614
|
+
console.log(`${vote.participantHandle} voted for "${optionText}"`);
|
|
615
|
+
});
|
|
616
|
+
} else {
|
|
617
|
+
// Parse poll definition
|
|
618
|
+
const pollData = parsePollDefinition(message);
|
|
619
|
+
console.log("Poll title:", pollData?.title);
|
|
620
|
+
console.log("Options:", pollData?.options);
|
|
621
|
+
}
|
|
509
622
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
623
|
+
// Or get a formatted summary
|
|
624
|
+
console.log(getPollSummary(message));
|
|
625
|
+
}
|
|
513
626
|
});
|
|
514
627
|
```
|
|
515
628
|
|
|
516
|
-
|
|
629
|
+
**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.
|
|
630
|
+
|
|
631
|
+
---
|
|
632
|
+
|
|
633
|
+
## iCloud _(Work in Progress)_
|
|
517
634
|
|
|
518
|
-
|
|
635
|
+
> Example: [findmy-friends.ts](./examples/findmy-friends.ts)
|
|
519
636
|
|
|
520
|
-
|
|
637
|
+
### Find My Friends
|
|
521
638
|
|
|
522
639
|
```typescript
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
640
|
+
// Get friends' locations
|
|
641
|
+
const friends = await sdk.icloud.getFindMyFriends();
|
|
642
|
+
|
|
643
|
+
// Refresh location data
|
|
644
|
+
await sdk.icloud.refreshFindMyFriends();
|
|
526
645
|
```
|
|
527
646
|
|
|
528
|
-
|
|
647
|
+
> Example: [findmy-friends.ts](./examples/findmy-friends.ts)
|
|
529
648
|
|
|
530
|
-
|
|
649
|
+
---
|
|
531
650
|
|
|
532
|
-
|
|
651
|
+
## Real-time Events
|
|
533
652
|
|
|
534
|
-
|
|
535
|
-
sdk.on("scheduled-message-sent", (data) => {
|
|
536
|
-
console.log("Scheduled message sent:", data);
|
|
537
|
-
});
|
|
538
|
-
```
|
|
653
|
+
> Examples: [listen-simple.ts](./examples/listen-simple.ts) | [listen-advanced.ts](./examples/listen-advanced.ts) | [auto-reply-hey.ts](./examples/auto-reply-hey.ts)
|
|
539
654
|
|
|
540
|
-
|
|
655
|
+
The SDK receives real-time events from the server via Socket.IO.
|
|
541
656
|
|
|
542
|
-
|
|
657
|
+
### Connection Events
|
|
543
658
|
|
|
544
659
|
```typescript
|
|
545
|
-
sdk.on("
|
|
546
|
-
console.
|
|
660
|
+
sdk.on("ready", () => {
|
|
661
|
+
console.log("SDK connected and ready");
|
|
547
662
|
});
|
|
548
|
-
```
|
|
549
|
-
|
|
550
|
-
#### `scheduled-message-created`
|
|
551
663
|
|
|
552
|
-
|
|
664
|
+
sdk.on("disconnect", () => {
|
|
665
|
+
console.log("Disconnected");
|
|
666
|
+
});
|
|
553
667
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
console.log("Scheduled message created:", data);
|
|
668
|
+
sdk.on("error", (error) => {
|
|
669
|
+
console.error("Error:", error);
|
|
557
670
|
});
|
|
558
671
|
```
|
|
559
672
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
Emitted when a scheduled message is updated.
|
|
673
|
+
### Message Events
|
|
563
674
|
|
|
564
675
|
```typescript
|
|
565
|
-
|
|
566
|
-
|
|
676
|
+
// New message
|
|
677
|
+
sdk.on("new-message", (message) => {
|
|
678
|
+
console.log("New message:", message.text);
|
|
679
|
+
console.log("From:", message.handle?.address);
|
|
680
|
+
console.log("From me:", message.isFromMe);
|
|
567
681
|
});
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
#### `scheduled-message-deleted`
|
|
571
682
|
|
|
572
|
-
|
|
683
|
+
// Message status update (delivered, read, etc.)
|
|
684
|
+
sdk.on("updated-message", (message) => {
|
|
685
|
+
if (message.dateRead) console.log("Message read");
|
|
686
|
+
else if (message.dateDelivered) console.log("Message delivered");
|
|
687
|
+
});
|
|
573
688
|
|
|
574
|
-
|
|
575
|
-
sdk.on("
|
|
576
|
-
console.
|
|
689
|
+
// Send failed
|
|
690
|
+
sdk.on("message-send-error", (data) => {
|
|
691
|
+
console.error("Send failed:", data);
|
|
577
692
|
});
|
|
578
693
|
```
|
|
579
694
|
|
|
580
|
-
###
|
|
695
|
+
### Chat Events
|
|
581
696
|
|
|
582
697
|
```typescript
|
|
583
|
-
//
|
|
584
|
-
sdk.
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
sdk.removeAllListeners("new-message");
|
|
698
|
+
// Chat read status changed
|
|
699
|
+
sdk.on("chat-read-status-changed", ({ chatGuid, read }) => {
|
|
700
|
+
console.log(`Chat ${chatGuid} marked as ${read ? "read" : "unread"}`);
|
|
701
|
+
});
|
|
588
702
|
```
|
|
589
703
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
### FaceTime Integration
|
|
704
|
+
### Typing Indicators
|
|
593
705
|
|
|
594
706
|
```typescript
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
console.log("FaceTime link:", link);
|
|
598
|
-
|
|
599
|
-
// Listen for FaceTime status changes
|
|
600
|
-
sdk.on("ft-call-status-changed", (data) => {
|
|
601
|
-
console.log("FaceTime status:", data.status);
|
|
707
|
+
sdk.on("typing-indicator", ({ display, guid }) => {
|
|
708
|
+
console.log(`${guid} ${display ? "is typing" : "stopped typing"}`);
|
|
602
709
|
});
|
|
603
710
|
```
|
|
604
711
|
|
|
605
|
-
###
|
|
712
|
+
### Group Events
|
|
606
713
|
|
|
607
714
|
```typescript
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
// Refresh data
|
|
612
|
-
await sdk.icloud.refreshFindMyFriends();
|
|
613
|
-
```
|
|
715
|
+
sdk.on("group-name-change", (message) => {
|
|
716
|
+
console.log("Group renamed to:", message.groupTitle);
|
|
717
|
+
});
|
|
614
718
|
|
|
615
|
-
|
|
719
|
+
sdk.on("participant-added", (message) => {
|
|
720
|
+
console.log("Someone joined the group");
|
|
721
|
+
});
|
|
616
722
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
const scheduled = await sdk.scheduledMessages.createScheduledMessage({
|
|
620
|
-
chatGuid: "any;-;+1234567890",
|
|
621
|
-
message: "This message was scheduled!",
|
|
622
|
-
scheduledFor: new Date(Date.now() + 60000), // 1 minute from now
|
|
623
|
-
schedule: { type: "once" },
|
|
723
|
+
sdk.on("participant-removed", (message) => {
|
|
724
|
+
console.log("Someone was removed from the group");
|
|
624
725
|
});
|
|
625
726
|
|
|
626
|
-
|
|
627
|
-
|
|
727
|
+
sdk.on("participant-left", (message) => {
|
|
728
|
+
console.log("Someone left the group");
|
|
729
|
+
});
|
|
628
730
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
message: "Updated message",
|
|
731
|
+
sdk.on("group-icon-changed", (message) => {
|
|
732
|
+
console.log("Group icon changed");
|
|
632
733
|
});
|
|
633
734
|
|
|
634
|
-
|
|
635
|
-
|
|
735
|
+
sdk.on("group-icon-removed", (message) => {
|
|
736
|
+
console.log("Group icon removed");
|
|
737
|
+
});
|
|
636
738
|
```
|
|
637
739
|
|
|
638
|
-
###
|
|
740
|
+
### Find My Friends Events _(WIP)_
|
|
639
741
|
|
|
640
742
|
```typescript
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
// Get message statistics
|
|
645
|
-
const stats = await sdk.server.getMessageStats();
|
|
646
|
-
|
|
647
|
-
// Get server logs
|
|
648
|
-
const logs = await sdk.server.getServerLogs(100);
|
|
649
|
-
|
|
650
|
-
// Get alerts
|
|
651
|
-
const alerts = await sdk.server.getAlerts();
|
|
652
|
-
|
|
653
|
-
// Mark alerts as read
|
|
654
|
-
await sdk.server.markAlertAsRead(["alert-id-1", "alert-id-2"]);
|
|
743
|
+
sdk.on("new-findmy-location", (location) => {
|
|
744
|
+
console.log(`${location.handle} location updated:`, location.coordinates);
|
|
745
|
+
});
|
|
655
746
|
```
|
|
656
747
|
|
|
657
|
-
|
|
748
|
+
### Remove Event Listeners
|
|
658
749
|
|
|
659
750
|
```typescript
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
chatGuid: "invalid-guid",
|
|
663
|
-
message: "Test",
|
|
664
|
-
});
|
|
665
|
-
} catch (error) {
|
|
666
|
-
if (error.response?.status === 404) {
|
|
667
|
-
console.error("Chat not found");
|
|
668
|
-
} else {
|
|
669
|
-
console.error("Send failed:", error.message);
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
```
|
|
751
|
+
const handler = (message) => console.log(message);
|
|
752
|
+
sdk.on("new-message", handler);
|
|
673
753
|
|
|
674
|
-
|
|
754
|
+
// Remove specific listener
|
|
755
|
+
sdk.off("new-message", handler);
|
|
675
756
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
serverUrl?: string; // Your subdomain: '{your-subdomain}.imsgd.photon.codes'
|
|
679
|
-
apiKey?: string; // Optional API key for authenticated backends
|
|
680
|
-
logLevel?: "debug" | "info" | "warn" | "error"; // Default: 'info'
|
|
681
|
-
}
|
|
757
|
+
// Remove all listeners
|
|
758
|
+
sdk.removeAllListeners("new-message");
|
|
682
759
|
```
|
|
683
760
|
|
|
761
|
+
---
|
|
762
|
+
|
|
684
763
|
## Best Practices
|
|
685
764
|
|
|
686
765
|
### Resource Management
|
|
687
766
|
|
|
688
767
|
```typescript
|
|
689
|
-
//
|
|
768
|
+
// Graceful shutdown
|
|
690
769
|
process.on("SIGINT", async () => {
|
|
691
770
|
await sdk.close();
|
|
692
771
|
process.exit(0);
|
|
693
772
|
});
|
|
694
773
|
```
|
|
695
774
|
|
|
696
|
-
###
|
|
697
|
-
|
|
698
|
-
```typescript
|
|
699
|
-
// Use specific event handlers
|
|
700
|
-
sdk.on("new-message", handleNewMessage);
|
|
701
|
-
sdk.on("error", handleError);
|
|
702
|
-
|
|
703
|
-
// Remove listeners when needed
|
|
704
|
-
sdk.off("new-message", handleNewMessage);
|
|
705
|
-
```
|
|
775
|
+
### Message Deduplication
|
|
706
776
|
|
|
707
|
-
|
|
777
|
+
The SDK includes built-in message deduplication to prevent processing duplicates during network instability:
|
|
708
778
|
|
|
709
779
|
```typescript
|
|
710
|
-
//
|
|
711
|
-
const messages = await sdk.messages.getMessages({
|
|
712
|
-
chatGuid: "any;-;+1234567890",
|
|
713
|
-
limit: 100,
|
|
714
|
-
offset: 0,
|
|
715
|
-
});
|
|
716
|
-
|
|
717
|
-
// Clear processed message records (prevents memory leaks)
|
|
780
|
+
// Clear processed messages (prevent memory leaks)
|
|
718
781
|
sdk.clearProcessedMessages(1000);
|
|
719
782
|
|
|
720
783
|
// Get processed message count
|
|
721
|
-
const
|
|
722
|
-
```
|
|
723
|
-
|
|
724
|
-
## Examples
|
|
725
|
-
|
|
726
|
-
The SDK includes comprehensive examples in the `examples/` directory. All examples can be run using Bun:
|
|
727
|
-
|
|
728
|
-
### Basic Examples
|
|
729
|
-
|
|
730
|
-
#### `demo-basic.ts` - Listen for Messages
|
|
731
|
-
|
|
732
|
-
Simple message listener demonstrating event handling.
|
|
733
|
-
|
|
734
|
-
```bash
|
|
735
|
-
bun run examples/demo-basic.ts
|
|
784
|
+
const count = sdk.getProcessedMessageCount();
|
|
736
785
|
```
|
|
737
786
|
|
|
738
|
-
|
|
787
|
+
### Error Handling
|
|
739
788
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
#### `message-audio.ts` - Send Voice Messages
|
|
755
|
-
|
|
756
|
-
Send voice messages (audio attachments with special handling).
|
|
757
|
-
|
|
758
|
-
```bash
|
|
759
|
-
CHAT_GUID="+1234567890" AUDIO_FILE_PATH="/path/to/audio.m4a" bun run examples/message-audio.ts
|
|
760
|
-
```
|
|
761
|
-
|
|
762
|
-
### Advanced Examples
|
|
763
|
-
|
|
764
|
-
#### `message-reaction.ts` - Reactions (Tapbacks)
|
|
765
|
-
|
|
766
|
-
Add and remove reactions to messages.
|
|
767
|
-
|
|
768
|
-
```bash
|
|
769
|
-
CHAT_GUID="chat-guid" MESSAGE_GUID="message-guid" bun run examples/message-reaction.ts
|
|
770
|
-
```
|
|
771
|
-
|
|
772
|
-
#### `message-edit.ts` - Edit Messages
|
|
773
|
-
|
|
774
|
-
Edit a sent message. Requires macOS Ventura (13.0) or newer and Private API.
|
|
775
|
-
|
|
776
|
-
```bash
|
|
777
|
-
CHAT_GUID="chat-guid" bun run examples/message-edit.ts
|
|
778
|
-
```
|
|
779
|
-
|
|
780
|
-
#### `message-unsend.ts` - Unsend Messages
|
|
781
|
-
|
|
782
|
-
Unsend a message within 2 minutes of sending. Requires macOS Ventura (13.0) or newer and Private API.
|
|
783
|
-
|
|
784
|
-
```bash
|
|
785
|
-
CHAT_GUID="chat-guid" bun run examples/message-unsend.ts
|
|
786
|
-
```
|
|
787
|
-
|
|
788
|
-
#### `message-typing.ts` - Typing Indicators
|
|
789
|
-
|
|
790
|
-
Start and stop typing indicators in a chat. Requires Private API.
|
|
791
|
-
|
|
792
|
-
```bash
|
|
793
|
-
CHAT_GUID="chat-guid" bun run examples/message-typing.ts
|
|
794
|
-
```
|
|
795
|
-
|
|
796
|
-
#### `message-contact-card.ts` - Share Contact Cards
|
|
797
|
-
|
|
798
|
-
Share contact cards in chats. Requires macOS Big Sur (11.0) or newer and Private API.
|
|
799
|
-
|
|
800
|
-
```bash
|
|
801
|
-
CHAT_GUID="chat-guid" CONTACT_ADDRESS="email-or-phone" bun run examples/message-contact-card.ts
|
|
802
|
-
```
|
|
803
|
-
|
|
804
|
-
#### `message-reply-sticker.ts` - Send Stickers
|
|
805
|
-
|
|
806
|
-
Send stickers and multipart messages. Requires Private API.
|
|
807
|
-
|
|
808
|
-
```bash
|
|
809
|
-
CHAT_GUID="chat-guid" STICKER_PATH="path/to/image.jpg" bun run examples/message-reply-sticker.ts
|
|
810
|
-
```
|
|
811
|
-
|
|
812
|
-
#### `message-effects.ts` - Message Effects
|
|
813
|
-
|
|
814
|
-
Send messages with visual effects (confetti, fireworks, balloons, etc.). Requires Private API.
|
|
815
|
-
|
|
816
|
-
```bash
|
|
817
|
-
CHAT_GUID="chat-guid" bun run examples/message-effects.ts
|
|
818
|
-
```
|
|
819
|
-
|
|
820
|
-
#### `message-reply.ts` - Reply to Messages
|
|
821
|
-
|
|
822
|
-
Reply to a specific message in a chat.
|
|
823
|
-
|
|
824
|
-
```bash
|
|
825
|
-
CHAT_GUID="chat-guid" MESSAGE_GUID="message-guid" bun run examples/message-reply.ts
|
|
826
|
-
```
|
|
827
|
-
|
|
828
|
-
#### `chat-fetch.ts` - Fetch Chats
|
|
829
|
-
|
|
830
|
-
Retrieve and filter chats from the database.
|
|
831
|
-
|
|
832
|
-
```bash
|
|
833
|
-
bun run examples/chat-fetch.ts
|
|
834
|
-
```
|
|
835
|
-
|
|
836
|
-
#### `chat-group.ts` - Group Chat Management
|
|
837
|
-
|
|
838
|
-
List and monitor group chats, track membership changes.
|
|
839
|
-
|
|
840
|
-
```bash
|
|
841
|
-
bun run examples/chat-group.ts
|
|
789
|
+
```typescript
|
|
790
|
+
try {
|
|
791
|
+
await sdk.messages.sendMessage({
|
|
792
|
+
chatGuid: "invalid-guid",
|
|
793
|
+
message: "test",
|
|
794
|
+
});
|
|
795
|
+
} catch (error) {
|
|
796
|
+
if (error.response?.status === 404) {
|
|
797
|
+
console.error("Chat not found");
|
|
798
|
+
} else {
|
|
799
|
+
console.error("Send failed:", error.message);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
842
802
|
```
|
|
843
803
|
|
|
844
|
-
|
|
804
|
+
### Auto-create Chats
|
|
845
805
|
|
|
846
|
-
|
|
806
|
+
When sending to a contact you've never messaged before, the SDK automatically creates the chat:
|
|
847
807
|
|
|
848
|
-
```
|
|
849
|
-
|
|
808
|
+
```typescript
|
|
809
|
+
// Works even without existing chat history
|
|
810
|
+
await sdk.messages.sendMessage({
|
|
811
|
+
chatGuid: "any;-;+1234567890",
|
|
812
|
+
message: "Hi, this is John",
|
|
813
|
+
});
|
|
814
|
+
// SDK detects the chat doesn't exist, creates it, then sends
|
|
850
815
|
```
|
|
851
816
|
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
View message statistics, chat activity, and analytics.
|
|
855
|
-
|
|
856
|
-
```bash
|
|
857
|
-
bun run examples/message-stats.ts
|
|
858
|
-
```
|
|
817
|
+
---
|
|
859
818
|
|
|
860
|
-
|
|
819
|
+
## Examples
|
|
861
820
|
|
|
862
|
-
|
|
821
|
+
Run any example with Bun:
|
|
863
822
|
|
|
864
823
|
```bash
|
|
865
|
-
|
|
824
|
+
bun run examples/<filename>.ts
|
|
866
825
|
```
|
|
867
826
|
|
|
868
|
-
|
|
827
|
+
### Getting Started
|
|
869
828
|
|
|
870
|
-
|
|
829
|
+
| File | Description |
|
|
830
|
+
| --------------------------------------------------------- | -------------------------------------- |
|
|
831
|
+
| [listen-simple.ts](./examples/listen-simple.ts) | Listen with formatted output |
|
|
832
|
+
| [listen-advanced.ts](./examples/listen-advanced.ts) | Listen with full JSON and startup info |
|
|
833
|
+
| [message-send.ts](./examples/message-send.ts) | Send text messages |
|
|
834
|
+
| [message-attachment.ts](./examples/message-attachment.ts) | Send attachments |
|
|
835
|
+
| [message-audio.ts](./examples/message-audio.ts) | Send audio messages |
|
|
871
836
|
|
|
872
|
-
|
|
873
|
-
bun run examples/facetime-link.ts
|
|
874
|
-
```
|
|
837
|
+
### Message Operations
|
|
875
838
|
|
|
876
|
-
|
|
839
|
+
| File | Description |
|
|
840
|
+
| ----------------------------------------------------- | ----------------- |
|
|
841
|
+
| [message-reply.ts](./examples/message-reply.ts) | Reply to messages |
|
|
842
|
+
| [message-unsend.ts](./examples/message-unsend.ts) | Unsend messages |
|
|
843
|
+
| [message-reaction.ts](./examples/message-reaction.ts) | Send Tapbacks |
|
|
844
|
+
| [message-effects.ts](./examples/message-effects.ts) | Message effects |
|
|
845
|
+
| [message-search.ts](./examples/message-search.ts) | Search messages |
|
|
877
846
|
|
|
878
|
-
|
|
847
|
+
### Chats & Groups
|
|
879
848
|
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
849
|
+
| File | Description |
|
|
850
|
+
| ------------------------------------------------- | ----------------- |
|
|
851
|
+
| [chat-fetch.ts](./examples/chat-fetch.ts) | Get chat list |
|
|
852
|
+
| [chat-group.ts](./examples/chat-group.ts) | Manage groups |
|
|
853
|
+
| [message-typing.ts](./examples/message-typing.ts) | Typing indicators |
|
|
883
854
|
|
|
884
|
-
|
|
855
|
+
### Contacts & Services
|
|
885
856
|
|
|
886
|
-
|
|
857
|
+
| File | Description |
|
|
858
|
+
| --------------------------------------------------------------- | ----------------------------- |
|
|
859
|
+
| [contact-list.ts](./examples/contact-list.ts) | Get contacts |
|
|
860
|
+
| [service-check.ts](./examples/service-check.ts) | Check iMessage availability |
|
|
861
|
+
| [message-service-check.ts](./examples/message-service-check.ts) | Monitor message service types |
|
|
887
862
|
|
|
888
|
-
|
|
889
|
-
bun run examples/contact-list.ts
|
|
890
|
-
```
|
|
863
|
+
### Attachments & Media
|
|
891
864
|
|
|
892
|
-
|
|
865
|
+
| File | Description |
|
|
866
|
+
| --------------------------------------------------------------- | -------------------- |
|
|
867
|
+
| [attachment-download.ts](./examples/attachment-download.ts) | Download attachments |
|
|
868
|
+
| [message-reply-sticker.ts](./examples/message-reply-sticker.ts) | Send stickers |
|
|
893
869
|
|
|
894
|
-
|
|
870
|
+
### Polls
|
|
895
871
|
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
872
|
+
| File | Description |
|
|
873
|
+
| --------------------------------------------------- | ---------------- |
|
|
874
|
+
| [poll-create.ts](./examples/poll-create.ts) | Create polls |
|
|
875
|
+
| [poll-add-option.ts](./examples/poll-add-option.ts) | Add poll options |
|
|
899
876
|
|
|
900
|
-
|
|
877
|
+
### Server & Advanced
|
|
901
878
|
|
|
902
|
-
|
|
879
|
+
| File | Description |
|
|
880
|
+
| ------------------------------------------------- | ----------------------- |
|
|
881
|
+
| [server-info.ts](./examples/server-info.ts) | Server info and logs |
|
|
882
|
+
| [message-stats.ts](./examples/message-stats.ts) | Message statistics |
|
|
883
|
+
| [findmy-friends.ts](./examples/findmy-friends.ts) | Find My Friends _(WIP)_ |
|
|
884
|
+
| [auto-reply-hey.ts](./examples/auto-reply-hey.ts) | Auto reply bot |
|
|
903
885
|
|
|
904
|
-
|
|
905
|
-
bun run examples/auto-reply-hey.ts
|
|
906
|
-
```
|
|
886
|
+
---
|
|
907
887
|
|
|
908
888
|
## LLMs
|
|
909
889
|
|
|
910
|
-
|
|
890
|
+
Download `llms.txt` for language model context:
|
|
911
891
|
|
|
912
892
|
- [Download llms.txt](./llms.txt)
|
|
913
893
|
|
|
894
|
+
---
|
|
895
|
+
|
|
914
896
|
## License
|
|
915
897
|
|
|
916
898
|
MIT License
|