@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/dist/index.d.ts
CHANGED
|
@@ -148,6 +148,7 @@ type MessageResponse = {
|
|
|
148
148
|
partCount?: number | null;
|
|
149
149
|
payloadData?: NodeJS.Dict<any>[];
|
|
150
150
|
hasPayloadData?: boolean;
|
|
151
|
+
isPoll?: boolean;
|
|
151
152
|
wasDeliveredQuietly?: boolean;
|
|
152
153
|
didNotifyRecipient?: boolean;
|
|
153
154
|
shareStatus?: number | null;
|
|
@@ -326,11 +327,59 @@ interface TypedEventEmitter {
|
|
|
326
327
|
removeListener(event: string | symbol, listener: (...args: unknown[]) => void): this;
|
|
327
328
|
}
|
|
328
329
|
|
|
330
|
+
interface CreatePollOptions {
|
|
331
|
+
chatGuid: string;
|
|
332
|
+
title?: string;
|
|
333
|
+
options: string[];
|
|
334
|
+
}
|
|
335
|
+
interface VotePollOptions {
|
|
336
|
+
chatGuid: string;
|
|
337
|
+
pollMessageGuid: string;
|
|
338
|
+
optionIdentifier: string;
|
|
339
|
+
}
|
|
340
|
+
interface AddPollOptionOptions {
|
|
341
|
+
chatGuid: string;
|
|
342
|
+
pollMessageGuid: string;
|
|
343
|
+
optionText: string;
|
|
344
|
+
}
|
|
345
|
+
interface PollOption {
|
|
346
|
+
optionIdentifier: string;
|
|
347
|
+
text: string;
|
|
348
|
+
attributedText: string;
|
|
349
|
+
creatorHandle: string;
|
|
350
|
+
canBeEdited: boolean;
|
|
351
|
+
}
|
|
352
|
+
interface PollVote {
|
|
353
|
+
voteOptionIdentifier: string;
|
|
354
|
+
participantHandle: string;
|
|
355
|
+
serverVoteTime?: number;
|
|
356
|
+
}
|
|
357
|
+
interface PollDefinition {
|
|
358
|
+
version: number;
|
|
359
|
+
item: {
|
|
360
|
+
title: string;
|
|
361
|
+
orderedPollOptions: PollOption[];
|
|
362
|
+
creatorHandle: string;
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
interface PollVoteResponse {
|
|
366
|
+
version: number;
|
|
367
|
+
item: {
|
|
368
|
+
votes: PollVote[];
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
type PollMessageResponse = MessageResponse;
|
|
372
|
+
|
|
329
373
|
interface SendStickerOptions {
|
|
330
374
|
chatGuid: string;
|
|
331
375
|
filePath: string;
|
|
332
376
|
fileName?: string;
|
|
333
377
|
selectedMessageGuid?: string;
|
|
378
|
+
stickerX?: number;
|
|
379
|
+
stickerY?: number;
|
|
380
|
+
stickerScale?: number;
|
|
381
|
+
stickerRotation?: number;
|
|
382
|
+
stickerWidth?: number;
|
|
334
383
|
}
|
|
335
384
|
|
|
336
385
|
type ValidTapback = "love" | "like" | "dislike" | "laugh" | "emphasize" | "question";
|
|
@@ -387,7 +436,6 @@ declare class ChatModule {
|
|
|
387
436
|
}): Promise<ChatResponse>;
|
|
388
437
|
deleteChat(guid: string): Promise<void>;
|
|
389
438
|
markChatRead(guid: string): Promise<void>;
|
|
390
|
-
markChatUnread(guid: string): Promise<void>;
|
|
391
439
|
leaveChat(guid: string): Promise<void>;
|
|
392
440
|
addParticipant(chatGuid: string, address: string): Promise<ChatResponse>;
|
|
393
441
|
removeParticipant(chatGuid: string, address: string): Promise<ChatResponse>;
|
|
@@ -528,6 +576,15 @@ declare class MessageModule {
|
|
|
528
576
|
}): Promise<MessageResponse[]>;
|
|
529
577
|
}
|
|
530
578
|
|
|
579
|
+
declare class PollModule {
|
|
580
|
+
private readonly http;
|
|
581
|
+
constructor(http: AxiosInstance);
|
|
582
|
+
create(options: CreatePollOptions): Promise<PollMessageResponse>;
|
|
583
|
+
vote(options: VotePollOptions): Promise<PollMessageResponse>;
|
|
584
|
+
unvote(options: VotePollOptions): Promise<PollMessageResponse>;
|
|
585
|
+
addOption(options: AddPollOptionOptions): Promise<PollMessageResponse>;
|
|
586
|
+
}
|
|
587
|
+
|
|
531
588
|
declare class ScheduledMessageModule {
|
|
532
589
|
private readonly http;
|
|
533
590
|
constructor(http: AxiosInstance);
|
|
@@ -543,8 +600,6 @@ declare class ServerModule {
|
|
|
543
600
|
getServerInfo(): Promise<any>;
|
|
544
601
|
getMessageStats(): Promise<any>;
|
|
545
602
|
getServerLogs(count?: number): Promise<string[]>;
|
|
546
|
-
getAlerts(): Promise<any[]>;
|
|
547
|
-
markAlertAsRead(ids: string[]): Promise<any>;
|
|
548
603
|
getMediaStatistics(options?: {
|
|
549
604
|
only?: string[];
|
|
550
605
|
}): Promise<any>;
|
|
@@ -568,10 +623,12 @@ declare class AdvancedIMessageKit extends EventEmitter$1 implements TypedEventEm
|
|
|
568
623
|
readonly handles: HandleModule;
|
|
569
624
|
readonly facetime: FaceTimeModule;
|
|
570
625
|
readonly icloud: ICloudModule;
|
|
626
|
+
readonly polls: PollModule;
|
|
571
627
|
readonly scheduledMessages: ScheduledMessageModule;
|
|
572
628
|
readonly server: ServerModule;
|
|
573
629
|
private processedMessages;
|
|
574
630
|
private sendQueue;
|
|
631
|
+
private readyEmitted;
|
|
575
632
|
private constructor();
|
|
576
633
|
emit<K extends keyof PhotonEventMap>(event: K, ...args: PhotonEventMap[K] extends undefined ? [] : [PhotonEventMap[K]]): boolean;
|
|
577
634
|
on<K extends keyof PhotonEventMap>(event: K, listener: PhotonEventMap[K] extends undefined ? () => void : (data: PhotonEventMap[K]) => void): this;
|
|
@@ -636,4 +693,19 @@ declare const NEW_FINDMY_LOCATION = "new-findmy-location";
|
|
|
636
693
|
declare const setGlobalLogLevel: (level: LogLevel) => void;
|
|
637
694
|
declare const getLogger: (tag: string) => Logger;
|
|
638
695
|
|
|
639
|
-
|
|
696
|
+
declare function isPollMessage(message: MessageResponse): boolean;
|
|
697
|
+
declare function isPollVote(message: MessageResponse): boolean;
|
|
698
|
+
interface ParsedPoll {
|
|
699
|
+
title: string;
|
|
700
|
+
creatorHandle: string;
|
|
701
|
+
options: PollOption[];
|
|
702
|
+
}
|
|
703
|
+
interface ParsedPollVote {
|
|
704
|
+
votes: PollVote[];
|
|
705
|
+
}
|
|
706
|
+
declare function parsePollDefinition(message: MessageResponse): ParsedPoll | null;
|
|
707
|
+
declare function parsePollVotes(message: MessageResponse): ParsedPollVote | null;
|
|
708
|
+
declare function getPollSummary(message: MessageResponse): string;
|
|
709
|
+
declare function getPollOneLiner(message: MessageResponse): string;
|
|
710
|
+
|
|
711
|
+
export { type AddPollOptionOptions, AdvancedIMessageKit, type Attachment, type AttachmentResponse, type BackupData, CHAT_READ_STATUS_CHANGED, type Chat, type ChatResponse, type ClientConfig, type CreatePollOptions, FT_CALL_STATUS_CHANGED, type FaceTimeStatusData, type FindMyLocationItem, GROUP_ICON_CHANGED, GROUP_ICON_REMOVED, GROUP_NAME_CHANGE, HELLO_WORLD, type Handle, type HandleResponse, IMESSAGE_ALIASES_REMOVED, INCOMING_FACETIME, MESSAGE_SEND_ERROR, MESSAGE_UPDATED, type Message, type MessageData, type MessageResponse, NEW_FINDMY_LOCATION, NEW_MESSAGE, NEW_SERVER, PARTICIPANT_ADDED, PARTICIPANT_LEFT, PARTICIPANT_REMOVED, type ParsedPoll, type ParsedPollVote, type PhotonEventMap, type PhotonEventName, type PollDefinition, type PollMessageResponse, type PollOption, type PollVote, type PollVoteResponse, SCHEDULED_MESSAGE_CREATED, SCHEDULED_MESSAGE_DELETED, SCHEDULED_MESSAGE_ERROR, SCHEDULED_MESSAGE_SENT, SCHEDULED_MESSAGE_UPDATED, SDK, SERVER_UPDATE, SERVER_UPDATE_DOWNLOADING, SERVER_UPDATE_INSTALLING, SETTINGS_BACKUP_CREATED, SETTINGS_BACKUP_DELETED, SETTINGS_BACKUP_UPDATED, type ScheduledMessageData, type SendAttachmentOptions, type SendMessageOptions, type SendStickerOptions, type ServerMetadataResponse, type ServerUpdateData, THEME_BACKUP_CREATED, THEME_BACKUP_DELETED, THEME_BACKUP_UPDATED, TYPING_INDICATOR, type TypedEventEmitter, type ValidRemoveTapback, type ValidTapback, type VotePollOptions, getLogger, getPollOneLiner, getPollSummary, isPollMessage, isPollVote, parsePollDefinition, parsePollVotes, setGlobalLogLevel };
|
package/dist/index.js
CHANGED
|
@@ -173,15 +173,23 @@ var AttachmentModule = class {
|
|
|
173
173
|
const fileName = options.fileName || path__default.basename(options.filePath);
|
|
174
174
|
const form = new FormData();
|
|
175
175
|
form.append("attachment", await readFile(options.filePath), fileName);
|
|
176
|
-
|
|
176
|
+
form.append("name", fileName);
|
|
177
|
+
form.append("chatGuid", options.chatGuid);
|
|
178
|
+
form.append("isSticker", "true");
|
|
179
|
+
form.append("method", "private-api");
|
|
180
|
+
if (options.selectedMessageGuid) {
|
|
181
|
+
form.append("selectedMessageGuid", options.selectedMessageGuid);
|
|
182
|
+
form.append("partIndex", "0");
|
|
183
|
+
}
|
|
184
|
+
form.append("stickerX", String(options.stickerX ?? 0.5));
|
|
185
|
+
form.append("stickerY", String(options.stickerY ?? 0.5));
|
|
186
|
+
form.append("stickerScale", String(options.stickerScale ?? 0.75));
|
|
187
|
+
form.append("stickerRotation", String(options.stickerRotation ?? 0));
|
|
188
|
+
form.append("stickerWidth", String(options.stickerWidth ?? 300));
|
|
189
|
+
const { data } = await this.http.post("/api/v1/message/attachment", form, {
|
|
177
190
|
headers: form.getHeaders()
|
|
178
191
|
});
|
|
179
|
-
|
|
180
|
-
chatGuid: options.chatGuid,
|
|
181
|
-
selectedMessageGuid: options.selectedMessageGuid,
|
|
182
|
-
parts: [{ partIndex: 0, attachment: data.data.path, name: fileName }]
|
|
183
|
-
});
|
|
184
|
-
return response.data.data;
|
|
192
|
+
return data.data;
|
|
185
193
|
});
|
|
186
194
|
}
|
|
187
195
|
};
|
|
@@ -198,35 +206,32 @@ var ChatModule = class {
|
|
|
198
206
|
return response.data.data;
|
|
199
207
|
}
|
|
200
208
|
async getChat(guid, options) {
|
|
201
|
-
const response = await this.http.get(`/api/v1/chat/${guid}`, {
|
|
209
|
+
const response = await this.http.get(`/api/v1/chat/${encodeURIComponent(guid)}`, {
|
|
202
210
|
params: options?.with ? { with: options.with.join(",") } : {}
|
|
203
211
|
});
|
|
204
212
|
return response.data.data;
|
|
205
213
|
}
|
|
206
214
|
async updateChat(guid, options) {
|
|
207
|
-
const response = await this.http.put(`/api/v1/chat/${guid}`, options);
|
|
215
|
+
const response = await this.http.put(`/api/v1/chat/${encodeURIComponent(guid)}`, options);
|
|
208
216
|
return response.data.data;
|
|
209
217
|
}
|
|
210
218
|
async deleteChat(guid) {
|
|
211
|
-
await this.http.delete(`/api/v1/chat/${guid}`);
|
|
219
|
+
await this.http.delete(`/api/v1/chat/${encodeURIComponent(guid)}`);
|
|
212
220
|
}
|
|
213
221
|
async markChatRead(guid) {
|
|
214
|
-
await this.http.post(`/api/v1/chat/${guid}/read`);
|
|
215
|
-
}
|
|
216
|
-
async markChatUnread(guid) {
|
|
217
|
-
await this.http.post(`/api/v1/chat/${guid}/unread`);
|
|
222
|
+
await this.http.post(`/api/v1/chat/${encodeURIComponent(guid)}/read`);
|
|
218
223
|
}
|
|
219
224
|
async leaveChat(guid) {
|
|
220
|
-
await this.http.post(`/api/v1/chat/${guid}/leave`);
|
|
225
|
+
await this.http.post(`/api/v1/chat/${encodeURIComponent(guid)}/leave`);
|
|
221
226
|
}
|
|
222
227
|
async addParticipant(chatGuid, address) {
|
|
223
|
-
const response = await this.http.post(`/api/v1/chat/${chatGuid}/participant`, {
|
|
228
|
+
const response = await this.http.post(`/api/v1/chat/${encodeURIComponent(chatGuid)}/participant`, {
|
|
224
229
|
address
|
|
225
230
|
});
|
|
226
231
|
return response.data.data;
|
|
227
232
|
}
|
|
228
233
|
async removeParticipant(chatGuid, address) {
|
|
229
|
-
const response = await this.http.delete(`/api/v1/chat/${chatGuid}/participant`, {
|
|
234
|
+
const response = await this.http.delete(`/api/v1/chat/${encodeURIComponent(chatGuid)}/participant`, {
|
|
230
235
|
data: { address }
|
|
231
236
|
});
|
|
232
237
|
return response.data.data;
|
|
@@ -239,7 +244,7 @@ var ChatModule = class {
|
|
|
239
244
|
if (options?.before !== void 0) params.before = options.before;
|
|
240
245
|
if (options?.after !== void 0) params.after = options.after;
|
|
241
246
|
if (options?.with) params.with = options.with.join(",");
|
|
242
|
-
const response = await this.http.get(`/api/v1/chat/${chatGuid}/message`, {
|
|
247
|
+
const response = await this.http.get(`/api/v1/chat/${encodeURIComponent(chatGuid)}/message`, {
|
|
243
248
|
params
|
|
244
249
|
});
|
|
245
250
|
return response.data.data;
|
|
@@ -249,15 +254,15 @@ var ChatModule = class {
|
|
|
249
254
|
const fileName = path__default.basename(filePath);
|
|
250
255
|
const form = new FormData();
|
|
251
256
|
form.append("icon", fileBuffer, fileName);
|
|
252
|
-
await this.http.post(`/api/v1/chat/${chatGuid}/icon`, form, {
|
|
257
|
+
await this.http.post(`/api/v1/chat/${encodeURIComponent(chatGuid)}/icon`, form, {
|
|
253
258
|
headers: form.getHeaders()
|
|
254
259
|
});
|
|
255
260
|
}
|
|
256
261
|
async removeGroupIcon(chatGuid) {
|
|
257
|
-
await this.http.delete(`/api/v1/chat/${chatGuid}/icon`);
|
|
262
|
+
await this.http.delete(`/api/v1/chat/${encodeURIComponent(chatGuid)}/icon`);
|
|
258
263
|
}
|
|
259
264
|
async getGroupIcon(chatGuid) {
|
|
260
|
-
const response = await this.http.get(`/api/v1/chat/${chatGuid}/icon`, {
|
|
265
|
+
const response = await this.http.get(`/api/v1/chat/${encodeURIComponent(chatGuid)}/icon`, {
|
|
261
266
|
responseType: "arraybuffer"
|
|
262
267
|
});
|
|
263
268
|
return Buffer.from(response.data);
|
|
@@ -269,10 +274,10 @@ var ChatModule = class {
|
|
|
269
274
|
return response.data.data;
|
|
270
275
|
}
|
|
271
276
|
async startTyping(chatGuid) {
|
|
272
|
-
await this.http.post(`/api/v1/chat/${chatGuid}/typing`);
|
|
277
|
+
await this.http.post(`/api/v1/chat/${encodeURIComponent(chatGuid)}/typing`);
|
|
273
278
|
}
|
|
274
279
|
async stopTyping(chatGuid) {
|
|
275
|
-
await this.http.delete(`/api/v1/chat/${chatGuid}/typing`);
|
|
280
|
+
await this.http.delete(`/api/v1/chat/${encodeURIComponent(chatGuid)}/typing`);
|
|
276
281
|
}
|
|
277
282
|
};
|
|
278
283
|
|
|
@@ -292,10 +297,10 @@ var ContactModule = class {
|
|
|
292
297
|
return response.data.data;
|
|
293
298
|
}
|
|
294
299
|
async shareContactCard(chatGuid) {
|
|
295
|
-
await this.http.post(`/api/v1/chat/${chatGuid}/share/contact`);
|
|
300
|
+
await this.http.post(`/api/v1/chat/${encodeURIComponent(chatGuid)}/share/contact`);
|
|
296
301
|
}
|
|
297
302
|
async shouldShareContact(chatGuid) {
|
|
298
|
-
const response = await this.http.get(`/api/v1/chat/${chatGuid}/share/contact/status`);
|
|
303
|
+
const response = await this.http.get(`/api/v1/chat/${encodeURIComponent(chatGuid)}/share/contact/status`);
|
|
299
304
|
return response.data.data;
|
|
300
305
|
}
|
|
301
306
|
};
|
|
@@ -509,6 +514,51 @@ var MessageModule = class {
|
|
|
509
514
|
}
|
|
510
515
|
};
|
|
511
516
|
|
|
517
|
+
// modules/poll.ts
|
|
518
|
+
var PollModule = class {
|
|
519
|
+
constructor(http) {
|
|
520
|
+
this.http = http;
|
|
521
|
+
}
|
|
522
|
+
async create(options) {
|
|
523
|
+
if (options.options.length < 2) {
|
|
524
|
+
throw new Error("Poll must have at least 2 options");
|
|
525
|
+
}
|
|
526
|
+
const { data } = await this.http.post("/api/v1/poll/create", {
|
|
527
|
+
chatGuid: options.chatGuid,
|
|
528
|
+
title: options.title ?? "",
|
|
529
|
+
options: options.options
|
|
530
|
+
});
|
|
531
|
+
return data.data;
|
|
532
|
+
}
|
|
533
|
+
async vote(options) {
|
|
534
|
+
const { data } = await this.http.post("/api/v1/poll/vote", {
|
|
535
|
+
chatGuid: options.chatGuid,
|
|
536
|
+
pollMessageGuid: options.pollMessageGuid,
|
|
537
|
+
optionIdentifier: options.optionIdentifier
|
|
538
|
+
});
|
|
539
|
+
return data.data;
|
|
540
|
+
}
|
|
541
|
+
async unvote(options) {
|
|
542
|
+
const { data } = await this.http.post("/api/v1/poll/unvote", {
|
|
543
|
+
chatGuid: options.chatGuid,
|
|
544
|
+
pollMessageGuid: options.pollMessageGuid,
|
|
545
|
+
optionIdentifier: options.optionIdentifier
|
|
546
|
+
});
|
|
547
|
+
return data.data;
|
|
548
|
+
}
|
|
549
|
+
async addOption(options) {
|
|
550
|
+
if (!options.optionText || options.optionText.trim().length === 0) {
|
|
551
|
+
throw new Error("Option text cannot be empty");
|
|
552
|
+
}
|
|
553
|
+
const { data } = await this.http.post("/api/v1/poll/option", {
|
|
554
|
+
chatGuid: options.chatGuid,
|
|
555
|
+
pollMessageGuid: options.pollMessageGuid,
|
|
556
|
+
optionText: options.optionText
|
|
557
|
+
});
|
|
558
|
+
return data.data;
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
|
|
512
562
|
// modules/scheduled.ts
|
|
513
563
|
var ScheduledMessageModule = class {
|
|
514
564
|
constructor(http) {
|
|
@@ -550,14 +600,6 @@ var ServerModule = class {
|
|
|
550
600
|
});
|
|
551
601
|
return response.data.data;
|
|
552
602
|
}
|
|
553
|
-
async getAlerts() {
|
|
554
|
-
const response = await this.http.get("/api/v1/server/alert");
|
|
555
|
-
return response.data.data;
|
|
556
|
-
}
|
|
557
|
-
async markAlertAsRead(ids) {
|
|
558
|
-
const response = await this.http.post("/api/v1/server/alert/read", { ids });
|
|
559
|
-
return response.data.data;
|
|
560
|
-
}
|
|
561
603
|
async getMediaStatistics(options) {
|
|
562
604
|
const params = {};
|
|
563
605
|
if (options?.only) params.only = options.only.join(",");
|
|
@@ -592,6 +634,7 @@ var _AdvancedIMessageKit = class _AdvancedIMessageKit extends EventEmitter {
|
|
|
592
634
|
__publicField(this, "handles");
|
|
593
635
|
__publicField(this, "facetime");
|
|
594
636
|
__publicField(this, "icloud");
|
|
637
|
+
__publicField(this, "polls");
|
|
595
638
|
__publicField(this, "scheduledMessages");
|
|
596
639
|
__publicField(this, "server");
|
|
597
640
|
// Message deduplication feature
|
|
@@ -605,6 +648,11 @@ var _AdvancedIMessageKit = class _AdvancedIMessageKit extends EventEmitter {
|
|
|
605
648
|
// Purpose: Ensure all outgoing messages (text, attachments, stickers, etc.) from
|
|
606
649
|
// a single user/SDK instance are sent in strict order, preventing race conditions.
|
|
607
650
|
__publicField(this, "sendQueue", Promise.resolve());
|
|
651
|
+
// Flag to track if 'ready' event has been emitted
|
|
652
|
+
//
|
|
653
|
+
// Purpose: Prevent duplicate 'ready' events when both legacy mode (no API key)
|
|
654
|
+
// and auth-ok events occur, which would cause user callbacks to fire twice.
|
|
655
|
+
__publicField(this, "readyEmitted", false);
|
|
608
656
|
this.config = {
|
|
609
657
|
serverUrl: "http://localhost:1234",
|
|
610
658
|
logLevel: "info",
|
|
@@ -647,6 +695,7 @@ var _AdvancedIMessageKit = class _AdvancedIMessageKit extends EventEmitter {
|
|
|
647
695
|
this.handles = new HandleModule(this.http);
|
|
648
696
|
this.facetime = new FaceTimeModule(this.http);
|
|
649
697
|
this.icloud = new ICloudModule(this.http);
|
|
698
|
+
this.polls = new PollModule(this.http);
|
|
650
699
|
this.scheduledMessages = new ScheduledMessageModule(this.http);
|
|
651
700
|
this.server = new ServerModule(this.http);
|
|
652
701
|
}
|
|
@@ -715,11 +764,15 @@ var _AdvancedIMessageKit = class _AdvancedIMessageKit extends EventEmitter {
|
|
|
715
764
|
}
|
|
716
765
|
this.socket.on("disconnect", () => {
|
|
717
766
|
this.logger.info("Disconnected from iMessage server");
|
|
767
|
+
this.readyEmitted = false;
|
|
718
768
|
this.emit("disconnect");
|
|
719
769
|
});
|
|
720
770
|
this.socket.on("auth-ok", () => {
|
|
721
771
|
this.logger.info("Authentication successful");
|
|
722
|
-
this.
|
|
772
|
+
if (!this.readyEmitted) {
|
|
773
|
+
this.readyEmitted = true;
|
|
774
|
+
this.emit("ready");
|
|
775
|
+
}
|
|
723
776
|
});
|
|
724
777
|
this.socket.on("auth-error", (error) => {
|
|
725
778
|
this.logger.error(`Authentication failed: ${error.message} ${error.reason ? `(${error.reason})` : ""}`);
|
|
@@ -733,7 +786,10 @@ var _AdvancedIMessageKit = class _AdvancedIMessageKit extends EventEmitter {
|
|
|
733
786
|
this.logger.info("Connected to iMessage server, waiting for authentication...");
|
|
734
787
|
if (!this.config.apiKey) {
|
|
735
788
|
this.logger.info("No API key provided, skipping authentication (legacy server mode)");
|
|
736
|
-
this.
|
|
789
|
+
if (!this.readyEmitted) {
|
|
790
|
+
this.readyEmitted = true;
|
|
791
|
+
this.emit("ready");
|
|
792
|
+
}
|
|
737
793
|
}
|
|
738
794
|
});
|
|
739
795
|
if (!this.socket.connected) {
|
|
@@ -817,6 +873,144 @@ var IMESSAGE_ALIASES_REMOVED = "imessage-aliases-removed";
|
|
|
817
873
|
var FT_CALL_STATUS_CHANGED = "ft-call-status-changed";
|
|
818
874
|
var NEW_FINDMY_LOCATION = "new-findmy-location";
|
|
819
875
|
|
|
820
|
-
|
|
876
|
+
// lib/poll-utils.ts
|
|
877
|
+
var POLL_BALLOON_BUNDLE_ID = "com.apple.messages.MSMessageExtensionBalloonPlugin:0000000000:com.apple.messages.Polls";
|
|
878
|
+
var pollCache = /* @__PURE__ */ new Map();
|
|
879
|
+
function cachePoll(messageGuid, poll) {
|
|
880
|
+
pollCache.set(messageGuid, poll);
|
|
881
|
+
}
|
|
882
|
+
function getOptionTextById(optionId) {
|
|
883
|
+
for (const poll of pollCache.values()) {
|
|
884
|
+
const option = poll.options.find((o) => o.optionIdentifier === optionId);
|
|
885
|
+
if (option) return option.text;
|
|
886
|
+
}
|
|
887
|
+
return null;
|
|
888
|
+
}
|
|
889
|
+
function isPollMessage(message) {
|
|
890
|
+
return message.balloonBundleId === POLL_BALLOON_BUNDLE_ID;
|
|
891
|
+
}
|
|
892
|
+
function isPollVote(message) {
|
|
893
|
+
return isPollMessage(message) && message.associatedMessageType === "4000";
|
|
894
|
+
}
|
|
895
|
+
function extractDataUrl(payloadData) {
|
|
896
|
+
if (!payloadData || payloadData.length === 0) return null;
|
|
897
|
+
const payload = payloadData[0];
|
|
898
|
+
if (!payload) return null;
|
|
899
|
+
if (payload.URL && typeof payload.URL === "string") {
|
|
900
|
+
return payload.URL;
|
|
901
|
+
}
|
|
902
|
+
const objects = payload.$objects;
|
|
903
|
+
if (Array.isArray(objects)) {
|
|
904
|
+
for (const obj of objects) {
|
|
905
|
+
if (typeof obj === "object" && obj !== null) {
|
|
906
|
+
if (obj["NS.relative"] && typeof obj["NS.relative"] === "object") {
|
|
907
|
+
const relativeObj = objects[obj["NS.relative"].UID];
|
|
908
|
+
if (typeof relativeObj === "string" && relativeObj.startsWith("data:,")) {
|
|
909
|
+
return relativeObj;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
if (typeof obj === "string" && obj.startsWith("data:,")) {
|
|
913
|
+
return obj;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
return null;
|
|
919
|
+
}
|
|
920
|
+
function parseDataUrl(dataUrl) {
|
|
921
|
+
try {
|
|
922
|
+
const prefix = "data:,";
|
|
923
|
+
if (!dataUrl.startsWith(prefix)) return null;
|
|
924
|
+
let data = dataUrl.slice(prefix.length);
|
|
925
|
+
const queryIndex = data.indexOf("?");
|
|
926
|
+
if (queryIndex !== -1) {
|
|
927
|
+
data = data.slice(0, queryIndex);
|
|
928
|
+
}
|
|
929
|
+
data = decodeURIComponent(data);
|
|
930
|
+
try {
|
|
931
|
+
return JSON.parse(data);
|
|
932
|
+
} catch {
|
|
933
|
+
const decoded = Buffer.from(data, "base64").toString("utf-8");
|
|
934
|
+
return JSON.parse(decoded);
|
|
935
|
+
}
|
|
936
|
+
} catch {
|
|
937
|
+
return null;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
function parsePollDefinition(message) {
|
|
941
|
+
if (!isPollMessage(message)) return null;
|
|
942
|
+
if (isPollVote(message)) return null;
|
|
943
|
+
const dataUrl = extractDataUrl(message.payloadData);
|
|
944
|
+
if (!dataUrl) return null;
|
|
945
|
+
const data = parseDataUrl(dataUrl);
|
|
946
|
+
if (!data || !data.item) return null;
|
|
947
|
+
const parsed = {
|
|
948
|
+
title: data.item.title || "",
|
|
949
|
+
creatorHandle: data.item.creatorHandle || "",
|
|
950
|
+
options: data.item.orderedPollOptions || []
|
|
951
|
+
};
|
|
952
|
+
if (message.guid) {
|
|
953
|
+
cachePoll(message.guid, parsed);
|
|
954
|
+
}
|
|
955
|
+
return parsed;
|
|
956
|
+
}
|
|
957
|
+
function parsePollVotes(message) {
|
|
958
|
+
if (!isPollMessage(message)) return null;
|
|
959
|
+
if (!isPollVote(message)) return null;
|
|
960
|
+
const dataUrl = extractDataUrl(message.payloadData);
|
|
961
|
+
if (!dataUrl) return null;
|
|
962
|
+
const data = parseDataUrl(dataUrl);
|
|
963
|
+
if (!data || !data.item) return null;
|
|
964
|
+
return {
|
|
965
|
+
votes: data.item.votes || []
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
function getPollSummary(message) {
|
|
969
|
+
if (!isPollMessage(message)) {
|
|
970
|
+
return message.text || "(no text)";
|
|
971
|
+
}
|
|
972
|
+
if (isPollVote(message)) {
|
|
973
|
+
const voteData = parsePollVotes(message);
|
|
974
|
+
if (voteData && voteData.votes.length > 0) {
|
|
975
|
+
const votes = voteData.votes.map((v) => {
|
|
976
|
+
const optionText = getOptionTextById(v.voteOptionIdentifier);
|
|
977
|
+
const optionDisplay = optionText ? `"${optionText}"` : `option ${v.voteOptionIdentifier}`;
|
|
978
|
+
return `${v.participantHandle || "Someone"} voted ${optionDisplay}`;
|
|
979
|
+
}).join(", ");
|
|
980
|
+
return `[Poll Vote] ${votes}`;
|
|
981
|
+
}
|
|
982
|
+
return "[Poll Vote]";
|
|
983
|
+
}
|
|
984
|
+
const pollData = parsePollDefinition(message);
|
|
985
|
+
if (pollData) {
|
|
986
|
+
const title = pollData.title ? `"${pollData.title}"` : "(untitled poll)";
|
|
987
|
+
const optionsList = pollData.options.map((opt, i) => ` ${i + 1}. ${opt.text}`).join("\n");
|
|
988
|
+
return `[Poll] ${title}
|
|
989
|
+
${optionsList}`;
|
|
990
|
+
}
|
|
991
|
+
return "[Poll] (unable to parse)";
|
|
992
|
+
}
|
|
993
|
+
function getPollOneLiner(message) {
|
|
994
|
+
if (!isPollMessage(message)) {
|
|
995
|
+
return message.text || "(no text)";
|
|
996
|
+
}
|
|
997
|
+
if (isPollVote(message)) {
|
|
998
|
+
const voteData = parsePollVotes(message);
|
|
999
|
+
if (voteData && voteData.votes.length > 0) {
|
|
1000
|
+
return `[Poll Vote] ${voteData.votes.length} vote(s)`;
|
|
1001
|
+
}
|
|
1002
|
+
return "[Poll Vote]";
|
|
1003
|
+
}
|
|
1004
|
+
const pollData = parsePollDefinition(message);
|
|
1005
|
+
if (pollData) {
|
|
1006
|
+
const title = pollData.title || "Poll";
|
|
1007
|
+
const optionsPreview = pollData.options.slice(0, 2).map((o) => o.text).join(", ");
|
|
1008
|
+
const moreOptions = pollData.options.length > 2 ? `, +${pollData.options.length - 2} more` : "";
|
|
1009
|
+
return `[${title}] ${optionsPreview}${moreOptions}`;
|
|
1010
|
+
}
|
|
1011
|
+
return "[Poll]";
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
export { AdvancedIMessageKit, CHAT_READ_STATUS_CHANGED, FT_CALL_STATUS_CHANGED, GROUP_ICON_CHANGED, GROUP_ICON_REMOVED, GROUP_NAME_CHANGE, HELLO_WORLD, IMESSAGE_ALIASES_REMOVED, INCOMING_FACETIME, MESSAGE_SEND_ERROR, MESSAGE_UPDATED, NEW_FINDMY_LOCATION, NEW_MESSAGE, NEW_SERVER, PARTICIPANT_ADDED, PARTICIPANT_LEFT, PARTICIPANT_REMOVED, SCHEDULED_MESSAGE_CREATED, SCHEDULED_MESSAGE_DELETED, SCHEDULED_MESSAGE_ERROR, SCHEDULED_MESSAGE_SENT, SCHEDULED_MESSAGE_UPDATED, SDK, SERVER_UPDATE, SERVER_UPDATE_DOWNLOADING, SERVER_UPDATE_INSTALLING, SETTINGS_BACKUP_CREATED, SETTINGS_BACKUP_DELETED, SETTINGS_BACKUP_UPDATED, THEME_BACKUP_CREATED, THEME_BACKUP_DELETED, THEME_BACKUP_UPDATED, TYPING_INDICATOR, getLogger, getPollOneLiner, getPollSummary, isPollMessage, isPollVote, parsePollDefinition, parsePollVotes, setGlobalLogLevel };
|
|
821
1015
|
//# sourceMappingURL=index.js.map
|
|
822
1016
|
//# sourceMappingURL=index.js.map
|