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